sql >> データベース >  >> RDS >> SQLite

アセットフォルダに配置されているAndroidのデータベースファイルからバージョン番号を読み取る方法

    単一のバージョン番号ではなく、バージョン番号が複数の値になる可能性があります。

    推測では、あなたは user_versionに隣接して話していると思います AndroidSDKSQLiteOpenHelperが使用します。

    application_idもあります 、user_versionと同様に、ユーザー変数として使用できます。

    すでにSQLite_Versionに遭遇しているので、割引することができます。

    data_versionもあります。これは、データベースファイルがリアルタイムで変更されたかどうかを示すために使用されることを目的としているため、バージョン番号である可能性は低いです。

    schema_versionもあります。おそらく、これを 警告:このプラグマの誤用はデータベースの破損につながる可能性があるため、使用したくないでしょう。

    user_version

    前に言ったように、あなたはおそらく user_versionについて話しているでしょう 。最初に注意することは、それがカスタム使用のために利用可能にされたユーザー制御の変数/フィールドであるということです。 SQliteはuser_versionを使用または変更しません ただし、変更して使用することはできます。

    さらに、SQLiteマネージャー(DBブラウザー、Navicatなど)はバージョン番号を自動的に変更しませんでした。そのため、データベースファイルをアセットフォルダにコピーする前に、user_versionを意図的に変更して使用できるようにする必要があります(そうする場合は、SQLiteOpenHelperのサブクラスを使用していることに注意してください。 onUpgrade およびonDowngrade メソッドが呼び出される場合があります。

    user_versionが特に変更されておらず、データベースがSQLite Managerツールによってのみアクセスされた場合、そのuser_versionは0になります。SQLiteOpenHelperのサブクラスを利用するAndroidアプリからデータベースファイルをコピーしてデータベースファイルを開いた場合は、次のようになります。 1以上のuser_version(SQLiteOpenHelperのコンストラクターの4番目のパラメーターとして使用される最後の値によって異なります)。もちろん、user_versionがプログラムで変更された場合、そのような変更は、ファイルがSQliteManagerツールにコピーされた場合にも反映されます。

    ファイルをコピーする前に、user_versionは通常、SQliteManagerツール内で適切な値に変更されます。

    user_versionを変更できます SQL PRAGMA user_version = 5;を使用する user_versionを取得できます PRAGMA user_versionのいずれかを使用する またはSELECT * FROM pragma_user_version;

    データベースを開く前にバージョンを確認する必要がある場合は、オフセット60で4バイトを読み取り、4バイトを整数に変換して、user_versionを別の値と照合することができます。それ以外の場合は、おそらく別の名前を使用してファイルをアセットフォルダーからコピーし、SQLiteDatabaseとして開き、上記のSQLを使用してuser_versionを取得してから、他の値と照合してデータベースファイルを閉じる必要があります。必要がない場合はファイルを削除します。それ以外の場合は、前のデータベースファイルを削除してから、コピーしたファイルの名前を変更します。

    以下は実際の例です(Kotlinを使用することはめったになく、これはJavaからAS studioを使用して変換されています)。

    これはクラス、つまり SQLAssetVersionCheckを使用します これは、ファイルをSQLiteDatabaseとして開くのではなく、ファイルからバージョン番号を抽出します。

    SQLAssetVersionCheck.kt:-

    class SQLAssetVersionCheck
    /**
     * Full SQLAssetVersionCheck Constructor - sub directories can be specified
     * @param context           Assets are part of package so use the context to get the asset file
     * @param dbName            The database name (i.e. the file name)
     * @param subDirectories    The sub-directories as per the heirarchial order
     * @param dbVersion         The database version to check against
     */
    (context: Context, val databaseName: String, subDirectories: Array<String>?, dbVersion: Int) {
        val assetPath: String
        var databaseVersion: Int = 0
            private set
        var result: Int = 0
            private set
    
    
        init {
            assetPath = applySubDirectories(databaseName, subDirectories)
            Log.d("SQLAVC", "Looking for Asset $assetPath")
            var stage = 0
            try {
                val `is` = context.assets.open(assetPath)
                stage++
                // Get the first 64 bytes of the header
                val v = ByteArray(64)
                `is`.read(v, 0, 64)
                // only interested in the 4 bytes from offset 60 so get them
                val v2 = ByteArray(4)
                for (i in 60..63) {
                    v2[i - 60] = v[i]
                }
                stage++
                // Done with the InputStream so close it
                `is`.close()
                // Extarct the stored DBVersion
                databaseVersion = ByteBuffer.wrap(v2).int
                if (databaseVersion < dbVersion) {
                    result = ASSETVERSIONLOW
    
                }
                if (databaseVersion > dbVersion) {
                    result = ASSETVERSIONHIGH
                }
                if (databaseVersion == dbVersion) {
                    result = ASSETVERSIONMATCH
                }
    
            } catch (e: IOException) {
                e.printStackTrace()
                when (stage) {
                    0 -> result = ASSETNOTFOUND
                    1 -> result = ASSETIOERROR
                }
            }
    
        }
    
        constructor(context: Context, dbName: String, dbVersion: Int) : this(context, dbName, null, dbVersion) {}
    
        private fun applySubDirectories(dbname: String, subDirectories: Array<String>?): String {
            val base = StringBuffer("")
            var firstdirectory = true
            if (subDirectories != null) {
                for (d in subDirectories) {
                    if (!firstdirectory) {
                        base.append(File.separatorChar)
                    }
                    firstdirectory = false
                    base.append(d)
                }
            }
            if (base.length > 0) {
                base.append(File.separatorChar)
            }
            base.append(dbname)
            return base.toString()
        }
    
        companion object {
    
            val ASSETNOTFOUND = -2
            val ASSETIOERROR = -3
            val ASSETVERSIONMATCH = 0
            val ASSETVERSIONHIGH = 1
            val ASSETVERSIONLOW = -1
        }
    }
    

    そして、これが上記のクラスを2回使用して、 testdbのバージョンを確認しようとするアクティビティです。 ファイル。

    • 最初の使用では、データベースファイル testdbが見つかりません アセットで見ているように フォルダ(データベースのサブディレクトリではありません)。

    • 2番目の使用法では、 testdbが見つかります サブディレクトリとしてのファイルデータベース が指定され(完全なコンストラクターの3番目のパラメーター)、アセット/データベース/で検索されます フォルダ、つまり Assets / databases / testdb :-

    MainActivity.kt:-

    class MainActivity : AppCompatActivity() {
    
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            val db_version_to_check_against = 100
    
            var mAVC1 = SQLAssetVersionCheck(this, "testdb", 100)
    
            var result = ""
            when (mAVC1.result) {
                SQLAssetVersionCheck.ASSETIOERROR -> result = "IO ERROR detected - check the Log"
                SQLAssetVersionCheck.ASSETNOTFOUND -> result = "The Asset, for Database " + mAVC1.databaseName + " was not located at  " + mAVC1.assetPath
                SQLAssetVersionCheck.ASSETVERSIONHIGH -> result = "The Asset was located and the version number being " +
                        mAVC1.databaseVersion.toString() +
                        " was higher than the version to be checked which was " +
                        db_version_to_check_against.toString()
                SQLAssetVersionCheck.ASSETVERSIONLOW -> result = "The Asset was located and the version number being " +
                        mAVC1.databaseVersion.toString() +
                        " was lower than the version to be checked which was " +
                        db_version_to_check_against.toString()
                SQLAssetVersionCheck.ASSETVERSIONMATCH -> result = "The Asset version and the version to be check ed are the same."
            }
            Log.d("ASSETVERSIONCHECK", "The result of the version check was - $result")
    
            var mAVC2 = SQLAssetVersionCheck(this, "testdb", arrayOf("databases"), db_version_to_check_against)
            result = ""
            when (mAVC2.result) {
                SQLAssetVersionCheck.ASSETIOERROR -> result = "IO ERROR detected - check the Log"
                SQLAssetVersionCheck.ASSETNOTFOUND -> result = "The Asset, for Database " + mAVC2.databaseName + " was not located at  " + mAVC2.assetPath
                SQLAssetVersionCheck.ASSETVERSIONHIGH -> result = "The Asset was located and the version number being " +
                        mAVC2.databaseVersion.toString() +
                        " was higher than the version to be checked which was " +
                        db_version_to_check_against.toString()
                SQLAssetVersionCheck.ASSETVERSIONLOW -> result = "The Asset was located and the version number being " +
                        mAVC2.databaseVersion.toString() +
                        " was lower than the version to be checked which was " +
                        db_version_to_check_against.toString()
                SQLAssetVersionCheck.ASSETVERSIONMATCH -> result = "The Asset version and the version to be check ed are the same."
            }
            Log.d("ASSETVERSIONCHECK", "The result of the version check was - $result")
        }
    }
    

    結果(ログ):-

    2019-02-19 13:11:34.473 19058-19058/com.example.so54741423assetdbversioning D/SQLAVC: Looking for Asset testdb
    2019-02-19 13:11:34.473 19058-19058/com.example.so54741423assetdbversioning W/System.err: java.io.FileNotFoundException: testdb
    2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.content.res.AssetManager.nativeOpenAsset(Native Method)
    2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.content.res.AssetManager.open(AssetManager.java:744)
    2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.content.res.AssetManager.open(AssetManager.java:721)
    2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at com.example.so54741423assetdbversioning.SQLAssetVersionCheck.<init>(SQLAssetVersionCheck.kt:31)
    2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at com.example.so54741423assetdbversioning.SQLAssetVersionCheck.<init>(SQLAssetVersionCheck.kt:67)
    2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at com.example.so54741423assetdbversioning.MainActivity.onCreate(MainActivity.kt:17)
    2019-02-19 13:11:34.474 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.app.Activity.performCreate(Activity.java:7136)
    2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.app.Activity.performCreate(Activity.java:7127)
    2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
    2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
    2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
    2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
    2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
    2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:106)
    2019-02-19 13:11:34.475 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.os.Looper.loop(Looper.java:193)
    2019-02-19 13:11:34.476 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6669)
    2019-02-19 13:11:34.476 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
    2019-02-19 13:11:34.476 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    2019-02-19 13:11:34.476 19058-19058/com.example.so54741423assetdbversioning W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
    2019-02-19 13:11:34.476 19058-19058/com.example.so54741423assetdbversioning D/ASSETVERSIONCHECK: The result of the version check was - The Asset, for Database testdb was not located at  testdb
    
    
    
    
    2019-02-19 13:11:34.476 19058-19058/com.example.so54741423assetdbversioning D/SQLAVC: Looking for Asset databases/testdb
    2019-02-19 13:11:34.477 19058-19058/com.example.so54741423assetdbversioning D/ASSETVERSIONCHECK: The result of the version check was - The Asset was located and the version number being 5 was lower than the version to be checked which was 100
    
    • 最初の試行ではファイルが見つかりません(キャッチされた例外が表示されます)。バージョンチェックの結果は-データベースtestdbのアセットがtestdbに見つかりませんでしたという行が表示されます。 表示されます。

    • 2回目の試行が機能し、結果はバージョンチェックの結果は次のとおりです-アセットが特定され、バージョン番号5は、チェック対象のバージョンである100よりも低かった

    • 2回目の試行を最初の試行から分割するために、空白行のギャップが追加されました。

    追加

    SQLite Managerツール(Navicat)を使用し、以下を使用した後:-

    PRAGMA user_version = 101;
    

    次に、ファイルを(Navicatで接続を閉じた後)アセットフォルダーにコピーすると(つまり、2つのtestdbファイルがあります)、結果は次のようになります:-

    2019-02-19 13:50:09.874 19253-19253/com.example.so54741423assetdbversioning D/SQLAVC: Looking for Asset testdb
    2019-02-19 13:50:09.874 19253-19253/com.example.so54741423assetdbversioning D/ASSETVERSIONCHECK: The result of the version check was - The Asset was located and the version number being 101 was higher than the version to be checked which was 100
    2019-02-19 13:50:09.874 19253-19253/com.example.so54741423assetdbversioning D/SQLAVC: Looking for Asset databases/testdb
    2019-02-19 13:50:09.874 19253-19253/com.example.so54741423assetdbversioning D/ASSETVERSIONCHECK: The result of the version check was - The Asset was located and the version number being 5 was lower than the version to be checked which was 100
    
    • つまり新しいファイルのuser_versionは101であるため、最初のファイルはファイルを検索し、2番目のファイルは以前と同様にファイル(user_version 5)を検索します。



    1. Jenkinsを使用したPostgreSQLの毎日のタスクの自動化

    2. MySQLで動的ピボットテーブルを作成する方法

    3. offset+limitを使用してmySQLクエリの結果の総数を検索します

    4. MySQL COS()関数–MySQLの数値の正弦を返します