SQLite
 sql >> डेटाबेस >  >> RDS >> SQLite

एंड्रॉइड में डेटाबेस फ़ाइल से संस्करण संख्या को कैसे पढ़ा जाए जो संपत्ति फ़ोल्डर में रखा गया है

एक संस्करण संख्या नहीं है, इसके बजाय संस्करण संख्या कई मान हो सकती है।

एक अनुमान के अनुसार आप user_version . के अलावा बात कर रहे हैं जिसका Android SDK SQLiteOpenHelper उपयोग करता है।

application_id . भी है , जो user_version की तरह उपयोगकर्ता चर के रूप में उपयोग किया जा सकता है।

आप पहले ही SQLite_Version का सामना कर चुके हैं, ताकि छूट दी जा सके।

डेटा_वर्जन भी है, यह संस्करण संख्या होने की संभावना नहीं है, क्योंकि इसका उद्देश्य एक संकेत के रूप में उपयोग करना है यदि डेटाबेस फ़ाइल को वास्तविक समय में संशोधित किया गया है।

स्कीमा_वर्जन भी है, आप शायद इसे चेतावनी के रूप में उपयोग नहीं करना चाहते हैं:इस प्रज्ञा के दुरुपयोग के परिणामस्वरूप डेटाबेस भ्रष्टाचार हो सकता है।

user_version

जैसा कि पहले कहा गया था कि आप शायद user_version . के बारे में बात कर रहे हैं . ध्यान देने वाली पहली बात यह है कि यह एक उपयोगकर्ता नियंत्रित चर/फ़ील्ड है जिसे कस्टम उपयोग के लिए उपलब्ध कराया गया है। SQlite user_version . का उपयोग या परिवर्तन नहीं करता है लेकिन इसे बदलने और उपयोग करने की अनुमति देता है।

इसके अलावा SQLite प्रबंधक (जैसे DB ब्राउज़र, Navicat आदि) स्वचालित रूप से संस्करण संख्या नहीं बदलेंगे। इस प्रकार आपको डेटाबेस फ़ाइल को एसेट फ़ोल्डर में कॉपी करने से पहले उपलब्ध होने के लिए उपयोगकर्ता_वर्जन को जानबूझकर बदलना होगा (ध्यान दें कि यदि ऐसा कर रहे हैं और आप SQLiteOpenHelper के उपवर्ग का उपयोग कर रहे हैं। कि onUpgrade और onDowngrade विधियों को कहा जा सकता है)।

यदि user_version विशेष रूप से नहीं बदला गया है और डेटाबेस को केवल SQLite प्रबंधक टूल द्वारा एक्सेस किया गया था तो यह user_version 0 होगा। यदि डेटाबेस फ़ाइल को किसी Android ऐप से डेटाबेस फ़ाइल को कॉपी करके खोला गया था जो SQLiteOpenHelper के उपवर्ग का उपयोग करता है, तो उसके पास होगा 1 या अधिक का user_version (SQLiteOpenHelper's constrcutor के चौथे पैरामीटर के रूप में उपयोग किए गए अंतिम मान के आधार पर)। निश्चित रूप से यदि user_version प्रोग्रामिक रूप से बदल दिया जाता है तो ऐसा परिवर्तन भी प्रतिबिंबित होगा यदि फ़ाइल को SQlite प्रबंधक टूल में कॉपी किया गया था।

फ़ाइल की प्रतिलिपि बनाने से पहले user_version को आमतौर पर SQlite प्रबंधक टूल में उचित मान में बदल दिया जाएगा।

आप user_version . को बदल सकते हैं SQL PRAGMA user_version = 5; . का उपयोग करके आप user_version . को पुनः प्राप्त कर सकते हैं या तो PRAGMA user_version . का उपयोग कर रहे हैं या SELECT * FROM pragma_user_version;

यदि आपको डेटाबेस खोलने से पहले संस्करण की जांच करने की आवश्यकता है तो आप ऑफसेट 60 पर 4 बाइट्स पढ़ सकते हैं और 4 बाइट्स को एक पूर्णांक में परिवर्तित कर सकते हैं, उपयोगकर्ता_वर्जन को किसी अन्य मान के विरुद्ध जांचने के लिए। अन्यथा आपको संभवतः फ़ाइल को कॉपी करना होगा, संभवतः एक अलग नाम का उपयोग करके, संपत्ति फ़ोल्डर से, इसे SQLiteDatabase के रूप में खोलें और उपरोक्त SQL का उपयोग करके user_version पुनर्प्राप्त करें और फिर डेटाबेस फ़ाइल को बंद करके इसे अन्य मान के विरुद्ध जांचें। यदि आवश्यक न हो तो फ़ाइल को हटाना, अन्यथा पूर्व डेटाबेस फ़ाइल को हटाना और फिर कॉपी की गई फ़ाइल का नाम बदलना।

उदाहरण

निम्नलिखित एक कामकाजी उदाहरण है (यह देखते हुए कि मैं शायद ही कभी कोटलिन का उपयोग करता हूं और इसे जावा से एएस स्टूडियो का उपयोग करके परिवर्तित किया गया है)।

यह एक वर्ग का उपयोग करता है, जिसका नाम है 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
    }
}

और यहां एक गतिविधि है जो testdb में संस्करण की जांच करने के लिए उपरोक्त वर्ग का दो बार उपयोग करती है फ़ाइल।

  • पहले उपयोग में डेटाबेस फ़ाइल नहीं मिलती testdb जैसा कि यह संपत्ति . में देख रहा है फ़ोल्डर (डेटाबेस उप-निर्देशिका नहीं)।

  • दूसरा उपयोग 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
  • पहला प्रयास फ़ाइल नहीं ढूंढता है (पकड़ा गया अपवाद प्रदर्शित होता है) और लाइन प्रदर्शित करता है संस्करण जांच का परिणाम था - एसेट, डेटाबेस टेस्टडीबी के लिए टेस्टडीबी पर स्थित नहीं था प्रदर्शित किया जाना है।

  • दूसरा प्रयास काम करता है और परिणाम संस्करण जांच का परिणाम था - संपत्ति स्थित थी और संस्करण संख्या 5 की जांच किए जाने वाले संस्करण की तुलना में कम थी जो कि 100 था

  • पहले प्रयास से दूसरे प्रयास को विभाजित करने के लिए रिक्त पंक्तियों के अंतराल को जोड़ा गया था।

अतिरिक्त

SQLite प्रबंधक टूल (Navicat) का उपयोग करने और :-

. का उपयोग करने के बाद
PRAGMA user_version = 101;

फिर फ़ाइल की प्रतिलिपि बनाना (नविकट में कनेक्शन बंद करने के बाद) संपत्ति फ़ोल्डर में (इसलिए मेरे पास दो टेस्टडीबी फाइलें हैं) तो परिणाम है:-

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
  • अर्थात नई फ़ाइल में 101 के रूप में user_version है और इसलिए पहला फ़ाइल ढूंढता है, दूसरा फ़ाइल (user_version 5) पहले की तरह ढूंढता है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. एंड्रॉइड एसक्यूलाइट डेटा अपडेट नहीं कर रहा है

  2. JSON फ़ंक्शन अब SQLite में डिफ़ॉल्ट रूप से सक्षम हैं

  3. Android SQLite डेटाबेस और ऐप अपडेट

  4. Android कक्ष डेटाबेस सभी डेटा निर्यात नहीं करेगा

  5. स्तम्भ _ID में त्रुटि नहीं है, हालांकि यह तालिका में मौजूद है