Sqlite源码解读(二)

2021SC@SDUSC

本篇开始解读代码:

开头一堆注释主要说明此文件是基于Windows NT操作系统内核(区分于Unix)

开始分析代码

#if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)

#  error "WAL mode requires support from the Windows NT kernel, compile\

 with SQLITE_OMIT_WAL."

如果不是windows NT 操作系统且没有引入WAL模式,则会报错。

关于WAL模式:Write ahead logging.WAL是一种日志模式,在3.7版本后被引入,用来保证日志一定先于对应的脏页落盘。Sqlite日志文件主要有DELETE和WAL两种。WAL较于DELETE的优点是:1.WAL支持读写并发,而DELETE读写互斥;2.WAL只需一次fsync调用,而且WAL的顺序写日志优于DELETE 的离散写日志。

#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0

#  error "Memory mapped files require support from the Windows NT kernel,\

 compile with SQLITE_MAX_MMAP_SIZE=0."

#endif

mmap是一个内存映射文件的方法,将该文件的磁盘地址映射到进程的虚拟地址。这样进程就可以用指针读写操作该内存,省去了对read()和write()系统函数的调用。

#ifndef NTDDI_WIN8

#  define NTDDI_WIN8                        0x06020000

#endif

#ifndef NTDDI_WINBLUE

#  define NTDDI_WINBLUE                     0x06030000

#endif

#ifndef NTDDI_WINTHRESHOLD

#  define NTDDI_WINTHRESHOLD                0x06040000

#endif

定义需要用到的SDK版本的常数

SDK包含了开发本Windows版本所需的函数、常数、API、相关工具及示例。

#ifndef SQLITE_WIN32_MAX_PATH_BYTES
#  define SQLITE_WIN32_MAX_PATH_BYTES   (SQLITE_WIN32_MAX_PATH_CHARS*4)
#endif
 
 
#ifndef SQLITE_WINNT_MAX_PATH_BYTES
#  define SQLITE_WINNT_MAX_PATH_BYTES   \
                            (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS)
#endif

对Win32路径名长度规定,每个字符用4个字节表示,采用UTF8编码。

对WinNT路径名长度规定,用Wchar长度乘unicode最大char长度。

#if SQLITE_OS_WINCE
typedef struct winceLock {
    
    
  int nReaders;       /* Number of reader locks obtained */
  BOOL bPending;      /* Indicates a pending lock has been obtained */
  BOOL bReserved;     /* Indicates a reserved lock has been obtained */
  BOOL bExclusive;    /* Indicates an exclusive lock has been obtained */
} winceLock;
#endif

WINCE是一个操作界面源于Windows的嵌入式新型操作系统。

创建wincelock结构体,并指出三个布尔变量。

typedef struct winFile winFile;
struct winFile {
    
    
  const sqlite3_io_methods *pMethod; /*** Must be first ***/
  sqlite3_vfs *pVfs;      /* The VFS used to open this file */
  HANDLE h;               /* Handle for accessing the file */
  u8 locktype;            /* Type of lock currently held on this file */
  short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
  u8 ctrlFlags;           /* Flags.  See WINFILE_* below */
  DWORD lastErrno;        /* The Windows errno from the last I/O error */
#ifndef SQLITE_OMIT_WAL
  winShm *pShm;           /* Instance of shared memory on this file */
#endif
  const char *zPath;      /* Full pathname of this file */
  int szChunk;            /* Chunk size configured by FCNTL_CHUNK_SIZE */
#if SQLITE_OS_WINCE
  LPWSTR zDeleteOnClose;  /* Name of file to delete when closing */
  HANDLE hMutex;          /* Mutex used to control access to shared lock */
  HANDLE hShared;         /* Shared memory segment used for locking */
  winceLock local;        /* Locks obtained by this instance of winFile */
  winceLock *shared;      /* Global shared lock memory for the file  */
#endif
#if SQLITE_MAX_MMAP_SIZE>0
  int nFetchOut;                /* Number of outstanding xFetch references */
  HANDLE hMap;                  /* Handle for accessing memory mapping */
  void *pMapRegion;             /* Area memory mapped */
  sqlite3_int64 mmapSize;       /* Size of mapped region */
  sqlite3_int64 mmapSizeMax;    /* Configured FCNTL_MMAP_SIZE value */
#endif
};
 
 
typedef struct winVfsAppData winVfsAppData;
struct winVfsAppData {
    
    
  const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */
  void *pAppData;                    /* The extra pAppData, if any. */
  BOOL bNoLock;                      /* Non-zero if locking is disabled. */
};
 
 
 
 

创建了winFile结构体

注册时首先声明VFS接口函数,在tvfs_vfs结构体里

static sqlite3_vfs tvfs_vfs

在pAppData记录原来默认的VFS

pVfs->pAppData = (void *)p;//把信息存到pVfs->pAppData里

void *pAppData:该指针指向一个存储有各种文件io操作方法的结构体地址

Win下默认使用的是win32 vfsVFS首先要注册,使用sqlite3_vfs_register函数。

接下来是tcl命令参数。假设注册VFS时新建的命令是tvfs,使用格式为:tvfs shm FILE VALUE。

db eval {CREATE TABLE t1(a TEXT, b INTEGER)} #新建表

db eval {

   INSERT INTO t1 VALUES('one',1);

   INSERT INTO t1 VALUES('two',2); 

   INSERT INTO t1 VALUES(NULL,3);

}  #插入行

    puts [db eval {SELECT * FROM t1}] #显示表的所有行并输出结果

猜你喜欢

转载自blog.csdn.net/qq_53825872/article/details/120692579