⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pager.c

📁 sqlite database for embed linux
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Truncate the database back to its original size.  */  rc = pager_truncate(pPager, pPager->stmtSize);  assert( pPager->state>=PAGER_SHARED );  /* Figure out how many records are in the statement journal.  */  assert( pPager->stmtInUse && pPager->journalOpen );  sqlite3OsSeek(pPager->stfd, 0);  nRec = pPager->stmtNRec;    /* Copy original pages out of the statement journal and back into the  ** database file.  Note that the statement journal omits checksums from  ** each record since power-failure recovery is not important to statement  ** journals.  */  for(i=nRec-1; i>=0; i--){    rc = pager_playback_one_page(pPager, pPager->stfd, 0);    assert( rc!=SQLITE_DONE );    if( rc!=SQLITE_OK ) goto end_stmt_playback;  }  /* Now roll some pages back from the transaction journal. Pager.stmtJSize  ** was the size of the journal file when this statement was started, so  ** everything after that needs to be rolled back, either into the  ** database, the memory cache, or both.  **  ** If it is not zero, then Pager.stmtHdrOff is the offset to the start  ** of the first journal header written during this statement transaction.  */  rc = sqlite3OsSeek(pPager->jfd, pPager->stmtJSize);  if( rc!=SQLITE_OK ){    goto end_stmt_playback;  }  pPager->journalOff = pPager->stmtJSize;  pPager->cksumInit = pPager->stmtCksum;  while( pPager->journalOff < hdrOff ){    rc = pager_playback_one_page(pPager, pPager->jfd, 1);    assert( rc!=SQLITE_DONE );    if( rc!=SQLITE_OK ) goto end_stmt_playback;  }  while( pPager->journalOff < szJ ){    u32 nJRec;         /* Number of Journal Records */    u32 dummy;    rc = readJournalHdr(pPager, szJ, &nJRec, &dummy);    if( rc!=SQLITE_OK ){      assert( rc!=SQLITE_DONE );      goto end_stmt_playback;    }    if( nJRec==0 ){      nJRec = (szJ - pPager->journalOff) / (pPager->pageSize+8);    }    for(i=nJRec-1; i>=0 && pPager->journalOff < szJ; i--){      rc = pager_playback_one_page(pPager, pPager->jfd, 1);      assert( rc!=SQLITE_DONE );      if( rc!=SQLITE_OK ) goto end_stmt_playback;    }  }  pPager->journalOff = szJ;  end_stmt_playback:  if( rc==SQLITE_OK) {    pPager->journalOff = szJ;    /* pager_reload_cache(pPager); */  }  return rc;}/*** Change the maximum number of in-memory pages that are allowed.*/void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){  if( mxPage>10 ){    pPager->mxPage = mxPage;  }else{    pPager->mxPage = 10;  }}/*** Adjust the robustness of the database to damage due to OS crashes** or power failures by changing the number of syncs()s when writing** the rollback journal.  There are three levels:****    OFF       sqlite3OsSync() is never called.  This is the default**              for temporary and transient files.****    NORMAL    The journal is synced once before writes begin on the**              database.  This is normally adequate protection, but**              it is theoretically possible, though very unlikely,**              that an inopertune power failure could leave the journal**              in a state which would cause damage to the database**              when it is rolled back.****    FULL      The journal is synced twice before writes begin on the**              database (with some additional information - the nRec field**              of the journal header - being written in between the two**              syncs).  If we assume that writing a**              single disk sector is atomic, then this mode provides**              assurance that the journal will not be corrupted to the**              point of causing damage to the database during rollback.**** Numeric values associated with these states are OFF==1, NORMAL=2,** and FULL=3.*/#ifndef SQLITE_OMIT_PAGER_PRAGMASvoid sqlite3PagerSetSafetyLevel(Pager *pPager, int level, int full_fsync){  pPager->noSync =  level==1 || pPager->tempFile;  pPager->fullSync = level==3 && !pPager->tempFile;  pPager->full_fsync = full_fsync;  if( pPager->noSync ) pPager->needSync = 0;}#endif/*** The following global variable is incremented whenever the library** attempts to open a temporary file.  This information is used for** testing and analysis only.  */#ifdef SQLITE_TESTint sqlite3_opentemp_count = 0;#endif/*** Open a temporary file. **** Write the file descriptor into *fd.  Return SQLITE_OK on success or some** other error code if we fail.**** The OS will automatically delete the temporary file when it is** closed.*/static int sqlite3PagerOpentemp(OsFile **pFd){  int cnt = 8;  int rc;  char zFile[SQLITE_TEMPNAME_SIZE];#ifdef SQLITE_TEST  sqlite3_opentemp_count++;  /* Used for testing and analysis only */#endif  do{    cnt--;    sqlite3OsTempFileName(zFile);    rc = sqlite3OsOpenExclusive(zFile, pFd, 1);    assert( rc!=SQLITE_OK || *pFd );  }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );  return rc;}/*** Create a new page cache and put a pointer to the page cache in *ppPager.** The file to be cached need not exist.  The file is not locked until** the first call to sqlite3PagerGet() and is only held open until the** last page is released using sqlite3PagerUnref().**** If zFilename is NULL then a randomly-named temporary file is created** and used as the file to be cached.  The file will be deleted** automatically when it is closed.**** If zFilename is ":memory:" then all information is held in cache.** It is never written to disk.  This can be used to implement an** in-memory database.*/int sqlite3PagerOpen(  Pager **ppPager,         /* Return the Pager structure here */  const char *zFilename,   /* Name of the database file to open */  int nExtra,              /* Extra bytes append to each in-memory page */  int flags                /* flags controlling this file */){  Pager *pPager = 0;  char *zFullPathname = 0;  int nameLen;  /* Compiler is wrong. This is always initialized before use */  OsFile *fd = 0;  int rc = SQLITE_OK;  int i;  int tempFile = 0;  int memDb = 0;  int readOnly = 0;  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;  int noReadlock = (flags & PAGER_NO_READLOCK)!=0;  char zTemp[SQLITE_TEMPNAME_SIZE];#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT  /* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to   ** malloc() must have already been made by this thread before it gets  ** to this point. This means the ThreadData must have been allocated already  ** so that ThreadData.nAlloc can be set. It would be nice to assert  ** that ThreadData.nAlloc is non-zero, but alas this breaks test cases   ** written to invoke the pager directly.  */  ThreadData *pTsd = sqlite3ThreadData();  assert( pTsd );#endif  /* We used to test if malloc() had already failed before proceeding.   ** But the way this function is used in SQLite means that can never  ** happen. Furthermore, if the malloc-failed flag is already set,   ** either the call to sqliteStrDup() or sqliteMalloc() below will  ** fail shortly and SQLITE_NOMEM returned anyway.  */  *ppPager = 0;  /* Open the pager file and set zFullPathname to point at malloc()ed   ** memory containing the complete filename (i.e. including the directory).  */  if( zFilename && zFilename[0] ){#ifndef SQLITE_OMIT_MEMORYDB    if( strcmp(zFilename,":memory:")==0 ){      memDb = 1;      zFullPathname = sqliteStrDup("");    }else#endif    {      zFullPathname = sqlite3OsFullPathname(zFilename);      if( zFullPathname ){        rc = sqlite3OsOpenReadWrite(zFullPathname, &fd, &readOnly);        assert( rc!=SQLITE_OK || fd );      }    }  }else{    rc = sqlite3PagerOpentemp(&fd);    sqlite3OsTempFileName(zTemp);    zFilename = zTemp;    zFullPathname = sqlite3OsFullPathname(zFilename);    if( rc==SQLITE_OK ){      tempFile = 1;    }  }  /* Allocate the Pager structure. As part of the same allocation, allocate  ** space for the full paths of the file, directory and journal   ** (Pager.zFilename, Pager.zDirectory and Pager.zJournal).  */  if( zFullPathname ){    nameLen = strlen(zFullPathname);    pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );    if( pPager && rc==SQLITE_OK ){      pPager->pTmpSpace = (char *)sqliteMallocRaw(SQLITE_DEFAULT_PAGE_SIZE);    }  }  /* If an error occured in either of the blocks above, free the memory   ** pointed to by zFullPathname, free the Pager structure and close the   ** file. Since the pager is not allocated there is no need to set   ** any Pager.errMask variables.  */  if( !pPager || !zFullPathname || !pPager->pTmpSpace || rc!=SQLITE_OK ){    sqlite3OsClose(&fd);    sqliteFree(zFullPathname);    sqliteFree(pPager);    return ((rc==SQLITE_OK)?SQLITE_NOMEM:rc);  }  PAGERTRACE3("OPEN %d %s\n", FILEHANDLEID(fd), zFullPathname);  IOTRACE(("OPEN %p %s\n", pPager, zFullPathname))  pPager->zFilename = (char*)&pPager[1];  pPager->zDirectory = &pPager->zFilename[nameLen+1];  pPager->zJournal = &pPager->zDirectory[nameLen+1];  strcpy(pPager->zFilename, zFullPathname);  strcpy(pPager->zDirectory, zFullPathname);  for(i=nameLen; i>0 && pPager->zDirectory[i-1]!='/'; i--){}  if( i>0 ) pPager->zDirectory[i-1] = 0;  strcpy(pPager->zJournal, zFullPathname);  sqliteFree(zFullPathname);  strcpy(&pPager->zJournal[nameLen], "-journal");  pPager->fd = fd;  /* pPager->journalOpen = 0; */  pPager->useJournal = useJournal && !memDb;  pPager->noReadlock = noReadlock && readOnly;  /* pPager->stmtOpen = 0; */  /* pPager->stmtInUse = 0; */  /* pPager->nRef = 0; */  pPager->dbSize = memDb-1;  pPager->pageSize = SQLITE_DEFAULT_PAGE_SIZE;  /* pPager->stmtSize = 0; */  /* pPager->stmtJSize = 0; */  /* pPager->nPage = 0; */  /* pPager->nMaxPage = 0; */  pPager->mxPage = 100;  assert( PAGER_UNLOCK==0 );  /* pPager->state = PAGER_UNLOCK; */  /* pPager->errMask = 0; */  pPager->tempFile = tempFile;  assert( tempFile==PAGER_LOCKINGMODE_NORMAL           || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );  assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );  pPager->exclusiveMode = tempFile;   pPager->memDb = memDb;  pPager->readOnly = readOnly;  /* pPager->needSync = 0; */  pPager->noSync = pPager->tempFile || !useJournal;  pPager->fullSync = (pPager->noSync?0:1);  /* pPager->pFirst = 0; */  /* pPager->pFirstSynced = 0; */  /* pPager->pLast = 0; */  pPager->nExtra = FORCE_ALIGNMENT(nExtra);  assert(fd||memDb);  if( !memDb ){    pPager->sectorSize = sqlite3OsSectorSize(fd);  }  /* pPager->pBusyHandler = 0; */  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */  *ppPager = pPager;#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT  pPager->pNext = pTsd->pPager;  pTsd->pPager = pPager;#endif  return SQLITE_OK;}/*** Set the busy handler function.*/void sqlite3PagerSetBusyhandler(Pager *pPager, BusyHandler *pBusyHandler){  pPager->pBusyHandler = pBusyHandler;}/*** Set the destructor for this pager.  If not NULL, the destructor is called** when the reference count on each page reaches zero.  The destructor can** be used to clean up information in the extra segment appended to each page.**** The destructor is not called as a result sqlite3PagerClose().  ** Destructors are only called by sqlite3PagerUnref().*/void sqlite3PagerSetDestructor(Pager *pPager, void (*xDesc)(DbPage*,int)){  pPager->xDestructor = xDesc;}/*** Set the reinitializer for this pager.  If not NULL, the reinitializer** is called when the content of a page in cache is restored to its original** value as a result of a rollback.  The callback gives higher-level code** an opportunity to restore the EXTRA section to agree with the restored** page data.*/void sqlite3PagerSetReiniter(Pager *pPager, void (*xReinit)(DbPage*,int)){  pPager->xReiniter = xReinit;}/*** Set the page size.  Return the new size.  If the suggest new page** size is inappropriate, then an alternative page size is selected** and returned.*/int sqlite3PagerSetPagesize(Pager *pPager, int pageSize){  assert( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE );  if( !pPager->memDb && pPager->nRef==0 ){    pager_reset(pPager);    pPager->pageSize = pageSize;    pPager->pTmpSpace = sqlite3ReallocOrFree(pPager->pTmpSpace, pageSize);  }  return pPager->pageSize;}/*** The following set of routines are used to disable the simulated** I/O error mechanism.  These routines are used to avoid simulated** errors in places where we do not care abou

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -