SQLite源码解析

一、SQLite源码解析

(1)SQLiteOpenHelper源码

    public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,
            @Nullable CursorFactory factory, int version) {
        this(context, name, factory, version, null);
    }

    public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,
            @Nullable CursorFactory factory, int version,
            @Nullable DatabaseErrorHandler errorHandler) {
        this(context, name, factory, version, 0, errorHandler);
    }

    public SQLiteOpenHelper(@Nullable Context context, @Nullable String name,
            @Nullable CursorFactory factory, int version,
            int minimumSupportedVersion, @Nullable DatabaseErrorHandler errorHandler) {
        this(context, name, version, minimumSupportedVersion,
                new SQLiteDatabase.OpenParams.Builder());
        mOpenParamsBuilder.setCursorFactory(factory);
        mOpenParamsBuilder.setErrorHandler(errorHandler);
    }

    private SQLiteOpenHelper(@Nullable Context context, @Nullable String name, int version,
            int minimumSupportedVersion,
            @NonNull SQLiteDatabase.OpenParams.Builder openParamsBuilder) {
        Preconditions.checkNotNull(openParamsBuilder);
        if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);

        mContext = context;
        mName = name;
        mNewVersion = version;
        mMinimumSupportedVersion = Math.max(0, minimumSupportedVersion);
        setOpenParamsBuilder(openParamsBuilder);
    }

(2)SQLiteOpenHelper.getWritableDatabase与getReadableDatabase源码


    //获得一个可读写的数据库
    public SQLiteDatabase getWritableDatabase() {
        synchronized (this) {
            return getDatabaseLocked(true);
        }
    }

    //获得一个只读的数据库
    public SQLiteDatabase getReadableDatabase() {
        synchronized (this) {
            return getDatabaseLocked(false);
        }
    }

    private SQLiteDatabase getDatabaseLocked(boolean writable) {
        if (mDatabase != null) {
            if (!mDatabase.isOpen()) {
                //如果数据库已经关闭,需要重新打开
                mDatabase = null;
            } else if (!writable || !mDatabase.isReadOnly()) {
                //数据库没有关闭,直接返回
                return mDatabase;
            }
        }
        SQLiteDatabase db = mDatabase;
        try {
            mIsInitializing = true;
            if (db != null) {
                if (writable && db.isReadOnly()) {
                    //当前数据是只读状态,需要获取可写的数据库
                    db.reopenReadWrite();
                }
            } else if (mName == null) {
                //数据库名称为null,为Memory Db
                db = SQLiteDatabase.createInMemory(mOpenParamsBuilder.build());
            } else {
                //获取数据库保存路径
                final File filePath = mContext.getDatabasePath(mName);
                //数据库创建的相关配置项
                SQLiteDatabase.OpenParams params = mOpenParamsBuilder.build();
                try {
                    //创建数据库操作SQLiteDatabase实例
                    db = SQLiteDatabase.openDatabase(filePath, params);
                    setFilePermissionsForDb(filePath.getPath());
                } catch (SQLException ex) {
                    if (writable) {
                        throw ex;
                    }
                    params = params.toBuilder().addOpenFlags(SQLiteDatabase.OPEN_READONLY).build();
                    db = SQLiteDatabase.openDatabase(filePath, params);
                }
            }
            //创建数据库成功,回调此方法配置数据库
            onConfigure(db);
            //获取当前数据库版本,默认为0
            final int version = db.getVersion();
            //mNewVersion是自行设置的版本号
            if (version != mNewVersion) {
                //此时如果是只读状态,将无法对数据库做任何更改
                if (db.isReadOnly()) {
                    throw new SQLiteException("Can't upgrade read-only database from version " +
                            db.getVersion() + " to " + mNewVersion + ": " + mName);
                }
                //如果当前版本号小于最小支持的版本,删除数据库
                if (version > 0 && version < mMinimumSupportedVersion) {
                    File databaseFile = new File(db.getPath());
                    onBeforeDelete(db);
                    db.close();
                    //删除数据库文件
                    if (SQLiteDatabase.deleteDatabase(databaseFile)) {
                        mIsInitializing = false;
                        //删除成功重新创建数据库
                        return getDatabaseLocked(writable);
                    } else {
                        throw new IllegalStateException("Unable to delete obsolete database "
                                + mName + " with version " + version);
                    }
                } else {
                    //开启事务
                    db.beginTransaction();
                    try {
                        //数据库第一次创建回调执行onCreate
                        if (version == 0) {
                            onCreate(db);
                        } else {
                            if (version > mNewVersion) {
                                //降级回调
                                onDowngrade(db, version, mNewVersion);
                            } else {
                                //升级回调
                                onUpgrade(db, version, mNewVersion);
                            }
                        }
                        //设置当前最后版本
                        db.setVersion(mNewVersion);
                        db.setTransactionSuccessful();
                    } finally {
                        db.endTransaction();
                    }
                }
            }
            //表示数据库已经打开回调
            onOpen(db);
            //赋值给当前成员
            mDatabase = db;
            return db;
        } finally {
            mIsInitializing = false;
            if (db != null && db != mDatabase) {
                db.close();
            }
        }
    }

    //获取自定义或默认路径
    @Override
    public File getDatabasePath(String name) {
        File dir;
        File f;

        if (name.charAt(0) == File.separatorChar) {
            //自定义存储路径
            String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
            dir = new File(dirPath);
            name = name.substring(name.lastIndexOf(File.separatorChar));
            f = new File(dir, name);

            if (!dir.isDirectory() && dir.mkdir()) {
                FileUtils.setPermissions(dir.getPath(),
                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
                    -1, -1);
            }
        } else {
            //默认路径
            dir = getDatabasesDir();
            f = makeFilename(dir, name);
        }

        return f;
    }

    public static final class OpenParams {
        //保存当前数据库相关配置
        private OpenParams(int openFlags, CursorFactory cursorFactory,
                DatabaseErrorHandler errorHandler, int lookasideSlotSize, int lookasideSlotCount,
                long idleConnectionTimeout, String journalMode, String syncMode) {
            //打开模式
            mOpenFlags = openFlags;
            //Cursor工厂
            mCursorFactory = cursorFactory;
            mErrorHandler = errorHandler;
            mLookasideSlotSize = lookasideSlotSize;
            mLookasideSlotCount = lookasideSlotCount;
            //空闲连接超时时间
            mIdleConnectionTimeout = idleConnectionTimeout;
            //日志模式
            mJournalMode = journalMode;
            //同步模式
            mSyncMode = syncMode;
        }
    }

SQLiteOpenHelper主要完成SQLiteDatabase 的创建、关闭、升/降级、配置等相关辅助管理
(3)SQLiteDatabase.openDatabase获取SQLiteDatabase实例源码

    public static SQLiteDatabase openDatabase(@NonNull File path,
            @NonNull OpenParams openParams) {
        return openDatabase(path.getPath(), openParams);
    }

    private static SQLiteDatabase openDatabase(@NonNull String path,
            @NonNull OpenParams openParams) {
        Preconditions.checkArgument(openParams != null, "OpenParams cannot be null");
        //创建SQLiteDatabase实例,将OpenParams配置参数传入SQLiteDatabase
        SQLiteDatabase db = new SQLiteDatabase(path, openParams.mOpenFlags,
                openParams.mCursorFactory, openParams.mErrorHandler,
                openParams.mLookasideSlotSize, openParams.mLookasideSlotCount,
                openParams.mIdleConnectionTimeout, openParams.mJournalMode, openParams.mSyncMode);
        //调用SQLiteDatabase的open
        db.open();
        return db;
    }

    //将前面保存相关创建配置的 OpenParams 信息保存到 SQLiteDatabaseConfiguartion 中
    private SQLiteDatabase(final String path, final int openFlags,
            CursorFactory cursorFactory, DatabaseErrorHandler errorHandler,
            int lookasideSlotSize, int lookasideSlotCount, long idleConnectionTimeoutMs,
            String journalMode, String syncMode) {
        mCursorFactory = cursorFactory;
        mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler();
        //SQLiteDatabase的创建模式,主要影响数据库连接池打开模式
        mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags);
        mConfigurationLocked.lookasideSlotSize = lookasideSlotSize;
        mConfigurationLocked.lookasideSlotCount = lookasideSlotCount;
        //禁用低内存设备上的lookaside分配器
        if (ActivityManager.isLowRamDeviceStatic()) {
            mConfigurationLocked.lookasideSlotCount = 0;
            mConfigurationLocked.lookasideSlotSize = 0;
        }
        long effectiveTimeoutMs = Long.MAX_VALUE;
        // Never close idle connections for in-memory databases
        if (!mConfigurationLocked.isInMemoryDb()) {
            //空闲连接超时,默认值-1表示未设置值
            if (idleConnectionTimeoutMs >= 0) {
                effectiveTimeoutMs = idleConnectionTimeoutMs;
            } else if (DEBUG_CLOSE_IDLE_CONNECTIONS) {
                //默认为false,表示空闲连接不会被关闭
                effectiveTimeoutMs = SQLiteGlobal.getIdleConnectionTimeout();
            }
        }
        mConfigurationLocked.idleConnectionTimeoutMs = effectiveTimeoutMs;
        mConfigurationLocked.journalMode = journalMode;
        mConfigurationLocked.syncMode = syncMode;
        if (!SQLiteGlobal.isCompatibilityWalSupported() || (
                SQLiteCompatibilityWalFlags.areFlagsSet() && !SQLiteCompatibilityWalFlags
                        .isCompatibilityWalSupported())) {
            //不支持兼容性WAL,则禁用掉兼容性WAL
            mConfigurationLocked.openFlags |= DISABLE_COMPATIBILITY_WAL;
        }
    }

    private void open() {
        try {
            try {
                openInner();
            } catch (SQLiteDatabaseCorruptException ex) {
                onCorruption();
                openInner();
            }
        } catch (SQLiteException ex) {
            close();
            throw ex;
        }
    }

    //创建当前SQLiteDatabase的数据库连接池SQLiteConnectionPool
    private void openInner() {
        synchronized (mLock) {
            assert mConnectionPoolLocked == null;
            //打开数据库连接池,ConfigurationLocked作为参数
            mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked);
            mCloseGuardLocked.open("close");
        }

        synchronized (sActiveDatabases) {
            //缓存当前SQLiteDatabase实例
            sActiveDatabases.put(this, null);
        }
    }

(4)SQLiteConnectionPool.open源码

    public static SQLiteConnectionPool open(SQLiteDatabaseConfiguration configuration) {
        if (configuration == null) {
            throw new IllegalArgumentException("configuration must not be null.");
        }
        //创建数据库连接池
        SQLiteConnectionPool pool = new SQLiteConnectionPool(configuration);
        //调用open可能抛出异常
        pool.open(); 
        return pool;
    }

    private SQLiteConnectionPool(SQLiteDatabaseConfiguration configuration) {
        mConfiguration = new SQLiteDatabaseConfiguration(configuration);
        //设置连接池的大小
        setMaxConnectionPoolSizeLocked();
        //在Long.MAX_VALUE下永远不会关闭连接
        if (mConfiguration.idleConnectionTimeoutMs != Long.MAX_VALUE) {
            //超时管理的Handler
            setupIdleConnectionHandler(Looper.getMainLooper(),
                    mConfiguration.idleConnectionTimeoutMs);
        }
    }

    private void setMaxConnectionPoolSizeLocked() {
        if (!mConfiguration.isInMemoryDb()
                && (mConfiguration.openFlags & SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING) != 0) {
            mMaxConnectionPoolSize = SQLiteGlobal.getWALConnectionPoolSize();
        } else {
            mMaxConnectionPoolSize = 1;
        }
    }

    //SQLiteGlobal.java
    public static int getWALConnectionPoolSize() {
        int value = SystemProperties.getInt("debug.sqlite.wal.poolsize",
                Resources.getSystem().getInteger(
                com.android.internal.R.integer.db_connection_pool_size));
        //连接池默认最小为2,最大取决于系统配置
        return Math.max(2, value);
    }

    @VisibleForTesting
    public void setupIdleConnectionHandler(Looper looper, long timeoutMs) {
        synchronized (mLock) {
            //创建IdleConnectionHandler,超时管理的Handler
            mIdleConnectionHandler = new IdleConnectionHandler(looper, timeoutMs);
        }
    }

    private class IdleConnectionHandler extends Handler {
        //保存配置的空闲连接超时时间
        private final long mTimeout;

        IdleConnectionHandler(Looper looper, long timeout) {
            super(looper);
            mTimeout = timeout;
        }

        @Override
        public void handleMessage(Message msg) {
            // Skip the (obsolete) message if the handler has changed
            synchronized (mLock) {
                if (this != mIdleConnectionHandler) {
                    return;
                }
                //关闭空闲超时的SQLiteConnection
                if (closeAvailableConnectionLocked(msg.what)) {
                }
            }
        }

        void connectionReleased(SQLiteConnection con) {
            //根据连接id,发送超时消息
            sendEmptyMessageDelayed(con.getConnectionId(), mTimeout);
        }

        void connectionAcquired(SQLiteConnection con) {
            removeMessages(con.getConnectionId());
        }

        void connectionClosed(SQLiteConnection con) {
            //移除当前超时机制,说明连接被重新使用
            removeMessages(con.getConnectionId());
        }
    }

    private void open() {
        //创建数据库主链接,只有主连接才可以写数据库,每一个数据库连接池默认仅有一条主连接
        mAvailablePrimaryConnection = openConnectionLocked(mConfiguration,
                true /*primaryConnection*/);
        synchronized (mLock) {
            if (mIdleConnectionHandler != null) {
                //由于此时还没有任何使用,故开启空闲超时关闭机制
                mIdleConnectionHandler.connectionReleased(mAvailablePrimaryConnection);
            }
        }
        mIsOpen = true;
        mCloseGuard.open("close");
    }

    private SQLiteConnection openConnectionLocked(SQLiteDatabaseConfiguration configuration,
            boolean primaryConnection) {
        //当前连接的唯一id
        final int connectionId = mNextConnectionId++;
        //创建连接
        return SQLiteConnection.open(this, configuration,
                connectionId, primaryConnection); // might throw
    }

    //从连接池获取到一个 SQLiteConnection
    public SQLiteConnection acquireConnection(String sql, int connectionFlags,
            CancellationSignal cancellationSignal) {
        //获取一个SQLiteConnection
        SQLiteConnection con = waitForConnection(sql, connectionFlags, cancellationSignal);
        synchronized (mLock) {
            if (mIdleConnectionHandler != null) {
                //移除该连接的超时关闭消息
                mIdleConnectionHandler.connectionAcquired(con);
            }
        }
        return con;
    }

    //对该连接开启超时关闭机制
    public void releaseConnection(SQLiteConnection connection) {
        synchronized (mLock) {
            if (mIdleConnectionHandler != null) {
                //重新加入超时关闭机制
                mIdleConnectionHandler.connectionReleased(connection);
            }
            //code...
        }
    }

(5)SQLiteConnection.open源码

    static SQLiteConnection open(SQLiteConnectionPool pool,
            SQLiteDatabaseConfiguration configuration,
            int connectionId, boolean primaryConnection) {
        //创建SQLiteConnection,每个SQLiteConnection对一个native层一个操作句柄
        SQLiteConnection connection = new SQLiteConnection(pool, configuration,
                connectionId, primaryConnection);
        try {
            //调用自己的open方法
            connection.open();
            return connection;
        } catch (SQLiteException ex) {
            connection.dispose(false);
            throw ex;
        }
    }

    private SQLiteConnection(SQLiteConnectionPool pool,
            SQLiteDatabaseConfiguration configuration,
            int connectionId, boolean primaryConnection) {
        //持有数据库连接池
        mPool = pool;
        //操作日志
        mRecentOperations = new OperationLog(mPool);
        //持有数据库配置信息
        mConfiguration = new SQLiteDatabaseConfiguration(configuration);
        //该链接的唯一id
        mConnectionId = connectionId;
        //是否是主链接
        mIsPrimaryConnection = primaryConnection;
        //是否是只读模式
        mIsReadOnlyConnection = (configuration.openFlags & SQLiteDatabase.OPEN_READONLY) != 0;
        //缓存预编译后的SQL语句,内部采用LRU算法
        mPreparedStatementCache = new PreparedStatementCache(
                mConfiguration.maxSqlCacheSize);
        mCloseGuard.open("close");
    }

    private void open() {
        //创建数据库操作句柄
        mConnectionPtr = nativeOpen(mConfiguration.path, mConfiguration.openFlags,
                mConfiguration.label,
                SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME,
                mConfiguration.lookasideSlotSize, mConfiguration.lookasideSlotCount);
        //设置页缓存大小
        setPageSize();
        setForeignKeyModeFromConfiguration();
        //根据Configuration设置WAL模式
        setWalModeFromConfiguration();
        setJournalSizeLimit();
        setAutoCheckpointInterval();
        setLocaleFromConfiguration();

        // Register custom functions.
        final int functionCount = mConfiguration.customFunctions.size();
        for (int i = 0; i < functionCount; i++) {
            SQLiteCustomFunction function = mConfiguration.customFunctions.get(i);
            nativeRegisterCustomFunction(mConnectionPtr, function);
        }
    }

你可能感兴趣的:(SQLite源码解析)