在 Android SQLite 上执行“PRAGMAcompile_options”没有输出任何内容

问题描述 投票:0回答:1

我在Android上使用sqlite,如何在操作系统内获取Android Sqlite上的compile_options

私人乐趣 getChunkSizeFromSqlite() { val db = BundleStorageProvider.getDb(mPlatformType) ?: 返回

val cursor = db.query("PRAGMA compile_options")
while (cursor.moveToNext()) {
  val compileOption = cursor.getString(0)
  KxbLog.i("hello", compileOption)
}
android sqlite android-room
1个回答
0
投票

如何在操作系统内获取Android Sqlite上的compile_options

我不相信你可以,因为使用的编译似乎具有 SQLITE_OMIT_COMPILEOPTION_DIAGS 选项。

更具体地考虑以下函数(基本上相同,但一个用于 SQLiteDatabase(非房间),另一个用于 SupportSQLiteDatabase(房间)):-

    private fun getCompileTimeOptions(db: SQLiteDatabase) {
        try {
            val sb = StringBuilder()
            for (i in 1..10) {
                val csr = db.rawQuery(" SELECT sqlite_compileoption_get(${i})",null)
                while (csr.moveToNext()) {
                    sb.append("Compile Option ${i} is ${csr.getString(0)}")
                }
                csr.close()
            }
            Log.d(TAG, sb.toString())
        } catch (e: Exception) {
            Log.d(TAG,"Exception Caught: ${e.cause}")
        }
        try {
            var csr = db.rawQuery("PRAGMA compile_options",null)
            DatabaseUtils.dumpCursor(csr)
            csr = db.rawQuery("SELECT * FROM pragma_compile_options",null)
            DatabaseUtils.dumpCursor(csr)
            csr.close()

        } catch (e: Exception) {
            Log.d(TAG,"Exception Caught: ${e.cause}")
        }
    }
    private fun getCompileOptions(db: SupportSQLiteDatabase) {
        try {
            val sb = StringBuilder()
            for (i in 1..10) {
                val csr = db.query(" SELECT sqlite_compileoption_get(${i})")
                while (csr.moveToNext()) {
                    sb.append("Compile Option ${i} is ${csr.getString(0)}")
                }
                csr.close()
            }
            Log.d(TAG, sb.toString())
        } catch (e: Exception) {
            Log.d(TAG,"Exception Caught: ${e.cause}")
        }
        try {

            var csr = db.query("PRAGMA compile_options")
            DatabaseUtils.dumpCursor(csr)
            csr = db.query("SELECT * FROM pragma_compile_options")
            DatabaseUtils.dumpCursor(csr)
            csr.close()
        } catch (e: Exception) {
            Log.d(TAG,"Exception Caught: ${e.cause}")
        }
    }

第一个函数在通过以下方式检索数据库后调用 Room

databaseBuilder
之前调用:-

    fun preOpenSchemaDump(context: Context) {
        if (context.getDatabasePath(DB_NAME).exists()) {
            val db = SQLiteDatabase.openDatabase(
                context.getDatabasePath(DB_NAME).path,
                null,
                SQLiteDatabase.OPEN_READWRITE
            )
            Log.d(TAG,"Database Version is ${db.version}: Room version will be ${DB_VERSION}" )
            dumpSchema("PreOpen invoked", db)
            getCompileTimeOptions(db) /*<<<<<<<<<<*/
            db.close()
        } else {
            Log.d(TAG,"PreOpen Invoked but Database does not exist yet (nothing to dump so skipped)")
        }
    }

第二个函数是通过

CallBack
在重写的
onOpen
onCreate
方法中调用的。

所有这些都在返回

@Database
带注释的类的实例的函数内处理,如下所示:-

    fun getInstance(context: Context): RoomDatabaseImpl {
        if (instance==null) {
            preOpenSchemaDump(context) /*<<<<<<<<<< */
            instance= Room.databaseBuilder(context,RoomDatabaseImpl::class.java, DB_NAME)
                .allowMainThreadQueries() /* For brevity */
                .addCallback(CB) /* added for debugging */ /* <<<<<<<<<< */
                .addMigrations(Migration1To2,Migration2To3,Migration3To4)
                .build()
        }
        return instance as RoomDatabaseImpl
    }

可以看出,两个函数都尝试通过 3 种方法获取编译时选项

  1. 通过
    sqlite_compileoption_get
    标量函数
  2. 通过
    COMPILE_OPTIONS
    PRAGMA
  3. 通过 PRAGMA 的表值版本,即
    SELECT * FROM pragma_compile_options

结果是调用(无论是通过 SQLiteDatabase 对象还是 SupportSQLiteDatabase 对象调用):-

2024-04-27 11:00:18.698 D/DBINFO: PreOpen invoked - dumping schema to log:-
2024-04-27 11:00:18.699 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@aa6612
2024-04-27 11:00:18.699 I/System.out: 0 {
2024-04-27 11:00:18.699 I/System.out:    type=table
2024-04-27 11:00:18.699 I/System.out:    name=android_metadata
2024-04-27 11:00:18.699 I/System.out:    tbl_name=android_metadata
2024-04-27 11:00:18.699 I/System.out:    rootpage=3
2024-04-27 11:00:18.700 I/System.out:    sql=CREATE TABLE android_metadata (locale TEXT)
2024-04-27 11:00:18.700 I/System.out: }
2024-04-27 11:00:18.700 I/System.out: 1 {
2024-04-27 11:00:18.700 I/System.out:    type=table
2024-04-27 11:00:18.700 I/System.out:    name=project
2024-04-27 11:00:18.700 I/System.out:    tbl_name=project
2024-04-27 11:00:18.700 I/System.out:    rootpage=4
2024-04-27 11:00:18.700 I/System.out:    sql=CREATE TABLE `project` (`id` TEXT NOT NULL, `uuid` TEXT NOT NULL, `name` TEXT NOT NULL, `startDate` TEXT, `endDate` TEXT, `venueName` TEXT, `timeZone` TEXT, `scheduledAnonymisationDate` TEXT, `nfcCollectorId` TEXT, `nfcMerchantId` TEXT, `nfcPrivateKey` TEXT, `nfcProfileId` TEXT, PRIMARY KEY(`id`))
2024-04-27 11:00:18.700 I/System.out: }
2024-04-27 11:00:18.700 I/System.out: 2 {
2024-04-27 11:00:18.700 I/System.out:    type=index
2024-04-27 11:00:18.700 I/System.out:    name=sqlite_autoindex_project_1
2024-04-27 11:00:18.701 I/System.out:    tbl_name=project
2024-04-27 11:00:18.701 I/System.out:    rootpage=5
2024-04-27 11:00:18.701 I/System.out:    sql=null
2024-04-27 11:00:18.701 I/System.out: }
2024-04-27 11:00:18.701 I/System.out: 3 {
2024-04-27 11:00:18.701 I/System.out:    type=index
2024-04-27 11:00:18.701 I/System.out:    name=index_project_uuid
2024-04-27 11:00:18.701 I/System.out:    tbl_name=project
2024-04-27 11:00:18.701 I/System.out:    rootpage=6
2024-04-27 11:00:18.701 I/System.out:    sql=CREATE INDEX `index_project_uuid` ON `project` (`uuid`)
2024-04-27 11:00:18.701 I/System.out: }
2024-04-27 11:00:18.701 I/System.out: 4 {
2024-04-27 11:00:18.701 I/System.out:    type=table
2024-04-27 11:00:18.701 I/System.out:    name=room_master_table
2024-04-27 11:00:18.702 I/System.out:    tbl_name=room_master_table
2024-04-27 11:00:18.702 I/System.out:    rootpage=7
2024-04-27 11:00:18.702 I/System.out:    sql=CREATE TABLE room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)
2024-04-27 11:00:18.702 I/System.out: }
2024-04-27 11:00:18.702 I/System.out: <<<<<
2024-04-27 11:00:18.702 E/SQLiteLog: (1) no such function: sqlite_compileoption_get
2024-04-27 11:00:18.702 D/DBINFO: Exception Caught: null
2024-04-27 11:00:18.702 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor@79321e3
2024-04-27 11:00:18.703 I/System.out: <<<<<
2024-04-27 11:00:18.703 E/SQLiteLog: (1) no such table: pragma_compile_options
2024-04-27 11:00:18.703 D/DBINFO: Exception Caught: null

所以

  1. sqlite_compileoption_get
    不是已知函数,
  2. PRAGMA 检索到的游标是空的,根据 “如果发出未知的编译指示,则不会生成错误消息。未知的编译指示将被简单地忽略。” https://www.sqlite.org/pragma.html#pragma_compile_options
  3. pragma_compile_options
    表不存在。

一切都非常符合您的预期:-

此选项用于省略 SQLite 中可用的编译时选项诊断,包括 sqlite3_compileoption_used() 和 sqlite3_compileoption_get() C/C++ 函数、sqlite_compileoption_used() 和 sqlite_compileoption_get() SQL 函数以及compile_options pragma。

© www.soinside.com 2019 - 2024. All rights reserved.