SQLite
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> SQLite

Cách đọc số phiên bản từ tệp cơ sở dữ liệu trong Android được đặt trong thư mục nội dung

Không có một số phiên bản duy nhất, thay vào đó, số phiên bản có thể là nhiều giá trị.

Có thể đoán bạn đang nói về user_version mà Android SDK SQLiteOpenHelper sử dụng.

Ngoài ra còn có application_id , chẳng hạn như user_version có thể được sử dụng làm biến người dùng.

Bạn đã gặp SQLite_Version, do đó, bạn có thể được chiết khấu.

Ngoài ra còn có data_version, đây không phải là số phiên bản, vì nó được sử dụng như một dấu hiệu nếu tệp cơ sở dữ liệu đã được sửa đổi trong thời gian thực.

Ngoài ra còn có schema_version, có thể bạn KHÔNG muốn sử dụng nó làm Cảnh báo:Việc lạm dụng pragma này có thể dẫn đến hỏng cơ sở dữ liệu.

user_version

Như đã nói trước đây, có thể bạn đang nói về user_version . Điều đầu tiên cần lưu ý là nó là một biến / trường do người dùng kiểm soát được tạo sẵn để sử dụng tùy chỉnh. SQlite không sử dụng hoặc thay đổi user_version nhưng cho phép nó được thay đổi và sử dụng.

Hơn nữa, Trình quản lý SQLite (chẳng hạn như Trình duyệt DB, Navicat, v.v.) sẽ không tự động thay đổi số phiên bản. Do đó, bạn sẽ phải cố ý thay đổi user_version để nó có sẵn trước khi sao chép tệp cơ sở dữ liệu vào thư mục nội dung (lưu ý rằng nếu làm như vậy và bạn đang sử dụng lớp con của SQLiteOpenHelper rằng onUpgradeonDowngrade phương thức có thể được gọi).

Nếu user_version không được thay đổi cụ thể và cơ sở dữ liệu chỉ được truy cập bởi công cụ SQLite Manager thì user_version sẽ bằng 0. Nếu tệp cơ sở dữ liệu được mở bằng cách sao chép tệp cơ sở dữ liệu từ một Ứng dụng Android sử dụng lớp con của SQLiteOpenHelper nó sẽ có một user_version của 1 hoặc nhiều hơn (tùy thuộc vào giá trị cuối cùng được sử dụng làm tham số thứ 4 cho công cụ tạo của SQLiteOpenHelper). Tất nhiên nếu user_version được thay đổi theo chương trình thì thay đổi đó cũng sẽ được phản ánh nếu tệp được sao chép vào công cụ SQlite Manager.

Trước khi sao chép tệp, user_version thường sẽ được thay đổi trong công cụ SQlite Manager thành một giá trị thích hợp.

Bạn có thể thay đổi user_version sử dụng SQL PRAGMA user_version = 5; Bạn có thể truy xuất user_version sử dụng PRAGMA user_version hoặc SELECT * FROM pragma_user_version;

Nếu bạn cần kiểm tra phiên bản trước khi mở cơ sở dữ liệu thì bạn có thể đọc 4 byte ở độ lệch 60 và chuyển 4 byte thành số nguyên, để kiểm tra user_version với giá trị khác. Nếu không, bạn có thể phải sao chép tệp, có thể sử dụng một tên khác, từ thư mục nội dung, mở nó dưới dạng SQLiteDatabase và truy xuất user_version bằng cách sử dụng SQL ở trên, sau đó kiểm tra nó với giá trị khác, đóng tệp cơ sở dữ liệu. Việc xóa tệp nếu không cần thiết, nếu không thì xóa tệp cơ sở dữ liệu trước đó rồi đổi tên tệp đã sao chép.

Ví dụ

Sau đây là một ví dụ hoạt động (lưu ý rằng tôi hiếm khi sử dụng Kotlin và điều này đã được chuyển đổi bằng cách sử dụng AS studio từ java).

Điều này sử dụng một lớp, cụ thể là SQLAssetVersionCheck trích xuất số phiên bản từ tệp thay vì mở tệp dưới dạng 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
    }
}

Và đây là Hoạt động sử dụng lớp trên hai lần để cố gắng kiểm tra phiên bản trong testdb tệp.

  • Lần sử dụng đầu tiên không tìm thấy tệp cơ sở dữ liệu testdb vì nó đang tìm kiếm trong nội dung thư mục (không phải thư mục con của cơ sở dữ liệu).

  • Cách sử dụng thứ hai tìm testdb tệp dưới dạng thư mục con cơ sở dữ liệu được chỉ định (tham số thứ 3 của hàm tạo đầy đủ), tìm thấy trong nội dung / cơ sở dữ liệu / thư mục tức là tài sản / cơ sở dữ liệu / 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")
    }
}

Kết quả (nhật ký):-

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
  • Lần thử đầu tiên không tìm thấy tệp (ngoại lệ đã bị bắt được hiển thị) và hiển thị dòng Kết quả kiểm tra phiên bản là - Nội dung, cho Cơ sở dữ liệu testdb không được đặt tại testdb được hiển thị.

  • Lần thử thứ hai hoạt động và dẫn đến Kết quả của việc kiểm tra phiên bản là - Nội dung đã được định vị và số phiên bản là 5 thấp hơn phiên bản cần kiểm tra là 100

  • Khoảng cách của các dòng trống đã được thêm vào để tách lần thử thứ hai với lần đầu tiên.

Bổ sung

Sau khi sử dụng công cụ SQLite Manager (Navicat) và sử dụng:-

PRAGMA user_version = 101;

Sau đó sao chép tệp (sau khi đóng kết nối trong Navicat) vào thư mục tài sản (vì vậy tôi có hai tệp testdb) thì kết quả là:-

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
  • tức là tệp mới có user_version là 101 và vì vậy tệp đầu tiên tìm thấy tệp, tệp thứ hai tìm tệp (user_version 5) như trước đây.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để an toàn luồng EnableWriteAheadLogging trong bối cảnh sử dụng thực tế và tài liệu SQLite?

  2. Làm cách nào để viết SQLite Real vals sang các giá trị BigDecimal của Java?

  3. Kết hợp Số lượng SQLite () với GROUP BY để Thêm cột “Đếm” vào Tập kết quả của bạn

  4. SQLITE không thể nâng cấp cơ sở dữ liệu chỉ đọc từ phiên bản 1 lên 2

  5. Cập nhật ListView dựa trên ContentProvider được SQLite hỗ trợ