コード例 #1
0
    private static int GetFileVersion(string filePath)
    {
        if (IsVersion1(filePath))
        {
            return(1);
        }

        // Versions 2+ are SQLite databases. Open it and read the version number inside.
        var sqlite = IntPtr.Zero; //sqlite3*
        var stmt   = IntPtr.Zero; // sqlite3_stmt*

        try {
            using NativeString filePathNative = new(filePath);
            using NativeBuffer sqliteBuffer   = new(IntPtr.Size);
            var result = NativeMethods.sqlite3_open(filePathNative.Ptr, sqliteBuffer.Ptr);
            if (result != NativeMethods.SQLITE_OK)
            {
                throw new Exception("This is not an SQL Notebook file.");
            }
            sqlite = Marshal.ReadIntPtr(sqliteBuffer.Ptr);

            var versionSql = "SELECT version FROM _sqlnotebook_version";
            using NativeString versionSqlNative  = new(versionSql);
            using NativeBuffer versionStmtNative = new(IntPtr.Size);
            result = NativeMethods.sqlite3_prepare_v2(sqlite, versionSqlNative.Ptr, versionSqlNative.ByteCount,
                                                      versionStmtNative.Ptr, IntPtr.Zero);
            stmt = Marshal.ReadIntPtr(versionStmtNative.Ptr); // sqlite3_stmt*
            if (result != NativeMethods.SQLITE_OK || stmt == IntPtr.Zero)
            {
                // it's ok, a plain SQLite database is a valid version 2 SQL Notebook file
                return(2);
            }

            if (NativeMethods.sqlite3_step(stmt) == NativeMethods.SQLITE_ROW)
            {
                return(NativeMethods.sqlite3_column_int(stmt, 0));
            }
            return(2); // missing version row; it's still a valid version 2 file
        } finally {
            if (stmt != IntPtr.Zero)
            {
                SqliteUtil.ThrowIfError(sqlite, NativeMethods.sqlite3_finalize(stmt));
            }
            if (sqlite != IntPtr.Zero)
            {
                SqliteUtil.ThrowIfError(IntPtr.Zero, NativeMethods.sqlite3_close(sqlite));
            }
        }
    }