示例#1
0
/*
** Usage:   page_number PAGE
**
** Return the page number for a page.
*/
static int page_number(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  char zBuf[100];
  DbPage *pPage;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " PAGE\"", 0);
    return TCL_ERROR;
  }
  pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", sqlite3PagerPagenumber(pPage));
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}
/*
** Usage:   btree_pager_stats ID
**
** Returns pager statistics
*/
static int btree_pager_stats(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int i;
  int *a;

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
 
  /* Normally in this file, with a b-tree handle opened using the 
  ** [btree_open] command it is safe to call sqlite3BtreeEnter() directly.
  ** But this function is sometimes called with a btree handle obtained
  ** from an open SQLite connection (using [btree_from_db]). In this case
  ** we need to obtain the mutex for the controlling SQLite handle before
  ** it is safe to call sqlite3BtreeEnter().
  */
  sqlite3_mutex_enter(pBt->db->mutex);

  sqlite3BtreeEnter(pBt);
  a = sqlite3PagerStats(sqlite3BtreePager(pBt));
  for(i=0; i<11; i++){
    static char *zName[] = {
      "ref", "page", "max", "size", "state", "err",
      "hit", "miss", "ovfl", "read", "write"
    };
    char zBuf[100];
    Tcl_AppendElement(interp, zName[i]);
    sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",a[i]);
    Tcl_AppendElement(interp, zBuf);
  }
  sqlite3BtreeLeave(pBt);

  /* Release the mutex on the SQLite handle that controls this b-tree */
  sqlite3_mutex_leave(pBt->db->mutex);
  return TCL_OK;
}
示例#3
0
/*
** Argument zPath points to a nul-terminated string containing a file path.
** If zPath is an absolute path, then it is copied as is into the output 
** buffer. Otherwise, if it is a relative path, then the equivalent full
** path is written to the output buffer.
**
** This function assumes that paths are UNIX style. Specifically, that:
**
**   1. Path components are separated by a '/'. and 
**   2. Full paths begin with a '/' character.
*/
static int demoFullPathname(
  sqlite3_vfs *pVfs,              /* VFS */
  const char *zPath,              /* Input path (possibly a relative path) */
  int nPathOut,                   /* Size of output buffer in bytes */
  char *zPathOut                  /* Pointer to output buffer */
){
  char zDir[MAXPATHNAME+1];
  if( zPath[0]=='/' ){
    zDir[0] = '\0';
  }else{
    getcwd(zDir, sizeof(zDir));
  }
  zDir[MAXPATHNAME] = '\0';

  sqlite3_snprintf(nPathOut, zPathOut, "%s/%s", zDir, zPath);
  zPathOut[nPathOut-1] = '\0';

  return SQLITE_OK;
}
示例#4
0
文件: test3.c 项目: AlvarHHM/sqlite
/*
** Usage:   btree_cursor ID TABLENUM WRITEABLE
**
** Create a new cursor.  Return the ID for the cursor.
*/
static int btree_cursor(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int iTable;
  BtCursor *pCur;
  int rc = SQLITE_OK;
  int wrFlag;
  char zBuf[30];

  if( argc!=4 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID TABLENUM WRITEABLE\"", 0);
    return TCL_ERROR;
  }
  pBt = sqlite3TestTextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
  if( Tcl_GetBoolean(interp, argv[3], &wrFlag) ) return TCL_ERROR;
  if( wrFlag ) wrFlag = BTREE_WRCSR;
  pCur = (BtCursor *)ckalloc(sqlite3BtreeCursorSize());
  memset(pCur, 0, sqlite3BtreeCursorSize());
  sqlite3_mutex_enter(pBt->db->mutex);
  sqlite3BtreeEnter(pBt);
#ifndef SQLITE_OMIT_SHARED_CACHE
  rc = sqlite3BtreeLockTable(pBt, iTable, !!wrFlag);
#endif
  if( rc==SQLITE_OK ){
    rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, pCur);
  }
  sqlite3BtreeLeave(pBt);
  sqlite3_mutex_leave(pBt->db->mutex);
  if( rc ){
    ckfree((char *)pCur);
    Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
    return TCL_ERROR;
  }
  sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pCur);
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}
示例#5
0
/*
** Print an error message
*/
static void errorMessage(const char *zFormat, ...){
  va_list ap;
  char *zMsg;
  char zPrefix[30];
  va_start(ap, zFormat);
  zMsg = sqlite3_vmprintf(zFormat, ap);
  va_end(ap);
  sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:ERROR: ", g.zName);
  if( g.pLog ){
    printWithPrefix(g.pLog, zPrefix, zMsg);
    fflush(g.pLog);
  }
  if( g.pErrLog && safe_strcmp(g.zErrLog,g.zLog) ){
    printWithPrefix(g.pErrLog, zPrefix, zMsg);
    fflush(g.pErrLog);
  }
  sqlite3_free(zMsg);
  g.nError++;
}
示例#6
0
static int
set_repo_user_version(sqlite3 *sqlite, const char *database, int reposcver)
{
    int		 retcode = EPKG_OK;
    char		 sql[BUFSIZ];
    char		*errmsg;
    const char	*fmt = "PRAGMA %Q.user_version = %d;" ;

    assert(database != NULL);

    sqlite3_snprintf(sizeof(sql), sql, fmt, database, reposcver);

    if (sqlite3_exec(sqlite, sql, NULL, NULL, &errmsg) != SQLITE_OK) {
        pkg_emit_error("sqlite: %s", errmsg);
        sqlite3_free(errmsg);
        retcode = EPKG_FATAL;
    }
    return (retcode);
}
示例#7
0
static int btreeSeqOpen(
    sqlite3_context *context, Btree *p, SEQ_COOKIE *cookie)
{
	BtShared *pBt;
	DBT key;
	DB_SEQUENCE *seq;
	char seq_key[BT_MAX_SEQ_NAME];
	int ret, seq_len;
	u_int32_t flags;

	pBt = p->pBt;

	if ((ret = btreeSeqGetCookie(context, p, cookie, 0)) != 0)
		return (ret);

	if (cookie->cache != 0) {
		if ((ret = db_sequence_create(&seq, pBt->metadb, 0)) != 0)
			return ret;

		seq->set_cachesize(seq, cookie->cache);
		flags = 0;
#ifdef BDBSQL_SINGLE_THREAD
		flags |= DB_THREAD;
#endif
		sqlite3_snprintf(
		    BT_MAX_SEQ_NAME, seq_key, "%s_db", cookie->name);
		seq_len = (int)strlen(seq_key);
		memset(&key, 0, sizeof(key));
		key.data = seq_key;
		key.size = key.ulen = seq_len;
		key.flags = DB_DBT_USERMEM;

		if ((ret = seq->open(
		    seq, NULL, &key, flags)) != 0) {
			(void)seq->close(seq, 0);
			return ret;
		}
		cookie->handle = seq;
	}

	return (0);
}
示例#8
0
文件: doc.c 项目: digsrc/fossil
/*
** Guess the mime-type of a document based on its name.
*/
const char *mimetype_from_name(const char *zName){
  const char *z;
  int i;
  int first, last;
  int len;
  char zSuffix[20];


#ifdef FOSSIL_DEBUG
  /* This is test code to make sure the table above is in the correct
  ** order
  */
  if( fossil_strcmp(zName, "mimetype-test")==0 ){
    mimetype_verify();
    return "ok";
  }
#endif

  z = zName;
  for(i=0; zName[i]; i++){
    if( zName[i]=='.' ) z = &zName[i+1];
  }
  len = strlen(z);
  if( len<sizeof(zSuffix)-1 ){
    sqlite3_snprintf(sizeof(zSuffix), zSuffix, "%s", z);
    for(i=0; zSuffix[i]; i++) zSuffix[i] = fossil_tolower(zSuffix[i]);
    first = 0;
    last = ArraySize(aMime) - 1;
    while( first<=last ){
      int c;
      i = (first+last)/2;
      c = fossil_strcmp(zSuffix, aMime[i].zSuffix);
      if( c==0 ) return aMime[i].zMimetype;
      if( c<0 ){
        last = i-1;
      }else{
        first = i+1;
      }
    }
  }
  return "application/x-fossil-artifact";
}
示例#9
0
文件: backup.c 项目: galaxyeye/bdb
static int btreeCleanupEnv(const char *home)
{
	DB_ENV *tmp_env;
	int count, i, ret;
	char **names, buf[512];

	log_msg(LOG_DEBUG, "btreeCleanupEnv removing existing env.");
	/*
	 * If there is a directory (environment), but no
	 * database file. Clear the environment to avoid
	 * carrying over information from earlier sessions.
	 */
	if ((ret = db_env_create(&tmp_env, 0)) != 0)
		return ret;

	/* Remove log files */
	if ((ret = __os_dirlist(tmp_env->env, home, 0, &names, &count)) != 0) {
		(void)tmp_env->close(tmp_env, 0);
		return ret;
	}

	for (i = 0; i < count; i++) {
		if (strncmp(names[i], "log.", 4) != 0)
			continue;
		sqlite3_snprintf(sizeof(buf), buf, "%s%s%s",
		    home, "/", names[i]);
		/*
		 * Use Berkeley DB __os_unlink (not sqlite3OsDelete) since
		 * this file has always been managed by Berkeley DB.
		 */
		(void)__os_unlink(NULL, buf, 0);
	}

	__os_dirfree(tmp_env->env, names, count);

	/*
	 * TODO: Do we want force here? Ideally all handles
	 * would always be closed on exit, so DB_FORCE would
	 * not be necessary.  The world is not currently ideal.
	 */
	return tmp_env->remove(tmp_env, home, DB_FORCE);
}
示例#10
0
/*
** Shared-memory operations.
*/
static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
  vfstrace_file *p = (vfstrace_file *)pFile;
  vfstrace_info *pInfo = p->pInfo;
  int rc;
  char zLck[100];
  int i = 0;
  memcpy(zLck, "|0", 3);
  if( flags & SQLITE_SHM_UNLOCK )    strappend(zLck, &i, "|UNLOCK");
  if( flags & SQLITE_SHM_LOCK )      strappend(zLck, &i, "|LOCK");
  if( flags & SQLITE_SHM_SHARED )    strappend(zLck, &i, "|SHARED");
  if( flags & SQLITE_SHM_EXCLUSIVE ) strappend(zLck, &i, "|EXCLUSIVE");
  if( flags & ~(0xf) ){
     sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags);
  }
  vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d,n=%d,%s)",
                  pInfo->zVfsName, p->zFName, ofst, n, &zLck[1]);
  rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
  vfstrace_print_errcode(pInfo, " -> %s\n", rc);
  return rc;
}
示例#11
0
/*
** Sync an vfstrace-file.
*/
static int vfstraceSync(sqlite3_file *pFile, int flags){
  vfstrace_file *p = (vfstrace_file *)pFile;
  vfstrace_info *pInfo = p->pInfo;
  int rc;
  int i;
  char zBuf[100];
  memcpy(zBuf, "|0", 3);
  i = 0;
  if( flags & SQLITE_SYNC_FULL )        strappend(zBuf, &i, "|FULL");
  else if( flags & SQLITE_SYNC_NORMAL ) strappend(zBuf, &i, "|NORMAL");
  if( flags & SQLITE_SYNC_DATAONLY )    strappend(zBuf, &i, "|DATAONLY");
  if( flags & ~(SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY) ){
    sqlite3_snprintf(sizeof(zBuf)-i, &zBuf[i], "|0x%x", flags);
  }
  vfstrace_printf(pInfo, "%s.xSync(%s,%s)", pInfo->zVfsName, p->zFName,
                  &zBuf[1]);
  rc = p->pReal->pMethods->xSync(p->pReal, flags);
  vfstrace_printf(pInfo, " -> %d\n", rc);
  return rc;
}
示例#12
0
static int pager_pagecount(
  void *NotUsed,
  Tcl_Interp *interp,    
  int argc,              
  const char **argv      
){
  Pager *pPager;
  char zBuf[100];
  int nPage;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pPager = sqlite3TestTextToPtr(argv[1]);
  sqlite3PagerPagecount(pPager, &nPage);
  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nPage);
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}
示例#13
0
/*
** Usage:   pager_pagecount ID
**
** Return the size of the database file.
*/
static int SQLITE_TCLAPI pager_pagecount(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Pager *pPager;
  char zBuf[100];
  int nPage;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pPager = sqlite3TestTextToPtr(argv[1]);
  sqlite3PagerPagecount(pPager, &nPage);
  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nPage);
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}
示例#14
0
文件: rstats.c 项目: 3615pipou/coopy
/*
** COMMAND: rstats
**
** Usage: %fossil rstats
**
** Deliver a report of the repository statistics for the
** current checkout.
*/
void rstats_cmd(void){
  i64 t;
  int n, m, fsize, vid;
  char zBuf[100];

  db_must_be_within_tree();
  vid = db_lget_int("checkout",0);
  if( vid==0 ){
    fossil_panic("no checkout");
  }
  fsize = file_size(g.zRepositoryName);
  n = db_int(0, "SELECT count(*) FROM blob");
  m = db_int(0, "SELECT count(*) FROM delta");
  printf(" Number of Artifacts: %d\n", n);
  printf("  %d full text + %d delta blobs\n", (n-m), m);
  if( n>0 ){
    int a, b;
    t = db_int64(0, "SELECT total(size) FROM blob WHERE size>0");
    sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", t);
    if( t/fsize < 5 ){
      b = 10;
      fsize /= 10;
    }else{
      b = 1;
    }
    a = t/fsize;
    printf(" %d bytes average, %s bytes total\n\n",
	   ((int)(((double)t)/(double)n)),
	   (zBuf));
  }
  n = db_int(0, "SELECT count(distinct mid) FROM mlink");
  printf("  Number Of Checkins: %d\n", n);
  n = db_int(0, "SELECT count(*) FROM filename");
  printf("     Number Of Files: %d\n", n);
  n = db_int(0, "SELECT count(*) FROM tag WHERE +tagname GLOB 'wiki-*'");
  printf("Number Of Wiki Pages: %d\n", n);
  n = db_int(0, "SELECT count(*) FROM tag WHERE +tagname GLOB 'tkt-*'");
  printf("   Number Of Tickets: %d\n", n);
  n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event) + 0.99");
  printf(" Duration Of Project: %d days\n", n);
}
示例#15
0
/*
** Usage:   btree_open FILENAME NCACHE
**
** Open a new database
*/
static int btree_open(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Btree *pBt;
  int rc, nCache;
  char zBuf[100];
  int n;
  char *zFilename;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME NCACHE FLAGS\"", 0);
    return TCL_ERROR;
  }
  if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR;
  nRefSqlite3++;
  if( nRefSqlite3==1 ){
    sDb.pVfs = sqlite3_vfs_find(0);
    sDb.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
    sqlite3_mutex_enter(sDb.mutex);
  }
  n = (int)strlen(argv[1]);
  zFilename = sqlite3_malloc( n+2 );
  if( zFilename==0 ) return TCL_ERROR;
  memcpy(zFilename, argv[1], n+1);
  zFilename[n+1] = 0;
  rc = sqlite3BtreeOpen(sDb.pVfs, zFilename, &sDb, &pBt, 0, 
     SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB);
  sqlite3_free(zFilename);
  if( rc!=SQLITE_OK ){
    Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
    return TCL_ERROR;
  }
  sqlite3BtreeSetCacheSize(pBt, nCache);
  sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pBt);
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}
示例#16
0
/*
** Compute an aggregate MD5 checksum over the repository image of every
** file in manifest vid.  The file names are part of the checksum.  The
** resulting checksum is suitable for use as the R-card of a manifest.
**
** Return the resulting checksum in blob pOut.
**
** If pManOut is not NULL then fill it with the checksum found in the
** "R" card near the end of the manifest.
**
** In a well-formed manifest, the two checksums computed here, pOut and
** pManOut, should be identical.  
*/
void vfile_aggregate_checksum_manifest(int vid, Blob *pOut, Blob *pManOut){
  int fid;
  Blob file;
  Blob err;
  Manifest *pManifest;
  ManifestFile *pFile;
  char zBuf[100];

  blob_zero(pOut);
  blob_zero(&err);
  if( pManOut ){
    blob_zero(pManOut);
  }
  db_must_be_within_tree();
  pManifest = manifest_get(vid, CFTYPE_MANIFEST, &err);
  if( pManifest==0 ){
    fossil_fatal("manifest file (%d) is malformed:\n%s\n",
                 vid, blob_str(&err));
  }
  manifest_file_rewind(pManifest);
  while( (pFile = manifest_file_next(pManifest,0))!=0 ){
    if( pFile->zUuid==0 ) continue;
    fid = uuid_to_rid(pFile->zUuid, 0);
    md5sum_step_text(pFile->zName, -1);
    content_get(fid, &file);
    sqlite3_snprintf(sizeof(zBuf), zBuf, " %d\n", blob_size(&file));
    md5sum_step_text(zBuf, -1);
    md5sum_step_blob(&file);
    blob_reset(&file);
  }
  if( pManOut ){
    if( pManifest->zRepoCksum ){
      blob_append(pManOut, pManifest->zRepoCksum, -1);
    }else{
      blob_zero(pManOut);
    }
  }
  manifest_destroy(pManifest);
  md5sum_finish(pOut);
}
示例#17
0
std::string DatabaseSQLite::escapeString(const std::string &s)
{
	// remember about quoiting even an empty string!
	if(!s.size())
		return std::string("''");

	// the worst case is 2n + 3
	char* output = new char[s.length() * 2 + 3];
	// quotes escaped string and frees temporary buffer
	sqlite3_snprintf(s.length() * 2 + 1, output, "%Q", s.c_str());

	std::string r(output);
	delete[] output;

	//escape % and _ because we are using LIKE operator.
	r = boost::regex_replace(r, boost::regex("%"), "\\%");
	r = boost::regex_replace(r, boost::regex("_"), "\\_");
	if(r[r.length() - 1] != '\'')
		r += "'";

	return r;
}
示例#18
0
/*
** Usage:   btree_move_to ID KEY
**
** Move the cursor to the entry with the given key.
*/
static int btree_move_to(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int rc;
  int res;
  char zBuf[20];

  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID KEY\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pCur->pBtree);
  if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){
    int iKey;
    if( Tcl_GetInt(interp, argv[2], &iKey) ){
      sqlite3BtreeLeave(pCur->pBtree);
      return TCL_ERROR;
    }
    rc = sqlite3BtreeMovetoUnpacked(pCur, 0, iKey, 0, &res);
  }else{
    rc = sqlite3BtreeMoveto(pCur, argv[2], strlen(argv[2]), 0, &res);  
  }
  sqlite3BtreeLeave(pCur->pBtree);
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  if( res<0 ) res = -1;
  if( res>0 ) res = 1;
  sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",res);
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}
示例#19
0
/*
** Run arbitrary SQL and record the results in an output string
** given by the first parameter.
*/
static int evalSql(String *p, const char *zFormat, ...){
  va_list ap;
  char *zSql;
  int rc;
  char *zErrMsg = 0;
  va_start(ap, zFormat);
  zSql = sqlite3_vmprintf(zFormat, ap);
  va_end(ap);
  assert( g.iTimeout>0 );
  rc = sqlite3_exec(g.db, zSql, evalCallback, p, &zErrMsg);
  sqlite3_free(zSql);
  if( rc ){
    char zErr[30];
    sqlite3_snprintf(sizeof(zErr), zErr, "error(%d)", rc);
    stringAppendTerm(p, zErr);
    if( zErrMsg ){
      stringAppendTerm(p, zErrMsg);
      sqlite3_free(zErrMsg);
    }
  }
  return rc;
}
示例#20
0
int
seafile_session_config_set_string (SeafileSession *session,
                                   const char *key,
                                   const char *value)
{
    char sql[256];

    sqlite3_snprintf (sizeof(sql), sql,
                      "REPLACE INTO Config VALUES ('%q', '%q');",
                      key, value);
    if (sqlite_query_exec (session->config_db, sql) < 0)
        return -1;

    if (g_strcmp0(key, KEY_SYNC_EXTRA_TEMP_FILE) == 0) {
        if (g_strcmp0(value, "true") == 0)
            session->sync_extra_temp_file = TRUE;
        else
            session->sync_extra_temp_file = FALSE;
    }

    return 0;
}
示例#21
0
/*
** Usage:   btree_eof ID
**
** Return TRUE if the given cursor is not pointing at a valid entry.
** Return FALSE if the cursor does point to a valid entry.
*/
static int btree_eof(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int rc;
  char zBuf[50];

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID\"", 0);
    return TCL_ERROR;
  }
  pCur = sqlite3TestTextToPtr(argv[1]);
  sqlite3BtreeEnter(pCur->pBtree);
  rc = sqlite3BtreeEof(pCur);
  sqlite3BtreeLeave(pCur->pBtree);
  sqlite3_snprintf(sizeof(zBuf),zBuf, "%d", rc);
  Tcl_AppendResult(interp, zBuf, 0);
  return SQLITE_OK;
}
示例#22
0
/*
** Add a single file to the growing tarball.
*/
static void tar_add_file(
  const char *zName,               /* Name of the file.  nul-terminated */
  Blob *pContent,                  /* Content of the file */
  int mPerm,                       /* 1: executable file, 2: symlink */
  unsigned int mTime               /* Last modification time of the file */
){
  int nName = strlen(zName);
  int n = blob_size(pContent);
  int lastPage;
  char cType = '0';

  /* length check moved to tar_split_path */
  tar_add_directory_of(zName, nName, mTime);

  /* 
   * If we have a symlink, write its destination path (which is stored in
   * pContent) into header, and set content length to 0 to avoid storing path
   * as file content in the next step.  Since 'linkname' header is limited to
   * 100 bytes (-1 byte for terminating zero), if path is greater than that,
   * store symlink as a plain-text file. (Not sure how TAR handles long links.)
   */
  if( mPerm == PERM_LNK && n <= 100 ){
    sqlite3_snprintf(100, (char*)&tball.aHdr[157], "%s", blob_str(pContent));
    cType = '2';
    n = 0;
  }

  tar_add_header(zName, nName, ( mPerm==PERM_EXE ) ? 0755 : 0644, 
                 mTime, n, cType);
  if( n ){
    gzip_step(blob_buffer(pContent), n);
    lastPage = n % 512;
    if( lastPage!=0 ){
      gzip_step(tball.zSpaces, 512 - lastPage);
    }
  }
}
示例#23
0
static int page_lookup(
  void *NotUsed,
  Tcl_Interp *interp,    
  int argc,              
  const char **argv      
){
  Pager *pPager;
  char zBuf[100];
  DbPage *pPage;
  int pgno;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID PGNO\"", 0);
    return TCL_ERROR;
  }
  pPager = sqlite3TestTextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
  pPage = sqlite3PagerLookup(pPager, pgno);
  if( pPage ){
    sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
    Tcl_AppendResult(interp, zBuf, 0);
  }
  return TCL_OK;
}
示例#24
0
文件: test2.c 项目: Av3ng3/Lamobo-D1s
/*
** Usage:   page_lookup ID PGNO
**
** Return a pointer to a page if the page is already in cache.
** If not in cache, return an empty string.
*/
static int page_lookup(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  Pager *pPager;
  char zBuf[100];
  DbPage *pPage;
  int pgno;
  if( argc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID PGNO\"", 0);
    return TCL_ERROR;
  }
  pPager = sqlite3TestTextToPtr(argv[1]);
  if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
  pPage = sqlite3PagerLookup(pPager, pgno);
  if( pPage ){
    sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
    Tcl_AppendResult(interp, zBuf, 0);
  }
  return TCL_OK;
}
示例#25
0
文件: date.c 项目: 1018824313/sqlite
/*
**    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
**
** Return a string described by FORMAT.  Conversions as follows:
**
**   %d  day of month
**   %f  ** fractional seconds  SS.SSS
**   %H  hour 00-24
**   %j  day of year 000-366
**   %J  ** julian day number
**   %m  month 01-12
**   %M  minute 00-59
**   %s  seconds since 1970-01-01
**   %S  seconds 00-59
**   %w  day of week 0-6  sunday==0
**   %W  week of year 00-53
**   %Y  year 0000-9999
**   %%  %
*/
static void strftimeFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  DateTime x;
  u64 n;
  size_t i,j;
  char *z;
  sqlite3 *db;
  const char *zFmt;
  char zBuf[100];
  if( argc==0 ) return;
  zFmt = (const char*)sqlite3_value_text(argv[0]);
  if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
  db = sqlite3_context_db_handle(context);
  for(i=0, n=1; zFmt[i]; i++, n++){
    if( zFmt[i]=='%' ){
      switch( zFmt[i+1] ){
        case 'd':
        case 'H':
        case 'm':
        case 'M':
        case 'S':
        case 'W':
          n++;
          /* fall thru */
        case 'w':
        case '%':
          break;
        case 'f':
          n += 8;
          break;
        case 'j':
          n += 3;
          break;
        case 'Y':
          n += 8;
          break;
        case 's':
        case 'J':
          n += 50;
          break;
        default:
          return;  /* ERROR.  return a NULL */
      }
      i++;
    }
  }
  testcase( n==sizeof(zBuf)-1 );
  testcase( n==sizeof(zBuf) );
  testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
  testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] );
  if( n<sizeof(zBuf) ){
    z = zBuf;
  }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){
    sqlite3_result_error_toobig(context);
    return;
  }else{
    z = sqlite3DbMallocRawNN(db, (int)n);
    if( z==0 ){
      sqlite3_result_error_nomem(context);
      return;
    }
  }
  computeJD(&x);
  computeYMD_HMS(&x);
  for(i=j=0; zFmt[i]; i++){
    if( zFmt[i]!='%' ){
      z[j++] = zFmt[i];
    }else{
      i++;
      switch( zFmt[i] ){
        case 'd':  sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break;
        case 'f': {
          double s = x.s;
          if( s>59.999 ) s = 59.999;
          sqlite3_snprintf(7, &z[j],"%06.3f", s);
          j += sqlite3Strlen30(&z[j]);
          break;
        }
        case 'H':  sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break;
        case 'W': /* Fall thru */
        case 'j': {
          int nDay;             /* Number of days since 1st day of year */
          DateTime y = x;
          y.validJD = 0;
          y.M = 1;
          y.D = 1;
          computeJD(&y);
          nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
          if( zFmt[i]=='W' ){
            int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
            wd = (int)(((x.iJD+43200000)/86400000)%7);
            sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7);
            j += 2;
          }else{
            sqlite3_snprintf(4, &z[j],"%03d",nDay+1);
            j += 3;
          }
          break;
        }
        case 'J': {
          sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0);
          j+=sqlite3Strlen30(&z[j]);
          break;
        }
        case 'm':  sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break;
        case 'M':  sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break;
        case 's': {
          sqlite3_snprintf(30,&z[j],"%lld",
                           (i64)(x.iJD/1000 - 21086676*(i64)10000));
          j += sqlite3Strlen30(&z[j]);
          break;
        }
        case 'S':  sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break;
        case 'w': {
          z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
          break;
        }
        case 'Y': {
          sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]);
          break;
        }
        default:   z[j++] = '%'; break;
      }
    }
  }
  z[j] = 0;
  sqlite3_result_text(context, z, -1,
                      z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
}
示例#26
0
static void db_seq_create_func(
    sqlite3_context *context, int argc, sqlite3_value **argv)
{
	Btree *p;
	BtShared *pBt;
	SEQ_COOKIE cookie;
	int i, rc;
	sqlite3 *db;

	if (argc < 1) {
		btreeSeqError(context, SQLITE_ERROR,
		    "wrong number of arguments to function "
		    "create_sequence()");
		return;
	}
	/*
	 * Ensure that the sequence name is OK with our static buffer
	 * size. We need extra characters for "seq_" and "_db".
	 */
	if (strlen((const char *)sqlite3_value_text(argv[0])) >
	    BT_MAX_SEQ_NAME - 8) {
		btreeSeqError(context, SQLITE_ERROR,
		    "Sequence name too long.");
		return;
	}
	db = sqlite3_context_db_handle(context);
	/*
	 * TODO: How do we know which BtShared to use?
	 * What if there are multiple attached DBs, can the user specify which
	 * one to create the sequence on?
	 */
	p = db->aDb[0].pBt;
	pBt = p->pBt;

	if (!p->connected &&
	    (rc = btreeOpenEnvironment(p, 1)) != SQLITE_OK) {
		btreeSeqError(context, SQLITE_ERROR,
		    "%sconnection could not be opened.", MSG_CREATE_FAIL);
		return;
	}

	/* The cookie holds configuration information. */
	memset(&cookie, 0, sizeof(SEQ_COOKIE));
	cookie.incr = 1;

	sqlite3_snprintf(BT_MAX_SEQ_NAME, cookie.name, "seq_%s",
	    sqlite3_value_text(argv[0]));
	cookie.name_len = (int)strlen(cookie.name);
	if (pBt->dbStorage == DB_STORE_NAMED && btreeSeqExists(context, p,
	    cookie.name) == 1) {
		btreeSeqError(context, SQLITE_ERROR,
		    "Attempt to call sequence_create when a sequence "
		    "already exists.");
		return;
	}

	/*
	 * TODO: In the future calling create_sequence when there is already a
	 *       handle in the cache could be used to alter the "cookie" values.
	 *       Don't do that for now, because it requires opening and closing
	 *       the DB handle, which needs care if it's being used by
	 *       multiple threads.
	 */

	/* Set the boundary values to distinguish if user set the values. */
	cookie.min_val = -INT64_MAX;
	cookie.max_val = INT64_MAX;
	cookie.start_val = -INT64_MAX;

	/* Parse options. */
	for (i = 1; i < argc; i++) {
		if (strncmp((char *)sqlite3_value_text(argv[i]),
		    "cache", 5) == 0) {
			if (i == argc ||
			    sqlite3_value_type(argv[++i]) != SQLITE_INTEGER) {
				btreeSeqError(context, SQLITE_ERROR,
				    "%sInvalid parameter.", MSG_CREATE_FAIL);
				goto err;
			}
			cookie.cache = sqlite3_value_int(argv[i]);
		} else if (strncmp((char *)sqlite3_value_text(argv[i]),
		    "incr", 4) == 0) {
			if (i == argc ||
			    sqlite3_value_type(argv[++i]) != SQLITE_INTEGER) {
				btreeSeqError(context, SQLITE_ERROR,
				    "%sInvalid parameter.", MSG_CREATE_FAIL);
				goto err;
			}
			cookie.incr = sqlite3_value_int(argv[i]);
		} else if (strncmp((char *)sqlite3_value_text(argv[i]),
		    "maxvalue", 8) == 0) {
			if (i == argc ||
			    sqlite3_value_type(argv[++i]) != SQLITE_INTEGER) {
				btreeSeqError(context, SQLITE_ERROR,
				    "%sInvalid parameter.", MSG_CREATE_FAIL);
				goto err;
			}
			cookie.max_val = sqlite3_value_int(argv[i]);
		} else if (strncmp((char *)sqlite3_value_text(argv[i]),
		    "minvalue", 8) == 0) {
			if (i == argc ||
			    sqlite3_value_type(argv[++i]) != SQLITE_INTEGER) {
				btreeSeqError(context, SQLITE_ERROR,
				    "%sInvalid parameter.", MSG_CREATE_FAIL);
				goto err;
			}
			cookie.min_val = sqlite3_value_int(argv[i]);
		} else if (strncmp((char *)sqlite3_value_text(argv[i]),
		    "start", 5) == 0) {
			if (i == argc ||
			    sqlite3_value_type(argv[++i]) != SQLITE_INTEGER) {
				btreeSeqError(context, SQLITE_ERROR,
				    "%sInvalid parameter.", MSG_CREATE_FAIL);
				goto err;
			}
			cookie.start_val = sqlite3_value_int(argv[i]);
		} else {
			btreeSeqError(context, SQLITE_ERROR,
			    "%sInvalid parameter.", MSG_CREATE_FAIL);
			goto err;
		}
	}

	/*
	 * Setup the cookie. Do this after the parsing so param order doesn't
	 * matter.
	 */
	if (cookie.incr < 0) {
		cookie.decrementing = 1;
		cookie.incr = -cookie.incr;
	}
	/* Attempt to give a reasonable default start value. */
	if (cookie.start_val == -INT64_MAX) {
		/*
		 * Set a reasonable default start value, if
		 * only half of a range has been given.
		 */
		if (cookie.decrementing == 1 &&
		    cookie.max_val != INT64_MAX) {
			cookie.start_val = cookie.max_val;
		} else if (cookie.decrementing == 0 &&
		    cookie.min_val != -INT64_MAX) {
			cookie.start_val = cookie.min_val;
		} else {
			/*
			 * If user does not set start_val, min_val and
			 * max_val, set default start_val to 0 by default.
			 */
			cookie.start_val = 0;
		}
	}

	/* Validate the settings. */
	if (cookie.min_val > cookie.max_val && cookie.max_val != 0) {
		btreeSeqError(context, SQLITE_ERROR,
		    "%sInvalid parameter.", MSG_CREATE_FAIL);
		goto err;
	}

	if (cookie.min_val > cookie.start_val ||
	    cookie.max_val < cookie.start_val) { 
		btreeSeqError(context, SQLITE_ERROR,
		    "%sInvalid parameter.", MSG_CREATE_FAIL);
		goto err;
	}

	if (cookie.cache != 0 && db->autoCommit == 0) {
		btreeSeqError(context, SQLITE_ERROR,
		    "Cannot create caching sequence in a transaction.");
		goto err;
	}

	if ((rc = btreeSeqGetHandle(context, p, SEQ_HANDLE_CREATE, &cookie)) !=
	    SQLITE_OK) {
		if (rc != SQLITE_ERROR)
			btreeSeqError(context, dberr2sqlite(rc, NULL),
			    "Failed to create sequence %s. Error: %s",
			    (const char *)sqlite3_value_text(argv[0]),
			    db_strerror(rc));
		goto err;
	}

	sqlite3_result_int(context, SQLITE_OK);
err:	return;
}
示例#27
0
static int btreeSeqGetHandle(sqlite3_context *context, Btree *p,
    int mode, SEQ_COOKIE *cookie)
{
	BtShared *pBt;
	CACHED_DB *cache_entry, *stale_db;
	int ret;

	cache_entry = NULL;
	ret = SQLITE_OK;
	pBt = p->pBt;

	/* Does not support in-memory db and temp db for now */
	if (pBt->dbStorage != DB_STORE_NAMED) {
		btreeSeqError(context, SQLITE_ERROR,
		    "Sequences do not support in-memory or "
		    "temporary databases.");
		return (SQLITE_ERROR);
	}

	/*
	 * The process here is:
	 * - Is the handle already in the cache - if so, just return.
	 * - Else, does the sequence already exist:
	 *   + No: create the sequence
	 * - open a handle and add it to the cache
	 *
	 * Use the cookie to store the name. If the handle is cached, the value
	 * will be overwritten.
	 */
	sqlite3_mutex_enter(pBt->mutex);
	cache_entry =
	    sqlite3HashFind(&pBt->db_cache, cookie->name, cookie->name_len);
	sqlite3_mutex_leave(pBt->mutex);

	if (CACHE_ENTRY_VALID(cache_entry)) {
		/* Check to see if the handle is no longer valid. */
		if (btreeSeqExists(context, p, cookie->name) == 0) {
			btreeSeqRemoveHandle(context, p, cache_entry);
			return (DB_NOTFOUND);
		}
		if (mode == SEQ_HANDLE_OPEN) {
			assert(cache_entry->cookie != NULL);
			memcpy(cookie, cache_entry->cookie, sizeof(SEQ_COOKIE));
			cookie->handle = (DB_SEQUENCE *)cache_entry->dbp;
			return (SQLITE_OK);
		} else if (mode == SEQ_HANDLE_CREATE) {
			cookie->handle = NULL;
			return (DB_KEYEXIST);
		}
	}

	/*
	 * The handle wasn't found; Get seq handle by open or create the
	 * sequence with the given name.
	 */
	if ((ret = btreeSeqOpen(context, p, cookie)) != 0) {
		if (mode == SEQ_HANDLE_CREATE)
			ret = btreeSeqCreate(context, p, cookie);
	} else if (mode == SEQ_HANDLE_CREATE) {
		return DB_KEYEXIST;
	}

	if (ret != 0) {
		if (cookie->handle != NULL)
			cookie->handle->close(cookie->handle, 0);
		return (ret);
	}

	/*
	 *  We dropped the pBt->mutex after the lookup failed, grab it
	 *  again before inserting into the cache. That means there is a race
	 *  adding the handle to the cache, so we need to deal with that.
	 */
	sqlite3_mutex_enter(pBt->mutex);
	/* Check to see if someone beat us to adding the handle. */
	cache_entry =
	    sqlite3HashFind(&pBt->db_cache, cookie->name, cookie->name_len);
	if (CACHE_ENTRY_VALID(cache_entry)) {
		cookie->handle->close(cookie->handle, 0);
		cookie->handle = (DB_SEQUENCE *)cache_entry->dbp;
		goto err;
	}
	/* Add the new handle to the cache. */
	if ((cache_entry =
	    (CACHED_DB *)sqlite3_malloc(sizeof(CACHED_DB))) == NULL) {
		btreeSeqError(context, SQLITE_NOMEM,
		    "Memory allocation failure during sequence create.");
		ret = SQLITE_NOMEM;
		goto err;
	}
	memset(cache_entry, 0, sizeof(CACHED_DB));
	if ((cache_entry->cookie =
	    (SEQ_COOKIE *)sqlite3_malloc(sizeof(SEQ_COOKIE))) == NULL) {
		btreeSeqError(context, SQLITE_NOMEM,
		    "Memory allocation failure during sequence create.");
		ret = SQLITE_NOMEM;
		goto err;
	}
	sqlite3_snprintf(
	    sizeof(cache_entry->key), cache_entry->key, cookie->name);
	/*
	 * Hack alert!
	 * We're assigning the sequence to the DB pointer in the cached entry
	 * it makes everything simpler, since much of the code in btree.c is
	 * coded assuming dbp will be populated. It just means we need to be a
	 * bit careful using DB handles from the cache now.
	 */
	cache_entry->dbp = (DB *)cookie->handle;
	cache_entry->is_sequence = 1;
	memcpy(cache_entry->cookie, cookie, sizeof(SEQ_COOKIE));
	stale_db = sqlite3HashInsert(&pBt->db_cache, cache_entry->key,
	    cookie->name_len, cache_entry);
	if (stale_db) {
		sqlite3_free(stale_db);
		/*
		 * Hash table out of memory when returned pointer is
		 * same as the original value pointer.
		 */
		if (stale_db == cache_entry) {
			btreeSeqError(context, SQLITE_NOMEM, MSG_MALLOC_FAIL);
			ret = SQLITE_NOMEM;
			goto err;
		}
	}

err:	sqlite3_mutex_leave(pBt->mutex);
	if (ret != 0 && cache_entry != NULL) {
		if (cache_entry->cookie != NULL)
			sqlite3_free(cache_entry->cookie);
		sqlite3_free(cache_entry);
	}
	return (ret);
}
示例#28
0
static void btreeSeqGetVal(
    sqlite3_context *context, const char * name, int mode) {

	Btree *p;
	BtShared *pBt;
	SEQ_COOKIE cookie;
	db_seq_t val;
	int rc, ret;
	sqlite3 *db;

	db = sqlite3_context_db_handle(context);
	p = db->aDb[0].pBt;
	pBt = p->pBt;
	memset(&cookie, 0, sizeof(cookie));

	if (!p->connected &&
	    (rc = btreeOpenEnvironment(p, 1)) != SQLITE_OK) {
		sqlite3_result_error(context,
		    "Sequence open failed: connection could not be opened.",
		    -1);
		return;
	}

	sqlite3_snprintf(BT_MAX_SEQ_NAME, cookie.name, "seq_%s", name);
	cookie.name_len = (int)strlen(cookie.name);
	rc = btreeSeqGetHandle(context, p, SEQ_HANDLE_OPEN, &cookie);

	if (rc != SQLITE_OK) {
		if (rc == DB_NOTFOUND) 
			btreeSeqError(context, dberr2sqlite(rc, NULL),
			    "no such sequence: %s", name);
		else if (rc != SQLITE_ERROR)
			btreeSeqError(context, dberr2sqlite(rc, NULL),
			    "Fail to get next value from seq %s. Error: %s",
			    name, db_strerror(rc));
		return;
	}

	if (cookie.cache == 0) {
		/*
		 * Ensure we see the latest value across connections. Use
		 * DB_RMW to ensure that no other process changes the value
		 * while we're updating it.
		 */
		if ((ret =
		    btreeSeqGetCookie(context, p, &cookie, DB_RMW)) != 0) {
			btreeSeqError(context, SQLITE_ERROR,
			    "Failed to retrieve sequence value. Error: %s",
			    db_strerror(ret));
			return;
		}
		if (mode == DB_SEQ_NEXT) {
			/* Bounds check. */
			if (cookie.used && ((cookie.decrementing &&
			    cookie.val - cookie.incr < cookie.min_val) ||
			    (!cookie.decrementing &&
			    cookie.val + cookie.incr > cookie.max_val))) {
				btreeSeqError(context, SQLITE_ERROR,
				    "Sequence value out of bounds.");
				return;
			}
			if (!cookie.used) {
				cookie.used = 1;
				cookie.val = cookie.start_val;
			} else if (cookie.decrementing)
				cookie.val -= cookie.incr;
			else
				cookie.val += cookie.incr;
			btreeSeqPutCookie(context, p, &cookie, 0);
		} else if (!cookie.used) {
			btreeSeqError(context, SQLITE_ERROR,
			    "Can't call currval on an unused sequence.");
			return ;
		}
		val = cookie.val;
	} else {
		if (mode == DB_SEQ_CURRENT) {
			btreeSeqError(context, SQLITE_ERROR,
			    "Can't call currval on a caching sequence.");
			return;
		}
		/*
		 * Using a cached sequence while an exclusive transaction is
		 * active on this handle causes a hang. Avoid it.
		 */
		if (p->txn_excl == 1) {
			btreeSeqError(context, SQLITE_ERROR,
			    "Can't call nextval on a caching sequence while an"
			    " exclusive transaction is active.");
			return;
		}
		/* Cached gets can't be transactionally protected. */
		if ((ret = cookie.handle->get(cookie.handle, NULL,
		    cookie.incr, &val, 0)) != 0) {
			if (ret == EINVAL)
				btreeSeqError(context, SQLITE_ERROR,
				    "Sequence value out of bounds.");
			else
				btreeSeqError(context, SQLITE_ERROR,
				    "Failed sequence get. Error: %s",
				    db_strerror(ret));
			return;
		}
	}

	sqlite3_result_int64(context, val);

}
示例#29
0
static void db_seq_drop_func(
    sqlite3_context *context, int argc, sqlite3_value **argv)
{
	Btree *p;
	BtShared *pBt;
	CACHED_DB *cache_entry;
	SEQ_COOKIE cookie;
	int mutex_held, rc;
	sqlite3 *db;

	db = sqlite3_context_db_handle(context);
	p = db->aDb[0].pBt;
	pBt = p->pBt;
	mutex_held = 0;
	memset(&cookie, 0, sizeof(cookie));

	if (!p->connected &&
	    (rc = btreeOpenEnvironment(p, 1)) != SQLITE_OK) {
		btreeSeqError(context, SQLITE_ERROR,
		    "Sequence drop failed: connection could not be opened.");
		return;
	}

	sqlite3_snprintf(BT_MAX_SEQ_NAME, cookie.name, "seq_%s",
	    sqlite3_value_text(argv[0]));
	cookie.name_len = (int)strlen(cookie.name);
	rc = btreeSeqGetHandle(context, p, SEQ_HANDLE_OPEN, &cookie);
	
	if (rc != SQLITE_OK) {
		/* If the handle doesn't exist, return an error. */
		if (rc == DB_NOTFOUND) 
			btreeSeqError(context, dberr2sqlite(rc, NULL),
			    "no such sequence: %s", cookie.name + 4);
		else if (rc != SQLITE_ERROR)
			btreeSeqError(context, dberr2sqlite(rc, NULL),
			"Fail to drop sequence %s. Error: %s",
			cookie.name + 4, db_strerror(rc));
		return;
	}

	sqlite3_mutex_enter(pBt->mutex);
	mutex_held = 1;
	cache_entry =
	    sqlite3HashFind(&pBt->db_cache, cookie.name, cookie.name_len);

	if (cache_entry == NULL)
		goto done;

	if (cookie.cache != 0 && db->autoCommit == 0) {
		btreeSeqError(context, SQLITE_ERROR,
		    "Cannot drop caching sequence in a transaction.");
		rc = SQLITE_ERROR;
		goto done;
	}

	sqlite3_mutex_leave(pBt->mutex);
	if ((rc = btreeSeqStartTransaction(context, p, 1)) != SQLITE_OK) {
			btreeSeqError(context, SQLITE_ERROR,
			    "Could not begin transaction for drop.");
			return;
	}

	/*
	 * Drop the mutex - it's not valid to begin a transaction while
	 * holding the mutex. We can drop it safely because it's use is to
	 * protect handle cache changes.
	 */
	sqlite3_mutex_enter(pBt->mutex);
	btreeSeqRemoveHandle(context, p, cache_entry);
done:	sqlite3_mutex_leave(pBt->mutex);

	if (rc == SQLITE_OK)
		sqlite3_result_int(context, SQLITE_OK);
}
示例#30
0
int
seaf_branch_manager_add_branch (SeafBranchManager *mgr, SeafBranch *branch)
{
#ifndef SEAFILE_SERVER
    char sql[256];

    pthread_mutex_lock (&mgr->priv->db_lock);

    sqlite3_snprintf (sizeof(sql), sql,
                      "SELECT 1 FROM Branch WHERE name=%Q and repo_id=%Q",
                      branch->name, branch->repo_id);
    if (sqlite_check_for_existence (mgr->priv->db, sql))
        sqlite3_snprintf (sizeof(sql), sql,
                          "UPDATE Branch SET commit_id=%Q WHERE "
                          "name=%Q and repo_id=%Q",
                          branch->commit_id, branch->name, branch->repo_id);
    else
        sqlite3_snprintf (sizeof(sql), sql,
                          "INSERT INTO Branch VALUES (%Q, %Q, %Q)",
                          branch->name, branch->repo_id, branch->commit_id);

    sqlite_query_exec (mgr->priv->db, sql);

    pthread_mutex_unlock (&mgr->priv->db_lock);

    return 0;
#else
    char *sql;
    SeafDB *db = mgr->seaf->db;

    if (seaf_db_type(db) == SEAF_DB_TYPE_PGSQL) {
        gboolean exists, err;
        int rc;

        sql = "SELECT repo_id FROM Branch WHERE name=? AND repo_id=?";
        exists = seaf_db_statement_exists(db, sql, &err,
                                          2, "string", branch->name,
                                          "string", branch->repo_id);
        if (err)
            return -1;

        if (exists)
            rc = seaf_db_statement_query (db,
                                          "UPDATE Branch SET commit_id=? "
                                          "WHERE name=? AND repo_id=?",
                                          3, "string", branch->commit_id,
                                          "string", branch->name,
                                          "string", branch->repo_id);
        else
            rc = seaf_db_statement_query (db,
                                          "INSERT INTO Branch VALUES (?, ?, ?)",
                                          3, "string", branch->name,
                                          "string", branch->repo_id,
                                          "string", branch->commit_id);
        if (rc < 0)
            return -1;
    } else {
        int rc = seaf_db_statement_query (db,
                                 "REPLACE INTO Branch VALUES (?, ?, ?)",
                                 3, "string", branch->name,
                                 "string", branch->repo_id,
                                 "string", branch->commit_id);
        if (rc < 0)
            return -1;
    }
    return 0;
#endif
}