当前位置:   article > 正文

2021SC@SDUSC SQLite源码分析(十二)————SQLite 数据库文件打开过程_usc文件怎么开

usc文件怎么开

2021SC@SDUSC SQLite源码分析(十二)————SQLite 数据库文件打开过程


前言

基于前面的博客分析和小组内成员的讨论,对数据库文件的打开过程做出分析与总结


过程分析

官方文档中的过程介绍

在这里插入图片描述

逐步分析

1、
main():
位于 shell.c
从命令行参数中得到数据库名,如果数据库文件存在,则打开它。
2、
open_db():
位于 shell.c
功能:确认数据库是否已经打开。如果已打开,则什么都不做。如果没有,则打开它。如果打开失败,输出一个错误信息。
3、
sqlite3_open():
位于 main.c。
功能:打开一个数据库。
该函数中只包含对 opendatabase()的调用,但调用的参数与sqlite3_open_v2()所使用的参数不同。
4、
opendatabase():
位于 main.c。
功能:这个函数为 sqlite3_open()和 sqlite3_open16()工作,打开一个数据库。数据库文件名
"zFilename"采用 UTF-8 编码。
先生成各类标志,然后生成默认的排序法。当需要生成数据库后台驱动时,调用sqlite3BtreeFactory()。
在此函数中真正分配 sqlite 结构的空间:db=sqlite3MallocZero(sizeof(sqlite3) )。
在调用 sqlite3BtreeFactory()之前,需要对 db 的一些域进行设置。

部分源码:

static int openDatabase(
  const char *zFilename, /* Database filename UTF-8 encoded */
  sqlite3 **ppDb,        /* OUT: Returned database handle */
  unsigned int flags,    /* Operational flags */
  const char *zVfs       /* Name of the VFS to use */
){
  sqlite3 *db;                    /* Store allocated handle here */
  int rc;                         /* Return code */
  int isThreadsafe;               /* True for threadsafe connections */
  char *zOpen = 0;                /* Filename argument to pass to BtreeOpen() */
  char *zErrMsg = 0;              /* Error message from sqlite3ParseUri() */
  int i;                          /* Loop counter */
#ifdef SQLITE_ENABLE_API_ARMOR
  if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
#endif
  *ppDb = 0;
#ifndef SQLITE_OMIT_AUTOINIT
  rc = sqlite3_initialize();
  if( rc ) return rc;
#endif

  if( sqlite3GlobalConfig.bCoreMutex==0 ){
    isThreadsafe = 0;
  }else if( flags & SQLITE_OPEN_NOMUTEX ){
    isThreadsafe = 0;
  }else if( flags & SQLITE_OPEN_FULLMUTEX ){
    isThreadsafe = 1;
  }else{
    isThreadsafe = sqlite3GlobalConfig.bFullMutex;
  }

  if( flags & SQLITE_OPEN_PRIVATECACHE ){
    flags &= ~SQLITE_OPEN_SHAREDCACHE;
  }else if( sqlite3GlobalConfig.sharedCacheEnabled ){
    flags |= SQLITE_OPEN_SHAREDCACHE;
  }
   /* Allocate the sqlite data structure */
  db = sqlite3MallocZero( sizeof(sqlite3) );
  if( db==0 ) goto opendb_out;
  if( isThreadsafe 
#ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS
   || sqlite3GlobalConfig.bCoreMutex
#endif
  ){
    db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
    if( db->mutex==0 ){
      sqlite3_free(db);
      db = 0;
      goto opendb_out;
    }
    if( isThreadsafe==0 ){
      sqlite3MutexWarnOnContention(db->mutex);
    }
  }
  sqlite3_mutex_enter(db->mutex);
  db->errMask = 0xff;
  db->nDb = 2;
  db->magic = SQLITE_MAGIC_BUSY;
  db->aDb = db->aDbStatic;
  db->lookaside.bDisable = 1;
  db->lookaside.sz = 0;

  assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
  memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
  db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS;
  db->autoCommit = 1;
  db->nextAutovac = -1;
  db->szMmap = sqlite3GlobalConfig.szMmap;
  db->nextPagesize = 0;
  db->nMaxSorterMmap = 0x7FFFFFFF;
  db->flags |= SQLITE_ShortColNames
                 | SQLITE_EnableTrigger
                 | SQLITE_EnableView
                 | SQLITE_CacheSpill
#if !defined(SQLITE_TRUSTED_SCHEMA) || SQLITE_TRUSTED_SCHEMA+0!=0
                 | SQLITE_TrustedSchema
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77

5、
sqlite3BtreeFactory()
位于 main.c。
功能:本函数创建到数据库 BTree 驱动的连接。如果 zFilename 是文件名,则打开并使用它。
如果 zFilename 是":memory:",则使用内存数据库(在连接断开时释放)。
如果 zFilename 为空且数据库是虚拟(virtual)的,则只是暂时使用,在连接断开时被删除。
虚拟数据库可以是磁盘文件或就在内存中,由 sqlite3TempInMemory()函数来决定是哪一种
情况。
6、
sqlite3BtreeOpen():
位于 btree.c。
功能:打开一个数据库文件。
由于在 sqlite3BtreeFactory()中已经调用过 sqlite3TempInMemory()函数,所以此处逻辑稍简单
了一些。
zFilename 是数据库文件名。如果 zFilename 为空,创建一个具有随机文件名的数据库,这
个数据库会在调用 sqlite3BtreeClose()时被删除。
如果 zFilename 是":memory:",创建内存数据库,并在关闭时被释放。
如果此 Btree 是共享缓冲区的候选者,则尝试寻找一个已存在的 BtShared 来共享。
如果不是共享缓冲区的候选者或未找到已存在的BtShared,则调用 sqlite3PagerOpen()函数打
开文件。
文件打开之后,调用 sqlite3PagerReadFileheader()来读文件头中的配置信息。
7、
sqlite3PagerOpen():
位于 pager.c。
功能:分配并初始化一个新 Pager 对象,将其指针放到*ppPager。

该 pager 会在调用 sqlite3PagerClose()时被释放。
zFilename 参数是要打开的数据库文件的路径。
如果 zFilename 为空,创建随机文件名的文件。
如果 pager 对象已分配且指定文件打开成功,返回 SQLITE_OK 并将*ppPager 指向新 pager
对象。
如果有错误发生,*ppPager 置空并返回错误代码。
执行过程是:先申请空间,再调用 sqlite3OsOpen()打开文件(如果需要),再根据打开的文
件设置内存。
8、
sqlite3OsOpen():
位于 os.c。
功能:打开一个文件,与具体的操作系统无关。
是一种 VFS 封装。VFS : “virtual file system”,虚拟文件系统。
本函数只有几条语句,只有一条关键语句:
rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x7f1f, pFlagsOut);
对于 Win32 操作系统,该语句实际调用的是 winOpen()函数。

int sqlite3OsOpen(
  sqlite3_vfs *pVfs,
  const char *zPath,
  sqlite3_file *pFile,
  int flags,
  int *pFlagsOut
){
  int rc;
  DO_OS_MALLOC_TEST(0);
  /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
  ** down into the VFS layer.  Some SQLITE_OPEN_ flags (for example,
  ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
  ** reaching the VFS. */
  rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x1087f7f, pFlagsOut);
  assert( rc==SQLITE_OK || pFile->pMethods==0 );
  return rc;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

9、
winOpen():
位于 os_win.c。
功能:打开一个 Windows 操作系统文件。
先将文件名转换为操作系统所使用的编码。再设置一系列参数。
最终调用操作系统函数 CreateFileA()打开文件。
10、
CreateFileA():
位于 WINBASE.H。
功能:
打开文件名所指定的文件。如果文件不存在,则创建。

参考资料:《Inside SQLite》

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/490941
推荐阅读
相关标签
  

闽ICP备14008679号