Sqlite源码解读(十三)

2021SC@SDUSC

接着上次继续看文件操作。

删除命名文件

static int winDelete(

  sqlite3_vfs *pVfs,          /*未用于win32 */

  const char *zFilename,      /* 要删除的文件名*/

  int syncDir                 /* 未用于 win32 */

){

  int cnt = 0;

  int rc;

  DWORD attr;

  DWORD lastErrno = 0;

  void *zConverted;

  UNUSED_PARAMETER(pVfs);

  UNUSED_PARAMETER(syncDir);

  SimulateIOError(return SQLITE_IOERR_DELETE);

  OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));

  zConverted = winConvertFromUtf8Filename(zFilename);

  if( zConverted==0 ){

    OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));

    return SQLITE_IOERR_NOMEM_BKPT;

  }

  if( osIsNT() ){

    do {

#if SQLITE_OS_WINRT

      WIN32_FILE_ATTRIBUTE_DATA sAttrData;

      memset(&sAttrData, 0, sizeof(sAttrData));

      if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,

                                  &sAttrData) ){

        attr = sAttrData.dwFileAttributes;

      }else{

        lastErrno = osGetLastError();

        if( lastErrno==ERROR_FILE_NOT_FOUND

         || lastErrno==ERROR_PATH_NOT_FOUND ){

          rc = SQLITE_IOERR_DELETE_NOENT;

        }else{

          rc = SQLITE_ERROR;

        }

        break;

      }

#else

      attr = osGetFileAttributesW(zConverted);

#endif

      if ( attr==INVALID_FILE_ATTRIBUTES ){

        lastErrno = osGetLastError();

        if( lastErrno==ERROR_FILE_NOT_FOUND

         || lastErrno==ERROR_PATH_NOT_FOUND ){

          rc = SQLITE_IOERR_DELETE_NOENT;

        }else{

          rc = SQLITE_ERROR;

        }

        break;

      }

      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){

        rc = SQLITE_ERROR;   /*只提供文件*/

        break;

      }

      if ( osDeleteFileW(zConverted) ){

        rc = SQLITE_OK;   /* 删除完成*/

        break;

      }

      if ( !winRetryIoerr(&cnt, &lastErrno) ){

        rc = SQLITE_ERROR;   /* 不再重试*/

        break;

      }

    } while(1);

  }

#ifdef SQLITE_WIN32_HAS_ANSI

  else{

    do {

      attr = osGetFileAttributesA(zConverted);

      if ( attr==INVALID_FILE_ATTRIBUTES ){

        lastErrno = osGetLastError();

        if( lastErrno==ERROR_FILE_NOT_FOUND

         || lastErrno==ERROR_PATH_NOT_FOUND ){

          rc = SQLITE_IOERR_DELETE_NOENT;

        }else{

          rc = SQLITE_ERROR;

        }

        break;

      }

      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){

        rc = SQLITE_ERROR;

        break;

      }

      if ( osDeleteFileA(zConverted) ){

        rc = SQLITE_OK;   /* 删除完成 */

        break;

      }

      if ( !winRetryIoerr(&cnt, &lastErrno) ){

        rc = SQLITE_ERROR;   /*不再重试 */

        break;

      }

    } while(1);

  }

#endif

  if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){

    rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);

  }else{

    winLogIoerr(cnt, __LINE__);

  }

  sqlite3_free(zConverted);

  OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));

  return rc;

}

检查文件的存在和状态

static int winAccess(

  sqlite3_vfs *pVfs,         /*未用于 win32 */

  const char *zFilename,     /* 要检查的文件名 */

  int flags,                 /* 要对这个文件进行测试的类型 */

  int *pResOut               /* 退出:结果 */

){

  DWORD attr;

  int rc = 0;

  DWORD lastErrno = 0;

  void *zConverted;

  UNUSED_PARAMETER(pVfs);

  SimulateIOError( return SQLITE_IOERR_ACCESS; );

  OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",

           zFilename, flags, pResOut));

  zConverted = winConvertFromUtf8Filename(zFilename);

  if( zConverted==0 ){

    OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));

    return SQLITE_IOERR_NOMEM_BKPT;

  }

  if( osIsNT() ){

    int cnt = 0;

    WIN32_FILE_ATTRIBUTE_DATA sAttrData;

    memset(&sAttrData, 0, sizeof(sAttrData));

    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,

                             GetFileExInfoStandard,

                             &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}

    if( rc ){

      /* 对于 SQLITE_ACCESS_EXISTS 查询, 将零长度文件视为不存在*/

      if(    flags==SQLITE_ACCESS_EXISTS

          && sAttrData.nFileSizeHigh==0

          && sAttrData.nFileSizeLow==0 ){

        attr = INVALID_FILE_ATTRIBUTES;

      }else{

        attr = sAttrData.dwFileAttributes;

      }

    }else{

      winLogIoerr(cnt, __LINE__);

      if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){

        sqlite3_free(zConverted);

        return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",

                           zFilename);

      }else{

        attr = INVALID_FILE_ATTRIBUTES;

      }

    }

  }

#ifdef SQLITE_WIN32_HAS_ANSI

  else{

    attr = osGetFileAttributesA((char*)zConverted);

  }

#endif

  sqlite3_free(zConverted);

  switch( flags ){

    case SQLITE_ACCESS_READ:

    case SQLITE_ACCESS_EXISTS:

      rc = attr!=INVALID_FILE_ATTRIBUTES;

      break;

    case SQLITE_ACCESS_READWRITE:

      rc = attr!=INVALID_FILE_ATTRIBUTES &&

             (attr & FILE_ATTRIBUTE_READONLY)==0;

      break;

    default:

      assert(!"Invalid flags argument");

  }

  *pResOut = rc;

  OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",

           zFilename, pResOut, *pResOut));

  return SQLITE_OK;

}

如果指定的路径以“长路径”前缀开头,则返回非零。

static BOOL winIsLongPathPrefix(

  const char *zPathname

){

  return ( zPathname[0]=='\\' && zPathname[1]=='\\'

        && zPathname[2]=='?'  && zPathname[3]=='\\' );

}

如果指定的路径名以驱动器号开头,则返回非零值,后面跟着冒号字符。

static BOOL winIsDriveLetterAndColon(

  const char *zPathname

){

  return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );

}

如果指定的路径名称应逐字使用,则返回非零。如果该函数返回非零,则调用函数必须逐字使用提供的路径名-或-使用GetFullPathName Win 32 API函数(如果可用)将其解析为完整路径名。

static BOOL winIsVerbatimPathname(

  const char *zPathname

){

/*如果路径名以正斜杠、反斜杠、字母或冒号开头,则返回true*/

if ( winIsDirSep(zPathname[0]) ){

    return TRUE;

  }

if ( winIsDriveLetterAndColon(zPathname) ){

    return TRUE;

  }

将相对路径名转换为完整路径名。将完整的路径名写入Zout[]。Zout[]的大小至少为pVfs->mxPathname字节

static int winFullPathname(

  sqlite3_vfs *pVfs,            /*指向VFS对象的指针 */

  const char *zRelative,        /*可能是相对输入路径*/

  int nFull,                    /* 输出缓冲区的大小(以字节为单位) */

  char *zFull                   /*输出缓冲区 */

){

#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)

  DWORD nByte;

  void *zConverted;

  char *zOut;

#endif

用于打开共享库、在共享库中查找入口点和关闭共享库的接口。

static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){

  HANDLE h;

#if defined(__CYGWIN__)

  int nFull = pVfs->mxPathname+1;

  char *zFull = sqlite3MallocZero( nFull );

  void *zConverted = 0;

  if( zFull==0 ){

    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));

    return 0;

  }

  if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){

    sqlite3_free(zFull);

    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));

    return 0;

  }

  zConverted = winConvertFromUtf8Filename(zFull);

  sqlite3_free(zFull);

#else

  void *zConverted = winConvertFromUtf8Filename(zFilename);

  UNUSED_PARAMETER(pVfs);

#endif

随机采集者的状态信息。

typedef struct EntropyGatherer EntropyGatherer;

struct EntropyGatherer {

  unsigned char *a;   /*将熵聚集到这个缓冲区中*/

  int na;            /*a[]的大小(以字节为单位)*/

  int i;            /*XOR下一个输入到[i]*/

  int nXor;         /*已完成的异或操作数目*/};

#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)

/*将熵的z字节混合到p.*/

static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){

  int j, k;

  for(j=0, k=p->i; j<sz; j++){

    p->a[k++] ^= x[j];

    if( k>=p->na ) k = 0;

  }

  p->i = k;

  p->nXor += sz;

}

#endif

将随机的nBuf字节写入zBuf。

static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){

#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)

  UNUSED_PARAMETER(pVfs);

  memset(zBuf, 0, nBuf);

  return nBuf;

#else

  EntropyGatherer e;

  UNUSED_PARAMETER(pVfs);

  memset(zBuf, 0, nBuf);

  e.a = (unsigned char*)zBuf;

  e.na = nBuf;

  e.nXor = 0;

  e.i = 0;

  {

    SYSTEMTIME x;

    osGetSystemTime(&x);

    xorMemory(&e, (unsigned char*)&x, sizeof(SYSTEMTIME));

  }

  {

    DWORD pid = osGetCurrentProcessId();

    xorMemory(&e, (unsigned char*)&pid, sizeof(DWORD));

  }

}

睡眠一会儿,返回睡眠的时间。

static int winSleep(sqlite3_vfs *pVfs, int microsec){

  sqlite3_win32_sleep((microsec+999)/1000);

  UNUSED_PARAMETER(pVfs);

  return ((microsec+999)/1000)*1000;

}

以下变量(如果设置为非零值)被解释为自1970年以来的秒数,并用于在测试期间设置sqlite3OsCurrentTime()的结果。

#ifdef SQLITE_TEST

int sqlite3_current_time = 0;     /*自1970年以来,以秒为单位伪造系统时间。*/

#endif

查找当前时间(通用协调时间)。将当前时间和日期作为朱利安日号写入*prNow并返回0。如果找不到时间和日期,请返回1。

static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){

  int rc;

  sqlite3_int64 i;

  rc = winCurrentTimeInt64(pVfs, &i);

  if( !rc ){

    *prNow = i/86400000.0;

  }

  return rc;

}

猜你喜欢

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