/* public native void close(); */
static void dbclose(JNIEnv* env, jobject object)
{
    sqlite3 * handle = (sqlite3 *)env->GetIntField(object, offset_db_handle);

    if (handle != NULL) {
        // release the memory associated with the traceFuncArg in enableSqlTracing function
        void *traceFuncArg = sqlite3_trace(handle, &sqlTrace, NULL);
        if (traceFuncArg != NULL) {
            free(traceFuncArg);
        }
        // release the memory associated with the traceFuncArg in enableSqlProfiling function
        traceFuncArg = sqlite3_profile(handle, &sqlProfile, NULL);
        if (traceFuncArg != NULL) {
            free(traceFuncArg);
        }
        LOGV("Closing database: handle=%p\n", handle);
        int result = sqlite3_close(handle);
        if (result == SQLITE_OK) {
            LOGV("Closed %p\n", handle);
            env->SetIntField(object, offset_db_handle, 0);
        } else {
            // This can happen if sub-objects aren't closed first.  Make sure the caller knows.
            throw_sqlite3_exception(env, handle);
            LOGE("sqlite3_close(%p) failed: %d\n", handle, result);
        }
    }
}
Ejemplo n.º 2
0
  std::vector<std::string> process()
  {
    std::srand(std::time(0));

    std::vector<CallbackData> dbs;
    std::vector<std::string> tortured_databases;

    dbs.emplace_back(CallbackData(tortured_databases, open_database("test1.db")));
    dbs.emplace_back(CallbackData(tortured_databases, open_database("test2.db")));
    dbs.emplace_back(CallbackData(tortured_databases, open_database("test3.db")));
    dbs.emplace_back(CallbackData(tortured_databases, open_database("test4.db")));
    dbs.emplace_back(CallbackData(tortured_databases, open_database("test5.db")));

    for (size_t i = 0; i<dbs.size(); ++i) {
      sqlite3_trace(dbs[i].db_, trace_callback, &dbs[i]);
    }

    for (size_t i = 0; i<dbs.size(); ++i) {
      torture_database(dbs[std::rand() % dbs.size()].db_);  
    }

    for (size_t i = 0; i<dbs.size(); ++i) {
      sqlite3_close(dbs[i].db_);
    }
    return tortured_databases;
  }
Ejemplo n.º 3
0
bool DB::Connection::connect(const char *
#if HAVE_SQL_TRACE
							 connectionLabel
#endif
							 )
{
	// Create and set file permissions if the DB does not exist.
	int fd = open(_dbpath.c_str(), O_CREAT, S_IRUSR | S_IWUSR);
	if (fd == -1)
	{
		DB::logError("Could not open database: %s (errno %i)",
			     _dbpath.c_str(), errno);
		return false;
	}
	::close(fd);

	int rv = sqlite3_open_v2(_dbpath.c_str(),
							 &_db,
							 SQLITE_OPEN_READWRITE
							 | SQLITE_OPEN_CREATE
							 | SQLITE_OPEN_FULLMUTEX,
							 NULL);

	if (rv != SQLITE_OK) {
		reportErrorDB(_db);
		return false;
	}

	int foreignKeyEnabled = 0;
	rv = sqlite3_db_config(_db,SQLITE_DBCONFIG_ENABLE_FKEY,1,&foreignKeyEnabled);
	if (rv != SQLITE_OK) {
		reportErrorDB(_db);
		return false;
	}

	if (foreignKeyEnabled != 1) {
		DB::logError("Connection::connect: foreign key support not enabled");
		return false;
	}

	rv = sqlite3_busy_timeout(_db, 15000); // 15 seconds
	if (rv != SQLITE_OK) {
		reportErrorDB(_db);
		return false;
	}
#if HAVE_SQL_TRACE
	sqlite3_trace(_db, xTrace, const_cast<char *>(connectionLabel));
#endif
	return true;
}
Ejemplo n.º 4
0
JournalStore* journal_store_open(JamAccount *acc, gboolean create, GError **err) {
	JournalStore *js = NULL;
	char *path = NULL;
	sqlite3 *db = NULL;
	int ret;
	gboolean exists;

	path = conf_make_account_path(acc, "journal.db");
	exists = g_file_test(path, G_FILE_TEST_EXISTS);

	if (!exists && !create) {
		g_set_error(err, 0, 0, "No offline copy of this journal.");
		goto out;
	}

	if (!verify_path(path, FALSE, &err))
		goto out;

	ret = sqlite3_open(path, &db);
	if (ret != SQLITE_OK) {
		g_set_error(err, 0, 0, "sqlite error %d: %s", ret, sqlite3_errmsg(db));
		goto out;
	}

	sqlite3_trace(db, sql_trace, NULL);

	if (exists) {
		if (!check_version(db)) {
			g_set_error(err, 0, 0,
					"The on-disk journal version differs from "
					"the version understood by this version of LogJam.  "
					"You need to resynchronize your journal.");
			goto out;
		}
	} else {
		if (!init_db(db, err))
			goto out;
	}

	js = g_new0(JournalStore, 1);
	js->account = acc;
	js->db = db;

out:
	g_free(path);
	if (!js && db) sqlite3_close(db);
	return js;
}
Ejemplo n.º 5
0
bool marky::Backend_SQLite::init() {
    if (db != NULL) {
        ERROR("Already inited sqlite db at %s!", path.c_str());
        return false;
    }

    int ret = sqlite3_open(path.c_str(), &db);/* rw + create */
    if (ret != SQLITE_OK) {
        ERROR("Failed to open sqlite db at %s: %d/%s",
                path.c_str(), ret, sqlite3_errmsg(db));
        return false;
    }

#ifdef DEBUG_ENABLED
    sqlite3_trace(db, trace_callback, NULL);
#endif

    if (!exec(db, PRAGMA_ENABLE_FOREIGN_KEYS)) {
        ERROR("Unable to enable SQLite Foreign Key support. "
                "Please rebuild SQLite with SQLITE_OMIT_FORIGN_KEY and SQLITE_OMIT_TRIGGER turned OFF!");
        return false;
    }
    if (!exec(db, UNSAFE_PRAGMA_OPTIMIZATIONS)) {
        LOG("Failed to enable unsafe SQLite speed optimizations. Continuing anyway...");
    }
    if (!exec(db, QUERY_CREATE_TABLES)) {
        return false;
    }

    if (!prepare(db, QUERY_SET_STATE, stmt_set_state) ||
            !prepare(db, QUERY_GET_STATE, stmt_get_state) ||
            !prepare(db, QUERY_GET_RANDOM, stmt_get_random) ||
            !prepare(db, QUERY_GET_PREVS, stmt_get_prevs) ||
            !prepare(db, QUERY_GET_NEXTS, stmt_get_nexts) ||
            !prepare(db, QUERY_UPDATE_SNIPPET, stmt_update_snippet) ||
            !prepare(db, QUERY_UPSERT_SNIPPET, stmt_upsert_snippet) ||
            !prepare(db, QUERY_INSERT_SNIPPET, stmt_insert_snippet) ||
            !prepare(db, QUERY_INSERT_NEXT, stmt_insert_next) ||
            !prepare(db, QUERY_INSERT_PREV, stmt_insert_prev) ||
            !prepare(db, QUERY_GET_ALL, stmt_get_all) ||
            !prepare(db, QUERY_DELETE_SNIPPET, stmt_delete_snippet)) {
        ERROR("Unable to prepare SQLite statements.");
        return false;
    }
    return true;
}
Ejemplo n.º 6
0
bool DB::Connection::connect(const char *
#if HAVE_SQL_TRACE
							 connectionLabel
#endif
							 )
{
	// Circumvent the sqlite3 reliance on umask to enforce secure permissions
	mode_t saved_umask = umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);

	int rv = sqlite3_open_v2(_dbpath.c_str(),
							 &_db,
							 SQLITE_OPEN_READWRITE
							 | SQLITE_OPEN_CREATE
							 | SQLITE_OPEN_FULLMUTEX,
							 NULL);
	// Restore umask to avoid side effects
	(void) umask(saved_umask);

	if (rv != SQLITE_OK) {
		reportErrorDB(_db);
		return false;
	}

	int foreignKeyEnabled = 0;
	rv = sqlite3_db_config(_db,SQLITE_DBCONFIG_ENABLE_FKEY,1,&foreignKeyEnabled);
	if (rv != SQLITE_OK) {
		reportErrorDB(_db);
		return false;
	}

	if (foreignKeyEnabled != 1) {
		DB::logError("Connection::connect: foreign key support not enabled");
		return false;
	}

	rv = sqlite3_busy_timeout(_db, 15000); // 15 seconds
	if (rv != SQLITE_OK) {
		reportErrorDB(_db);
		return false;
	}
#if HAVE_SQL_TRACE
	sqlite3_trace(_db, xTrace, const_cast<char *>(connectionLabel));
#endif
	return true;
}
Ejemplo n.º 7
0
/* call-seq:
 *    trace { |sql| ... }
 *    trace(Class.new { def call sql; end }.new)
 *
 * Installs (or removes) a block that will be invoked for every SQL
 * statement executed. The block receives one parameter: the SQL statement
 * executed. If the block is +nil+, any existing tracer will be uninstalled.
 */
static VALUE trace(int argc, VALUE *argv, VALUE self)
{
  sqlite3RubyPtr ctx;
  VALUE block;

  Data_Get_Struct(self, sqlite3Ruby, ctx);
  REQUIRE_OPEN_DB(ctx);

  rb_scan_args(argc, argv, "01", &block);

  if(NIL_P(block) && rb_block_given_p()) block = rb_block_proc();

  rb_iv_set(self, "@tracefunc", block);

  sqlite3_trace(ctx->db, NIL_P(block) ? NULL : tracefunc, (void *)self);

  return self;
}
Ejemplo n.º 8
0
MetadataStorage::MetadataStorage(const char* db, aku_logger_cb_t logger)
    : pool_(nullptr, &delete_apr_pool)
    , driver_(nullptr)
    , handle_(nullptr, AprHandleDeleter(nullptr))
    , logger_(logger)
{
    apr_pool_t *pool = nullptr;
    auto status = apr_pool_create(&pool, NULL);
    if (status != APR_SUCCESS) {
        // report error (can't return error from c-tor)
        throw std::runtime_error("Can't create memory pool");
    }
    pool_.reset(pool);

    status = apr_dbd_get_driver(pool, "sqlite3", &driver_);
    if (status != APR_SUCCESS) {
        (*logger_)(AKU_LOG_ERROR, "Can't load driver, maybe libaprutil1-dbd-sqlite3 isn't installed");
        throw std::runtime_error("Can't load sqlite3 dirver");
    }

    apr_dbd_t *handle = nullptr;
    status = apr_dbd_open(driver_, pool, db, &handle);
    if (status != APR_SUCCESS) {
        (*logger_)(AKU_LOG_ERROR, "Can't open database, check file path");
        throw std::runtime_error("Can't open database");
    }
    handle_ = HandleT(handle, AprHandleDeleter(driver_));

    auto sqlite_handle = apr_dbd_native_handle(driver_, handle);
    sqlite3_trace((sqlite3*)sqlite_handle, callback_adapter, (void*)logger_);

    create_tables();

    // Create prepared statement
    const char* query = "INSERT INTO akumuli_series (series_id, keyslist, storage_id) VALUES (%s, %s, %d)";
    status = apr_dbd_prepare(driver_, pool_.get(), handle_.get(), query, "INSERT_SERIES_NAME", &insert_);
    if (status != 0) {
        (*logger_)(AKU_LOG_ERROR, "Error creating prepared statement");
        throw std::runtime_error(apr_dbd_error(driver_, handle_.get(), status));
    }
}
Ejemplo n.º 9
0
SqliteTrainerModel::SqliteTrainerModel(QObject *parent, QString fileName) :
    TrainerModel(parent)
{

    m_cardItemModel = new CardItemModel(this);
    m_cardItemModel->setObjectName("card_items");

    QSqlError err;
    QSqlDatabase db = QSqlDatabase::database(fileName);
    if(!db.isValid()) {
        db = QSqlDatabase::addDatabase("QSQLITE", fileName);
        db.setDatabaseName(fileName);
    }
    if (!db.open()) {
        err = db.lastError();
        db = QSqlDatabase();
        QSqlDatabase::removeDatabase(fileName);
    }
    if(err.isValid()) {
        qWarning() << err.text();
    } else {
        qDebug() << fileName << "opened";

        m_db = db;

        QVariant v = db.driver()->handle();
        if (v.isValid() && qstrcmp(v.typeName(), "sqlite3*")==0) {
            // v.data() returns a pointer to the handle
            sqlite3 *handle = *static_cast<sqlite3 **>(v.data());
            if (handle != 0) { // check that it is not NULL
                sqlite3_trace(handle,trace,NULL);
            }
        }

        initCardItemModel();

        initModels();

    }

}
Ejemplo n.º 10
0
Archivo: scache.c Proyecto: hyc/heimdal
static krb5_error_code
default_db(krb5_context context, sqlite3 **db)
{
    char *name;
    int ret;

    ret = _krb5_expand_default_cc_name(context, KRB5_SCACHE_DB, &name);
    if (ret)
	return ret;

    ret = sqlite3_open_v2(name, db, SQLITE_OPEN_READWRITE, NULL);
    free(name);
    if (ret != SQLITE_OK) {
	krb5_clear_error_message(context);
	return ENOENT;
    }

#ifdef TRACEME
    sqlite3_trace(*db, trace, NULL);
#endif

    return 0;
}
Ejemplo n.º 11
0
/*
   SQLite dbs have no user name, passwords, hosts or ports.
   just file names.
*/
bool SQLiteDriver::open(const QString & db, const QString &, const QString &, const QString &, int, const QString &)
{
    if (isOpen())
        close();

    if (db.isEmpty())
        return false;

    if (sqlite3_open16(db.utf16(), &d->access) == SQLITE_OK) {
        sqlite3_busy_timeout(d->access, 500);
#if defined(SQLITEDRIVER_DEBUG)
        sqlite3_trace(d->access, trace, NULL);
#endif
        setOpen(true);
        setOpenError(false);
        installSQLiteExtension(d->access);
        return true;
    } else {
        setLastError(qMakeError(d->access, tr("Error opening database"),
                     QSqlError::ConnectionError));
        setOpenError(true);
        return false;
    }
}
static jlong nativeOpen(JNIEnv* env, jclass clazz, jstring pathStr, jint openFlags,
        jstring labelStr, jboolean enableTrace, jboolean enableProfile) {
    int sqliteFlags;
    if (openFlags & SQLiteConnection::CREATE_IF_NECESSARY) {
        sqliteFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
    } else if (openFlags & SQLiteConnection::OPEN_READONLY) {
        sqliteFlags = SQLITE_OPEN_READONLY;
    } else {
        sqliteFlags = SQLITE_OPEN_READWRITE;
    }

    const char* pathChars = env->GetStringUTFChars(pathStr, NULL);
    String8 path(pathChars);
    env->ReleaseStringUTFChars(pathStr, pathChars);

    const char* labelChars = env->GetStringUTFChars(labelStr, NULL);
    String8 label(labelChars);
    env->ReleaseStringUTFChars(labelStr, labelChars);

    sqlite3* db;
    int err = sqlite3_open_v2(path.string(), &db, sqliteFlags, NULL);
    if (err != SQLITE_OK) {
        throw_sqlite3_exception_errcode(env, err, "Could not open database");
        return 0;
    }

    // Check that the database is really read/write when that is what we asked for.
    if ((sqliteFlags & SQLITE_OPEN_READWRITE) && sqlite3_db_readonly(db, NULL)) {
        throw_sqlite3_exception(env, db, "Could not open the database in read/write mode.");
        sqlite3_close(db);
        return 0;
    }

    // Set the default busy handler to retry automatically before returning SQLITE_BUSY.
    err = sqlite3_busy_timeout(db, BUSY_TIMEOUT_MS);
    if (err != SQLITE_OK) {
        throw_sqlite3_exception(env, db, "Could not set busy timeout");
        sqlite3_close(db);
        return 0;
    }

    // Register custom Android functions.
    err = register_android_functions(db, UTF16_STORAGE);
    if (err) {
        throw_sqlite3_exception(env, db, "Could not register Android SQL functions.");
        sqlite3_close(db);
        return 0;
    }

    // Create wrapper object.
    SQLiteConnection* connection = new SQLiteConnection(db, openFlags, path, label);

    // Enable tracing and profiling if requested.
    if (enableTrace) {
        sqlite3_trace(db, &sqliteTraceCallback, connection);
    }
    if (enableProfile) {
        sqlite3_profile(db, &sqliteProfileCallback, connection);
    }

    ALOGV("Opened connection %p with label '%s'", db, label.string());
    return reinterpret_cast<jlong>(connection);
}
Ejemplo n.º 13
0
Archivo: scache.c Proyecto: hyc/heimdal
static krb5_error_code
make_database(krb5_context context, krb5_scache *s)
{
    int created_file = 0;
    int ret;

    if (s->db)
	return 0;

    ret = open_database(context, s, 0);
    if (ret) {
	mode_t oldumask = umask(077);
	ret = open_database(context, s, SQLITE_OPEN_CREATE);
	umask(oldumask);
	if (ret) goto out;

	created_file = 1;

	ret = exec_stmt(context, s->db, SQL_CMASTER, KRB5_CC_IO);
	if (ret) goto out;
	ret = exec_stmt(context, s->db, SQL_CCACHE, KRB5_CC_IO);
	if (ret) goto out;
	ret = exec_stmt(context, s->db, SQL_CCREDS, KRB5_CC_IO);
	if (ret) goto out;
	ret = exec_stmt(context, s->db, SQL_CPRINCIPALS, KRB5_CC_IO);
	if (ret) goto out;
	ret = exec_stmt(context, s->db, SQL_SETUP_MASTER, KRB5_CC_IO);
	if (ret) goto out;

	ret = exec_stmt(context, s->db, SQL_TCACHE, KRB5_CC_IO);
	if (ret) goto out;
	ret = exec_stmt(context, s->db, SQL_TCRED, KRB5_CC_IO);
	if (ret) goto out;
    }

#ifdef TRACEME
    sqlite3_trace(s->db, trace, NULL);
#endif

    ret = prepare_stmt(context, s->db, &s->icred, SQL_ICRED);
    if (ret) goto out;
    ret = prepare_stmt(context, s->db, &s->dcred, SQL_DCRED);
    if (ret) goto out;
    ret = prepare_stmt(context, s->db, &s->iprincipal, SQL_IPRINCIPAL);
    if (ret) goto out;
    ret = prepare_stmt(context, s->db, &s->icache, SQL_ICACHE);
    if (ret) goto out;
    ret = prepare_stmt(context, s->db, &s->ucachen, SQL_UCACHE_NAME);
    if (ret) goto out;
    ret = prepare_stmt(context, s->db, &s->ucachep, SQL_UCACHE_PRINCIPAL);
    if (ret) goto out;
    ret = prepare_stmt(context, s->db, &s->dcache, SQL_DCACHE);
    if (ret) goto out;
    ret = prepare_stmt(context, s->db, &s->scache, SQL_SCACHE);
    if (ret) goto out;
    ret = prepare_stmt(context, s->db, &s->scache_name, SQL_SCACHE_NAME);
    if (ret) goto out;
    ret = prepare_stmt(context, s->db, &s->umaster, SQL_UMASTER);
    if (ret) goto out;

    return 0;

out:
    if (s->db)
	sqlite3_close(s->db);
    if (created_file)
	unlink(s->file);

    return ret;
}
Ejemplo n.º 14
0
int main(int argc, char **argv){
  const char *zFileToRead = 0;  /* Input file.  NULL for stdin */
  const char *zDbName = 0;      /* Name of the database file to create */
  int useWithoutRowid = 0;      /* True for --without-rowid */
  int iMode = MODE_INSERT;      /* One of MODE_xxxxx */
  int useNocase = 0;            /* True for --nocase */
  int doTrace = 0;              /* True for --trace */
  int showStats = 0;            /* True for --stats */
  int showSummary = 0;          /* True for --summary */
  int showTimer = 0;            /* True for --timer */
  int cacheSize = 0;            /* Desired cache size.  0 means default */
  int pageSize = 0;             /* Desired page size.  0 means default */
  int commitInterval = 0;       /* How often to commit.  0 means never */
  int noSync = 0;               /* True for --nosync */
  const char *zJMode = 0;       /* Journal mode */
  int nOp = 0;                  /* Operation counter */
  int i, j;                     /* Loop counters */
  sqlite3 *db;                  /* The SQLite database connection */
  char *zSql;                   /* Constructed SQL statement */
  sqlite3_stmt *pInsert = 0;    /* The INSERT statement */
  sqlite3_stmt *pUpdate = 0;    /* The UPDATE statement */
  sqlite3_stmt *pSelect = 0;    /* The SELECT statement */
  sqlite3_stmt *pDelete = 0;    /* The DELETE statement */
  FILE *in;                     /* The open input file */
  int rc;                       /* Return code from an SQLite interface */
  int iCur, iHiwtr;             /* Statistics values, current and "highwater" */
  sqlite3_int64 sumCnt = 0;     /* Sum in QUERY mode */
  sqlite3_int64 startTime;
  char zInput[2000];            /* A single line of input */

  /* Process command-line arguments */
  for(i=1; i<argc; i++){
    const char *z = argv[i];
    if( z[0]=='-' ){
      do{ z++; }while( z[0]=='-' );
      if( strcmp(z,"without-rowid")==0 ){
        useWithoutRowid = 1;
      }else if( strcmp(z,"replace")==0 ){
        iMode = MODE_REPLACE;
      }else if( strcmp(z,"select")==0 ){
        iMode = MODE_SELECT;
      }else if( strcmp(z,"insert")==0 ){
        iMode = MODE_INSERT;
      }else if( strcmp(z,"update")==0 ){
        iMode = MODE_UPDATE;
      }else if( strcmp(z,"delete")==0 ){
        iMode = MODE_DELETE;
      }else if( strcmp(z,"query")==0 ){
        iMode = MODE_QUERY;
      }else if( strcmp(z,"nocase")==0 ){
        useNocase = 1;
      }else if( strcmp(z,"trace")==0 ){
        doTrace = 1;
      }else if( strcmp(z,"nosync")==0 ){
        noSync = 1;
      }else if( strcmp(z,"stats")==0 ){
        showStats = 1;
      }else if( strcmp(z,"summary")==0 ){
        showSummary = 1;
      }else if( strcmp(z,"timer")==0 ){
        showTimer = i;
      }else if( strcmp(z,"cachesize")==0 && i<argc-1 ){
        i++;
        cacheSize = atoi(argv[i]);
      }else if( strcmp(z,"pagesize")==0 && i<argc-1 ){
        i++;
        pageSize = atoi(argv[i]);
      }else if( strcmp(z,"commit")==0 && i<argc-1 ){
        i++;
        commitInterval = atoi(argv[i]);
      }else if( strcmp(z,"journal")==0 && i<argc-1 ){
        zJMode = argv[++i];
      }else{
        fatal_error("unknown option: %s\n", argv[i]);
      }
    }else if( zDbName==0 ){
      zDbName = argv[i];
    }else if( zFileToRead==0 ){
      zFileToRead = argv[i];
    }else{
      fatal_error("surplus argument: %s\n", argv[i]);
    }
  }
  if( zDbName==0 ){
    fatal_error("Usage: %s [--options] DATABASE [INPUTFILE]\n", argv[0]);
  }
  startTime = realTime();

  /* Open the database and the input file */
  if( sqlite3_open(zDbName, &db) ){
    fatal_error("Cannot open database file: %s\n", zDbName);
  }
  if( zFileToRead ){
    in = fopen(zFileToRead, "rb");
    if( in==0 ){
      fatal_error("Could not open input file \"%s\"\n", zFileToRead);
    }
  }else{
    in = stdin;
  }

  /* Set database connection options */
  if( doTrace ) sqlite3_trace(db, traceCallback, 0);
  if( pageSize ){
    zSql = sqlite3_mprintf("PRAGMA page_size=%d", pageSize);
    sqlite3_exec(db, zSql, 0, 0, 0);
    sqlite3_free(zSql);
  }
  if( cacheSize ){
    zSql = sqlite3_mprintf("PRAGMA cache_size=%d", cacheSize);
    sqlite3_exec(db, zSql, 0, 0, 0);
    sqlite3_free(zSql);
  }
  if( noSync ) sqlite3_exec(db, "PRAGMA synchronous=OFF", 0, 0, 0);
  if( zJMode ){
    zSql = sqlite3_mprintf("PRAGMA journal_mode=%s", zJMode);
    sqlite3_exec(db, zSql, 0, 0, 0);
    sqlite3_free(zSql);
  }


  /* Construct the "wordcount" table into which to put the words */
  if( sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, 0) ){
    fatal_error("Could not start a transaction\n");
  }
  zSql = sqlite3_mprintf(
     "CREATE TABLE IF NOT EXISTS wordcount(\n"
     "  word TEXT PRIMARY KEY COLLATE %s,\n"
     "  cnt INTEGER\n"
     ")%s",
     useNocase ? "nocase" : "binary",
     useWithoutRowid ? " WITHOUT ROWID" : ""
  );
  if( zSql==0 ) fatal_error("out of memory\n");
  rc = sqlite3_exec(db, zSql, 0, 0, 0);
  if( rc ) fatal_error("Could not create the wordcount table: %s.\n",
                       sqlite3_errmsg(db));
  sqlite3_free(zSql);

  /* Prepare SQL statements that will be needed */
  if( iMode==MODE_QUERY ){
    rc = sqlite3_prepare_v2(db,
          "SELECT cnt FROM wordcount WHERE word=?1",
          -1, &pSelect, 0);
    if( rc ) fatal_error("Could not prepare the SELECT statement: %s\n",
                          sqlite3_errmsg(db));
  }
  if( iMode==MODE_SELECT ){
    rc = sqlite3_prepare_v2(db,
          "SELECT 1 FROM wordcount WHERE word=?1",
          -1, &pSelect, 0);
    if( rc ) fatal_error("Could not prepare the SELECT statement: %s\n",
                          sqlite3_errmsg(db));
    rc = sqlite3_prepare_v2(db,
          "INSERT INTO wordcount(word,cnt) VALUES(?1,1)",
          -1, &pInsert, 0);
    if( rc ) fatal_error("Could not prepare the INSERT statement: %s\n",
                         sqlite3_errmsg(db));
  }
  if( iMode==MODE_SELECT || iMode==MODE_UPDATE || iMode==MODE_INSERT ){
    rc = sqlite3_prepare_v2(db,
          "UPDATE wordcount SET cnt=cnt+1 WHERE word=?1",
          -1, &pUpdate, 0);
    if( rc ) fatal_error("Could not prepare the UPDATE statement: %s\n",
                         sqlite3_errmsg(db));
  }
  if( iMode==MODE_INSERT ){
    rc = sqlite3_prepare_v2(db,
          "INSERT OR IGNORE INTO wordcount(word,cnt) VALUES(?1,1)",
          -1, &pInsert, 0);
    if( rc ) fatal_error("Could not prepare the INSERT statement: %s\n",
                         sqlite3_errmsg(db));
  }
  if( iMode==MODE_UPDATE ){
    rc = sqlite3_prepare_v2(db,
          "INSERT OR IGNORE INTO wordcount(word,cnt) VALUES(?1,0)",
          -1, &pInsert, 0);
    if( rc ) fatal_error("Could not prepare the INSERT statement: %s\n",
                         sqlite3_errmsg(db));
  }
  if( iMode==MODE_REPLACE ){
    rc = sqlite3_prepare_v2(db,
          "REPLACE INTO wordcount(word,cnt)"
          "VALUES(?1,coalesce((SELECT cnt FROM wordcount WHERE word=?1),0)+1)",
          -1, &pInsert, 0);
    if( rc ) fatal_error("Could not prepare the REPLACE statement: %s\n",
                          sqlite3_errmsg(db));
  }
  if( iMode==MODE_DELETE ){
    rc = sqlite3_prepare_v2(db,
          "DELETE FROM wordcount WHERE word=?1",
          -1, &pDelete, 0);
    if( rc ) fatal_error("Could not prepare the DELETE statement: %s\n",
                         sqlite3_errmsg(db));
  }

  /* Process the input file */
  while( fgets(zInput, sizeof(zInput), in) ){
    for(i=0; zInput[i]; i++){
      if( !isalpha(zInput[i]) ) continue;
      for(j=i+1; isalpha(zInput[j]); j++){}

      /* Found a new word at zInput[i] that is j-i bytes long. 
      ** Process it into the wordcount table.  */
      if( iMode==MODE_DELETE ){
        sqlite3_bind_text(pDelete, 1, zInput+i, j-i, SQLITE_STATIC);
        if( sqlite3_step(pDelete)!=SQLITE_DONE ){
          fatal_error("DELETE failed: %s\n", sqlite3_errmsg(db));
        }
        sqlite3_reset(pDelete);
      }else if( iMode==MODE_SELECT ){
        sqlite3_bind_text(pSelect, 1, zInput+i, j-i, SQLITE_STATIC);
        rc = sqlite3_step(pSelect);
        sqlite3_reset(pSelect);
        if( rc==SQLITE_ROW ){
          sqlite3_bind_text(pUpdate, 1, zInput+i, j-i, SQLITE_STATIC);
          if( sqlite3_step(pUpdate)!=SQLITE_DONE ){
            fatal_error("UPDATE failed: %s\n", sqlite3_errmsg(db));
          }
          sqlite3_reset(pUpdate);
        }else if( rc==SQLITE_DONE ){
          sqlite3_bind_text(pInsert, 1, zInput+i, j-i, SQLITE_STATIC);
          if( sqlite3_step(pInsert)!=SQLITE_DONE ){
            fatal_error("Insert failed: %s\n", sqlite3_errmsg(db));
          }
          sqlite3_reset(pInsert);
        }else{
          fatal_error("SELECT failed: %s\n", sqlite3_errmsg(db));
        }
      }else if( iMode==MODE_QUERY ){
        sqlite3_bind_text(pSelect, 1, zInput+i, j-i, SQLITE_STATIC);
        if( sqlite3_step(pSelect)==SQLITE_ROW ){
          sumCnt += sqlite3_column_int64(pSelect, 0);
        }
        sqlite3_reset(pSelect);
      }else{
        sqlite3_bind_text(pInsert, 1, zInput+i, j-i, SQLITE_STATIC);
        if( sqlite3_step(pInsert)!=SQLITE_DONE ){
          fatal_error("INSERT failed: %s\n", sqlite3_errmsg(db));
        }
        sqlite3_reset(pInsert);
        if( iMode==MODE_UPDATE
         || (iMode==MODE_INSERT && sqlite3_changes(db)==0)
        ){
          sqlite3_bind_text(pUpdate, 1, zInput+i, j-i, SQLITE_STATIC);
          if( sqlite3_step(pUpdate)!=SQLITE_DONE ){
            fatal_error("UPDATE failed: %s\n", sqlite3_errmsg(db));
          }
          sqlite3_reset(pUpdate);
        }
      }
      i = j-1;

      /* Increment the operation counter.  Do a COMMIT if it is time. */
      nOp++;
      if( commitInterval>0 && (nOp%commitInterval)==0 ){
        sqlite3_exec(db, "COMMIT; BEGIN IMMEDIATE", 0, 0, 0);
      }
    }
  }
  sqlite3_exec(db, "COMMIT", 0, 0, 0);
  if( zFileToRead ) fclose(in);
  sqlite3_finalize(pInsert);
  sqlite3_finalize(pUpdate);
  sqlite3_finalize(pSelect);
  sqlite3_finalize(pDelete);

  if( iMode==MODE_QUERY ){
    printf("sum of cnt: %lld\n", sumCnt);
    rc = sqlite3_prepare_v2(db,"SELECT sum(cnt*cnt) FROM wordcount", -1,
                            &pSelect, 0);
    if( rc==SQLITE_OK && sqlite3_step(pSelect)==SQLITE_ROW ){
      printf("double-check: %lld\n", sqlite3_column_int64(pSelect, 0));
    }
    sqlite3_finalize(pSelect);
  }


  if( showTimer ){
    sqlite3_int64 elapseTime = realTime() - startTime;
    fprintf(stderr, "%3d.%03d wordcount", (int)(elapseTime/1000),
                                   (int)(elapseTime%1000));
    for(i=1; i<argc; i++) if( i!=showTimer ) fprintf(stderr, " %s", argv[i]);
    fprintf(stderr, "\n");
  }

  if( showSummary ){
    sqlite3_create_function(db, "checksum", -1, SQLITE_UTF8, 0,
                            0, checksumStep, checksumFinalize);
    sqlite3_exec(db, 
      "SELECT 'count(*):  ', count(*) FROM wordcount;\n"
      "SELECT 'sum(cnt):  ', sum(cnt) FROM wordcount;\n"
      "SELECT 'max(cnt):  ', max(cnt) FROM wordcount;\n"
      "SELECT 'avg(cnt):  ', avg(cnt) FROM wordcount;\n"
      "SELECT 'sum(cnt=1):', sum(cnt=1) FROM wordcount;\n"
      "SELECT 'top 10:    ', group_concat(word, ', ') FROM "
         "(SELECT word FROM wordcount ORDER BY cnt DESC, word LIMIT 10);\n"
      "SELECT 'checksum:  ', checksum(word, cnt) FROM "
         "(SELECT word, cnt FROM wordcount ORDER BY word);\n"
      "PRAGMA integrity_check;\n",
      printResult, 0, 0);
  }

  /* Database connection statistics printed after both prepared statements
  ** have been finalized */
  if( showStats ){
    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, 0);
    printf("-- Lookaside Slots Used:        %d (max %d)\n", iCur,iHiwtr);
    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, 0);
    printf("-- Successful lookasides:       %d\n", iHiwtr);
    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur,&iHiwtr,0);
    printf("-- Lookaside size faults:       %d\n", iHiwtr);
    sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur,&iHiwtr,0);
    printf("-- Lookaside OOM faults:        %d\n", iHiwtr);
    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, 0);
    printf("-- Pager Heap Usage:            %d bytes\n", iCur);
    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
    printf("-- Page cache hits:             %d\n", iCur);
    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
    printf("-- Page cache misses:           %d\n", iCur); 
    sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
    printf("-- Page cache writes:           %d\n", iCur); 
    sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, 0);
    printf("-- Schema Heap Usage:           %d bytes\n", iCur); 
    sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, 0);
    printf("-- Statement Heap Usage:        %d bytes\n", iCur); 
  }

  sqlite3_close(db);

  /* Global memory usage statistics printed after the database connection
  ** has closed.  Memory usage should be zero at this point. */
  if( showStats ){
    sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, 0);
    printf("-- Memory Used (bytes):         %d (max %d)\n", iCur,iHiwtr);
    sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, 0);
    printf("-- Outstanding Allocations:     %d (max %d)\n", iCur,iHiwtr);
    sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, 0);
    printf("-- Pcache Overflow Bytes:       %d (max %d)\n", iCur,iHiwtr);
    sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, 0);
    printf("-- Scratch Overflow Bytes:      %d (max %d)\n", iCur,iHiwtr);
    sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, 0);
    printf("-- Largest Allocation:          %d bytes\n",iHiwtr);
    sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, 0);
    printf("-- Largest Pcache Allocation:   %d bytes\n",iHiwtr);
    sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, 0);
    printf("-- Largest Scratch Allocation:  %d bytes\n", iHiwtr);
  }
  return 0;
}
Ejemplo n.º 15
0
svn_error_t *
svn_sqlite__open(svn_sqlite__db_t **db, const char *path,
                 svn_sqlite__mode_t mode, const char * const statements[],
                 int latest_schema, const char * const *upgrade_sql,
                 apr_pool_t *result_pool, apr_pool_t *scratch_pool)
{
  SVN_ERR(svn_atomic__init_once(&sqlite_init_state,
                                init_sqlite, NULL, scratch_pool));

  *db = apr_pcalloc(result_pool, sizeof(**db));

  SVN_ERR(internal_open(&(*db)->db3, path, mode, scratch_pool));

#ifdef SQLITE3_DEBUG
  sqlite3_trace((*db)->db3, sqlite_tracer, (*db)->db3);
#endif
#ifdef SQLITE3_PROFILE
  sqlite3_profile((*db)->db3, sqlite_profiler, (*db)->db3);
#endif

  /* Work around a bug in SQLite 3.7.7.  The bug was fixed in SQLite 3.7.7.1.

     See:

       Date: Sun, 26 Jun 2011 18:52:14 -0400
       From: Richard Hipp <*****@*****.**>
       To: General Discussion of SQLite Database <*****@*****.**>
       Cc: [email protected]
       Subject: Re: [sqlite] PRAGMA bug in 3.7.7 (but fine in 3.7.6.3)
       Message-ID: <*****@*****.**>
   */
  {
    int ignored_err = SQLITE_OK;
#if !SQLITE_VERSION_AT_LEAST(3,7,8) && defined(SQLITE_SCHEMA)
    if (!strcmp(sqlite3_libversion(), "3.7.7"))
      ignored_err = SQLITE_SCHEMA;
#endif

    SVN_ERR(exec_sql2(*db, "PRAGMA case_sensitive_like=1;", ignored_err));
  }

  SVN_ERR(exec_sql(*db,
              /* Disable synchronization to disable the explicit disk flushes
                 that make Sqlite up to 50 times slower; especially on small
                 transactions.

                 This removes some stability guarantees on specific hardware
                 and power failures, but still guarantees atomic commits on
                 application crashes. With our dependency on external data
                 like pristine files (Wc) and revision files (repository),
                 we can't keep up these additional guarantees anyway.

                 ### Maybe switch to NORMAL(1) when we use larger transaction
                     scopes */
              "PRAGMA synchronous=OFF;"
              /* Enable recursive triggers so that a user trigger will fire
                 in the deletion phase of an INSERT OR REPLACE statement.
                 Requires SQLite >= 3.6.18  */
              "PRAGMA recursive_triggers=ON;"));

#if SQLITE_VERSION_AT_LEAST(3,6,19) && defined(SVN_DEBUG)
  /* When running in debug mode, enable the checking of foreign key
     constraints.  This has possible performance implications, so we don't
     bother to do it for production...for now. */
  SVN_ERR(exec_sql(*db, "PRAGMA foreign_keys=ON;"));
#endif

  /* Store temporary tables in RAM instead of in temporary files, but don't
     fail on this if this option is disabled in the sqlite compilation by
     setting SQLITE_TEMP_STORE to 0 (always to disk) */
  svn_error_clear(exec_sql(*db, "PRAGMA temp_store = MEMORY;"));

  /* Validate the schema, upgrading if necessary. */
  if (upgrade_sql != NULL)
    SVN_ERR(check_format(*db, latest_schema, upgrade_sql, scratch_pool));

  /* Store the provided statements. */
  if (statements)
    {
      (*db)->statement_strings = statements;
      (*db)->nbr_statements = 0;
      while (*statements != NULL)
        {
          statements++;
          (*db)->nbr_statements++;
        }
      (*db)->prepared_stmts = apr_pcalloc(result_pool, (*db)->nbr_statements
                                                * sizeof(svn_sqlite__stmt_t *));
    }
  else
    (*db)->nbr_statements = 0;

  (*db)->state_pool = result_pool;
  apr_pool_cleanup_register(result_pool, *db, close_apr, apr_pool_cleanup_null);

  return SVN_NO_ERROR;
}
Ejemplo n.º 16
0
int SQLITE_CDECL main(int argc, char **argv){
  const char *zClient;
  int iClient;
  int n, i;
  int openFlags = SQLITE_OPEN_READWRITE;
  int rc;
  char *zScript;
  int taskId;
  const char *zTrace;
  const char *zCOption;
  const char *zJMode;
  const char *zNRep;
  int nRep = 1, iRep;
  int iTmout = 0;              /* Default: no timeout */
  const char *zTmout;

  g.argv0 = argv[0];
  g.iTrace = 1;
  if( argc<2 ) usage(argv[0]);
  g.zDbFile = argv[1];
  if( strglob("*.test", g.zDbFile) ) usage(argv[0]);
  if( strcmp(sqlite3_sourceid(), SQLITE_SOURCE_ID)!=0 ){
    fprintf(stderr, "SQLite library and header mismatch\n"
                    "Library: %s\n"
                    "Header:  %s\n",
                    sqlite3_sourceid(), SQLITE_SOURCE_ID);
    exit(1);
  }
  n = argc-2;
  sqlite3_snprintf(sizeof(g.zName), g.zName, "%05d.mptest", GETPID());
  zJMode = findOption(argv+2, &n, "journalmode", 1);
  zNRep = findOption(argv+2, &n, "repeat", 1);
  if( zNRep ) nRep = atoi(zNRep);
  if( nRep<1 ) nRep = 1;
  g.zVfs = findOption(argv+2, &n, "vfs", 1);
  zClient = findOption(argv+2, &n, "client", 1);
  g.zErrLog = findOption(argv+2, &n, "errlog", 1);
  g.zLog = findOption(argv+2, &n, "log", 1);
  zTrace = findOption(argv+2, &n, "trace", 1);
  if( zTrace ) g.iTrace = atoi(zTrace);
  if( findOption(argv+2, &n, "quiet", 0)!=0 ) g.iTrace = 0;
  zTmout = findOption(argv+2, &n, "timeout", 1);
  if( zTmout ) iTmout = atoi(zTmout);
  g.bSqlTrace = findOption(argv+2, &n, "sqltrace", 0)!=0;
  g.bSync = findOption(argv+2, &n, "sync", 0)!=0;
  if( g.zErrLog ){
    g.pErrLog = fopen(g.zErrLog, "a");
  }else{
    g.pErrLog = stderr;
  }
  if( g.zLog ){
    g.pLog = fopen(g.zLog, "a");
  }else{
    g.pLog = stdout;
  }
  
  sqlite3_config(SQLITE_CONFIG_LOG, sqlErrorCallback, 0);
  if( zClient ){
    iClient = atoi(zClient);
    if( iClient<1 ) fatalError("illegal client number: %d\n", iClient);
    sqlite3_snprintf(sizeof(g.zName), g.zName, "%05d.client%02d",
                     GETPID(), iClient);
  }else{
    int nTry = 0;
    if( g.iTrace>0 ){
      printf("BEGIN: %s", argv[0]);
      for(i=1; i<argc; i++) printf(" %s", argv[i]);
      printf("\n");
      printf("With SQLite " SQLITE_VERSION " " SQLITE_SOURCE_ID "\n" );
      for(i=0; (zCOption = sqlite3_compileoption_get(i))!=0; i++){
        printf("-DSQLITE_%s\n", zCOption);
      }
      fflush(stdout);
    }
    iClient =  0;
    do{
      if( (nTry%5)==4 ) printf("... %strying to unlink '%s'\n",
                               nTry>5 ? "still " : "", g.zDbFile);
      rc = unlink(g.zDbFile);
      if( rc && errno==ENOENT ) rc = 0;
    }while( rc!=0 && (++nTry)<60 && sqlite3_sleep(1000)>0 );
    if( rc!=0 ){
      fatalError("unable to unlink '%s' after %d attempts\n",
                 g.zDbFile, nTry);
    }
    openFlags |= SQLITE_OPEN_CREATE;
  }
  rc = sqlite3_open_v2(g.zDbFile, &g.db, openFlags, g.zVfs);
  if( rc ) fatalError("cannot open [%s]", g.zDbFile);
  if( iTmout>0 ) sqlite3_busy_timeout(g.db, iTmout);
  
  if( zJMode ){
#if defined(_WIN32)
    if( sqlite3_stricmp(zJMode,"persist")==0
     || sqlite3_stricmp(zJMode,"truncate")==0
    ){
      printf("Changing journal mode to DELETE from %s", zJMode);
      zJMode = "DELETE";
    }
#endif
    runSql("PRAGMA journal_mode=%Q;", zJMode);
  }
  if( !g.bSync ) trySql("PRAGMA synchronous=OFF");
  sqlite3_enable_load_extension(g.db, 1);
  sqlite3_busy_handler(g.db, busyHandler, 0);
  sqlite3_create_function(g.db, "vfsname", 0, SQLITE_UTF8, 0,
                          vfsNameFunc, 0, 0);
  sqlite3_create_function(g.db, "eval", 1, SQLITE_UTF8, 0,
                          evalFunc, 0, 0);
  g.iTimeout = DEFAULT_TIMEOUT;
  if( g.bSqlTrace ) sqlite3_trace(g.db, sqlTraceCallback, 0);
  if( iClient>0 ){
    if( n>0 ) unrecognizedArguments(argv[0], n, argv+2);
    if( g.iTrace ) logMessage("start-client");
    while(1){
      char *zTaskName = 0;
      rc = startScript(iClient, &zScript, &taskId, &zTaskName);
      if( rc==SQLITE_DONE ) break;
      if( g.iTrace ) logMessage("begin %s (%d)", zTaskName, taskId);
      runScript(iClient, taskId, zScript, zTaskName);
      if( g.iTrace ) logMessage("end %s (%d)", zTaskName, taskId);
      finishScript(iClient, taskId, 0);
      sqlite3_free(zTaskName);
      sqlite3_sleep(10);
    }
    if( g.iTrace ) logMessage("end-client");
  }else{
    sqlite3_stmt *pStmt;
    int iTimeout;
    if( n==0 ){
      fatalError("missing script filename");
    }
    if( n>1 ) unrecognizedArguments(argv[0], n, argv+2);
    runSql(
      "DROP TABLE IF EXISTS task;\n"
      "DROP TABLE IF EXISTS counters;\n"
      "DROP TABLE IF EXISTS client;\n"
      "CREATE TABLE task(\n"
      "  id INTEGER PRIMARY KEY,\n"
      "  name TEXT,\n"
      "  client INTEGER,\n"
      "  starttime DATE,\n"
      "  endtime DATE,\n"
      "  script TEXT\n"
      ");"
      "CREATE INDEX task_i1 ON task(client, starttime);\n"
      "CREATE INDEX task_i2 ON task(client, endtime);\n"
      "CREATE TABLE counters(nError,nTest);\n"
      "INSERT INTO counters VALUES(0,0);\n"
      "CREATE TABLE client(id INTEGER PRIMARY KEY, wantHalt);\n"
    );
    zScript = readFile(argv[2]);
    for(iRep=1; iRep<=nRep; iRep++){
      if( g.iTrace ) logMessage("begin script [%s] cycle %d\n", argv[2], iRep);
      runScript(0, 0, zScript, argv[2]);
      if( g.iTrace ) logMessage("end script [%s] cycle %d\n", argv[2], iRep);
    }
    sqlite3_free(zScript);
    waitForClient(0, 2000, "during shutdown...\n");
    trySql("UPDATE client SET wantHalt=1");
    sqlite3_sleep(10);
    g.iTimeout = 0;
    iTimeout = 1000;
    while( ((rc = trySql("SELECT 1 FROM client"))==SQLITE_BUSY
        || rc==SQLITE_ROW) && iTimeout>0 ){
      sqlite3_sleep(10);
      iTimeout -= 10;
    }
    sqlite3_sleep(100);
    pStmt = prepareSql("SELECT nError, nTest FROM counters");
    iTimeout = 1000;
    while( (rc = sqlite3_step(pStmt))==SQLITE_BUSY && iTimeout>0 ){
      sqlite3_sleep(10);
      iTimeout -= 10;
    }
    if( rc==SQLITE_ROW ){
      g.nError += sqlite3_column_int(pStmt, 0);
      g.nTest += sqlite3_column_int(pStmt, 1);
    }
    sqlite3_finalize(pStmt);
  }
  sqlite3_close(g.db);
  maybeClose(g.pLog);
  maybeClose(g.pErrLog);
  if( iClient==0 ){
    printf("Summary: %d errors out of %d tests\n", g.nError, g.nTest);
    printf("END: %s", argv[0]);
    for(i=1; i<argc; i++) printf(" %s", argv[i]);
    printf("\n");
  }
  return g.nError>0;
}
Ejemplo n.º 17
0
int proxy_db_open(pool *p, const char *table_path, const char *schema_name) {
  int res;
  pool *tmp_pool;
  const char *stmt;

  if (p == NULL ||
      table_path == NULL) {
    errno = EINVAL;
    return -1;
  }

  /* If we already have a database handle open, then attach the given
   * path to our handle.  Otherwise, open/create the database file first.
   */

  if (proxy_dbh == NULL) {
    res = sqlite3_open(table_path, &proxy_dbh);
    if (res != SQLITE_OK) {
      pr_log_debug(DEBUG0, MOD_PROXY_VERSION
        ": error opening SQLite database '%s': %s", table_path,
        sqlite3_errmsg(proxy_dbh));
      errno = EPERM;
      return -1;
    }

    /* Tell SQLite to only use in-memory journals.  This is necessary for
     * working properly when a chroot is used.  Note that the MEMORY journal
     * mode of SQLite is supported only for SQLite-3.6.5 and later.
     */
    res = sqlite3_exec(proxy_dbh, "PRAGMA journal_mode = MEMORY;", NULL, NULL,
      NULL);
    if (res != SQLITE_OK) {
      pr_trace_msg(trace_channel, 2,
        "error setting MEMORY journal mode on SQLite database '%s': %s",
        table_path, sqlite3_errmsg(proxy_dbh));
    }

    if (pr_trace_get_level(trace_channel) >= PROXY_DB_SQLITE_TRACE_LEVEL) {
      sqlite3_trace(proxy_dbh, db_trace, NULL);
    }

    prepared_stmts = pr_table_nalloc(db_pool, 0, 4);
  }

  tmp_pool = make_sub_pool(p);

  stmt = pstrcat(tmp_pool, "ATTACH DATABASE '", table_path, "' AS ",
    schema_name, ";", NULL);
  res = sqlite3_exec(proxy_dbh, stmt, NULL, NULL, NULL);
  if (res != SQLITE_OK) {
    pr_trace_msg(trace_channel, 2,
      "error attaching database '%s' (as '%s') to existing SQLite handle "
      "using '%s': %s", table_path, schema_name, stmt,
      sqlite3_errmsg(proxy_dbh));
    destroy_pool(tmp_pool);
    errno = EPERM;
    return -1;
  }

  destroy_pool(tmp_pool);
  return 0;
}
Ejemplo n.º 18
0
DLL_FUNCTION(void*) BU_SQLite_Trace(sqlite3* db,
								   void(*xTrace)(void*, const char*),
								   void* param) {
#pragma comment(linker, "/EXPORT:BU_SQLite_Trace=_BU_SQLite_Trace@12")
	return sqlite3_trace(db, xTrace, param);
}
Ejemplo n.º 19
0
svn_error_t *
svn_sqlite__open(svn_sqlite__db_t **db, const char *path,
                 svn_sqlite__mode_t mode, const char * const statements[],
                 int unused1, const char * const *unused2,
                 apr_int32_t timeout,
                 apr_pool_t *result_pool, apr_pool_t *scratch_pool)
{
  SVN_ERR(svn_atomic__init_once(&sqlite_init_state,
                                init_sqlite, NULL, scratch_pool));

  *db = apr_pcalloc(result_pool, sizeof(**db));

  SVN_ERR(internal_open(*db, path, mode, timeout, scratch_pool));

#if SQLITE_VERSION_NUMBER >= 3008000 && SQLITE_VERSION_NUMBER < 3009000
  /* disable SQLITE_ENABLE_STAT3/4 from 3.8.1 - 3.8.3 (but not 3.8.3.1+)
   * to prevent using it when it's buggy.
   * See: https://www.sqlite.org/src/info/4c86b126f2 */
  if (sqlite3_libversion_number() > 3008000 &&
      sqlite3_libversion_number() < 3008004 &&
      strcmp(sqlite3_sourceid(),"2014-02-11")<0)
    {
      sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, (*db)->db3, 0x800);
    }
#endif

#ifdef SVN_UNICODE_NORMALIZATION_FIXES
  /* Create extension buffers with space for 200 UCS-4 characters. */
  svn_membuf__create(&(*db)->sqlext_buf1, 800, result_pool);
  svn_membuf__create(&(*db)->sqlext_buf2, 800, result_pool);
  svn_membuf__create(&(*db)->sqlext_buf3, 800, result_pool);

  /* Register collation and LIKE and GLOB operator replacements. */
  SQLITE_ERR_CLOSE(sqlite3_create_collation((*db)->db3,
                                            "svn-ucs-nfd", SQLITE_UTF8,
                                            *db, collate_ucs_nfd),
                   db, scratch_pool);
  /* ### Is it really necessary to override these functions?
         I would assume the default implementation to be collation agnostic?
         And otherwise our implementation should be...

         The default implementation is in some cases index backed, while our
         implementation can't be. With an index based on the collation it could
         be. */
  SQLITE_ERR_CLOSE(sqlite3_create_function((*db)->db3, "glob", 2,
                                           SQLITE_UTF8 | SQLITE_DETERMINISTIC,
                                           *db, glob_ucs_nfd, NULL, NULL),
                   db, scratch_pool);
  SQLITE_ERR_CLOSE(sqlite3_create_function((*db)->db3, "like", 2,
                                           SQLITE_UTF8 | SQLITE_DETERMINISTIC,
                                           *db, like_ucs_nfd, NULL, NULL),
                   db, scratch_pool);
  SQLITE_ERR_CLOSE(sqlite3_create_function((*db)->db3, "like", 3,
                                           SQLITE_UTF8 | SQLITE_DETERMINISTIC,
                                           *db, like_ucs_nfd, NULL, NULL),
                   db, scratch_pool);
#endif /* SVN_UNICODE_NORMALIZATION_FIXES */

#ifdef SQLITE3_DEBUG
  sqlite3_trace((*db)->db3, sqlite_tracer, (*db)->db3);
#endif
#ifdef SQLITE3_PROFILE
  sqlite3_profile((*db)->db3, sqlite_profiler, (*db)->db3);
#endif

  SVN_ERR_CLOSE(exec_sql(*db,
              /* The default behavior of the LIKE operator is to ignore case
                 for ASCII characters. Hence, by default 'a' LIKE 'A' is true.
                 The case_sensitive_like pragma installs a new application-
                 defined LIKE function that is either case sensitive or
                 insensitive depending on the value of the case_sensitive_like
                 pragma. */
              "PRAGMA case_sensitive_like=1;"
              /* Disable synchronization to disable the explicit disk flushes
                 that make Sqlite up to 50 times slower; especially on small
                 transactions.

                 This removes some stability guarantees on specific hardware
                 and power failures, but still guarantees atomic commits on
                 application crashes. With our dependency on external data
                 like pristine files (Wc) and revision files (repository),
                 we can't keep up these additional guarantees anyway.

                 ### Maybe switch to NORMAL(1) when we use larger transaction
                     scopes */
              "PRAGMA synchronous=OFF;"
              /* Enable recursive triggers so that a user trigger will fire
                 in the deletion phase of an INSERT OR REPLACE statement.
                 Requires SQLite >= 3.6.18  */
              "PRAGMA recursive_triggers=ON;"
              /* Enforce current Sqlite default behavior. Some distributions
                 might change the Sqlite defaults without realizing how this
                 affects application(read: Subversion) performance/behavior. */
              "PRAGMA foreign_keys=OFF;"      /* SQLITE_DEFAULT_FOREIGN_KEYS*/
              "PRAGMA locking_mode = NORMAL;" /* SQLITE_DEFAULT_LOCKING_MODE */
              /* Testing shows TRUNCATE is faster than DELETE on Windows. */
              "PRAGMA journal_mode = TRUNCATE;"
              ),
                *db);

#if defined(SVN_DEBUG)
  /* When running in debug mode, enable the checking of foreign key
     constraints.  This has possible performance implications, so we don't
     bother to do it for production...for now. */
  SVN_ERR_CLOSE(exec_sql(*db, "PRAGMA foreign_keys=ON;"),
                *db);
#endif

#ifdef SVN_SQLITE_REVERSE_UNORDERED_SELECTS
  /* When enabled, this PRAGMA causes SELECT statements without an ORDER BY
     clause to emit their results in the reverse order of what they normally
     would.  This can help detecting invalid assumptions about the result
     order.*/
  SVN_ERR_CLOSE(exec_sql(*db, "PRAGMA reverse_unordered_selects=ON;"),
                *db);
#endif

  /* Store temporary tables in RAM instead of in temporary files, but don't
     fail on this if this option is disabled in the sqlite compilation by
     setting SQLITE_TEMP_STORE to 0 (always to disk) */
  svn_error_clear(exec_sql(*db, "PRAGMA temp_store = MEMORY;"));

  /* Store the provided statements. */
  if (statements)
    {
      (*db)->statement_strings = statements;
      (*db)->nbr_statements = 0;
      while (*statements != NULL)
        {
          statements++;
          (*db)->nbr_statements++;
        }

      (*db)->prepared_stmts = apr_pcalloc(
                                  result_pool,
                                  ((*db)->nbr_statements + STMT_INTERNAL_LAST)
                                                * sizeof(svn_sqlite__stmt_t *));
    }
  else
    {
      (*db)->nbr_statements = 0;
      (*db)->prepared_stmts = apr_pcalloc(result_pool,
                                          (0 + STMT_INTERNAL_LAST)
                                                * sizeof(svn_sqlite__stmt_t *));
    }

  (*db)->state_pool = result_pool;
  apr_pool_cleanup_register(result_pool, *db, close_apr, apr_pool_cleanup_null);

  return SVN_NO_ERROR;
}
/* public native void enableSqlTracing(); */
static void enableSqlTracing(JNIEnv* env, jobject object, jstring databaseName, jshort connType)
{
    sqlite3 * handle = (sqlite3 *)env->GetIntField(object, offset_db_handle);
    sqlite3_trace(handle, &sqlTrace, (void *)getDatabaseName(env, handle, databaseName, connType));
}
Ejemplo n.º 21
0
int sqlite_test()
{
  const char *zClient;
  int iClient;
  int n, i;
  int openFlags = SQLITE_OPEN_READWRITE;
  int rc;
  char *zScript;
  int taskId;
  const char *zTrace;
  const char *zCOption;

  g.argv0 = argv[0];
  g.iTrace = 1;
  if( argc<2 ) usage(argv[0]);
  g.zDbFile = argv[1];
  if( strglob("*.test", g.zDbFile) ) usage(argv[0]);
  if( strcmp(sqlite3_sourceid(), SQLITE_SOURCE_ID)!=0 ){
    fprintf(stderr, "SQLite library and header mismatch\n"
                    "Library: %s\n"
                    "Header:  %s\n",
                    sqlite3_sourceid(), SQLITE_SOURCE_ID);
    exit(1);
  }
  n = argc-2;
  sqlite3_snprintf(sizeof(g.zName), g.zName, "%05d.mptest", GETPID());
  g.zVfs = findOption(argv+2, &n, "vfs", 1);
  zClient = findOption(argv+2, &n, "client", 1);
  g.zErrLog = findOption(argv+2, &n, "errlog", 1);
  g.zLog = findOption(argv+2, &n, "log", 1);
  zTrace = findOption(argv+2, &n, "trace", 1);
  if( zTrace ) g.iTrace = atoi(zTrace);
  if( findOption(argv+2, &n, "quiet", 0)!=0 ) g.iTrace = 0;
  g.bSqlTrace = findOption(argv+2, &n, "sqltrace", 0)!=0;
  g.bSync = findOption(argv+2, &n, "sync", 0)!=0;
  if( g.zErrLog ){
    g.pErrLog = fopen(g.zErrLog, "a");
  }else{
    g.pErrLog = stderr;
  }
  if( g.zLog ){
    g.pLog = fopen(g.zLog, "a");
  }else{
    g.pLog = stdout;
  }
  
  sqlite3_config(SQLITE_CONFIG_LOG, sqlErrorCallback, 0);
  if( zClient ){
    iClient = atoi(zClient);
    if( iClient<1 ) fatalError("illegal client number: %d\n", iClient);
    sqlite3_snprintf(sizeof(g.zName), g.zName, "%05d.client%02d",
                     GETPID(), iClient);
  }else{
    if( g.iTrace>0 ){
      printf("With SQLite " SQLITE_VERSION " " SQLITE_SOURCE_ID "\n" );
      for(i=0; (zCOption = sqlite3_compileoption_get(i))!=0; i++){
        printf("-DSQLITE_%s\n", zCOption);
      }
      fflush(stdout);
    }
    iClient =  0;
    unlink(g.zDbFile);
    openFlags |= SQLITE_OPEN_CREATE;
  }
  rc = sqlite3_open_v2(g.zDbFile, &g.db, openFlags, g.zVfs);
  if( rc ) fatalError("cannot open [%s]", g.zDbFile);
  sqlite3_enable_load_extension(g.db, 1);
  sqlite3_busy_handler(g.db, busyHandler, 0);
  sqlite3_create_function(g.db, "vfsname", 0, SQLITE_UTF8, 0,
                          vfsNameFunc, 0, 0);
  sqlite3_create_function(g.db, "eval", 1, SQLITE_UTF8, 0,
                          evalFunc, 0, 0);
  g.iTimeout = DEFAULT_TIMEOUT;
  if( g.bSqlTrace ) sqlite3_trace(g.db, sqlTraceCallback, 0);
  if( !g.bSync ) trySql("PRAGMA synchronous=OFF");
  if( iClient>0 ){
    if( n>0 ) unrecognizedArguments(argv[0], n, argv+2);
    if( g.iTrace ) logMessage("start-client");
    while(1){
      char *zTaskName = 0;
      rc = startScript(iClient, &zScript, &taskId, &zTaskName);
      if( rc==SQLITE_DONE ) break;
      if( g.iTrace ) logMessage("begin %s (%d)", zTaskName, taskId);
      runScript(iClient, taskId, zScript, zTaskName);
      if( g.iTrace ) logMessage("end %s (%d)", zTaskName, taskId);
      finishScript(iClient, taskId, 0);
      sqlite3_free(zTaskName);
      sqlite3_sleep(10);
    }
    if( g.iTrace ) logMessage("end-client");
  }else{
    sqlite3_stmt *pStmt;
    int iTimeout;
    if( n==0 ){
      fatalError("missing script filename");
    }
    if( n>1 ) unrecognizedArguments(argv[0], n, argv+2);
    runSql(
      "CREATE TABLE task(\n"
      "  id INTEGER PRIMARY KEY,\n"
      "  name TEXT,\n"
      "  client INTEGER,\n"
      "  starttime DATE,\n"
      "  endtime DATE,\n"
      "  script TEXT\n"
      ");"
      "CREATE INDEX task_i1 ON task(client, starttime);\n"
      "CREATE INDEX task_i2 ON task(client, endtime);\n"
      "CREATE TABLE counters(nError,nTest);\n"
      "INSERT INTO counters VALUES(0,0);\n"
      "CREATE TABLE client(id INTEGER PRIMARY KEY, wantHalt);\n"
    );
    zScript = readFile(argv[2]);
    if( g.iTrace ) logMessage("begin script [%s]\n", argv[2]);
    runScript(0, 0, zScript, argv[2]);
    sqlite3_free(zScript);
    if( g.iTrace ) logMessage("end script [%s]\n", argv[2]);
    waitForClient(0, 2000, "during shutdown...\n");
    trySql("UPDATE client SET wantHalt=1");
    sqlite3_sleep(10);
    g.iTimeout = 0;
    iTimeout = 1000;
    while( ((rc = trySql("SELECT 1 FROM client"))==SQLITE_BUSY
        || rc==SQLITE_ROW) && iTimeout>0 ){
      sqlite3_sleep(10);
      iTimeout -= 10;
    }
    sqlite3_sleep(100);
    pStmt = prepareSql("SELECT nError, nTest FROM counters");
    iTimeout = 1000;
    while( (rc = sqlite3_step(pStmt))==SQLITE_BUSY && iTimeout>0 ){
      sqlite3_sleep(10);
      iTimeout -= 10;
    }
    if( rc==SQLITE_ROW ){
      g.nError += sqlite3_column_int(pStmt, 0);
      g.nTest += sqlite3_column_int(pStmt, 1);
    }
    sqlite3_finalize(pStmt);
  }
  sqlite3_close(g.db);  
  maybeClose(g.pLog);
  maybeClose(g.pErrLog);
  if( iClient==0 ){
    printf("Summary: %d errors in %d tests\n", g.nError, g.nTest);
  }
  return g.nError>0;
}
Ejemplo n.º 22
0
static void createDatabase()
{
    sqlite3 *sqlite;
    int dotrans = 0;
    int accountsnb = 0;
    int i, nrows, ncols;
    char **rows;

    if (sqlite3_open(dbname, &sqlite) != SQLITE_OK) {
        fprintf(stderr, "unable to connect to %s\n", dbname);
	exit(1);
    }
#ifdef TRACE_DBINIT
    sqlite3_trace(sqlite, dbtrace, NULL);
#endif
    if (sqlite3_exec(sqlite, begtrans, NULL, NULL, NULL)
	== SQLITE_OK) {
        dotrans = 1;
    }
    if (sqlite3_get_table(sqlite, "SELECT count(*) FROM accounts",
			  &rows, &ncols, &nrows, NULL)
	== SQLITE_OK) {
        if (rows && ncols == 1 && nrows == 1 && rows[1]) {
	    accountsnb = strtol(rows[1], NULL, 0);
	}
	if (rows) {
	    sqlite3_free_table(rows);
	}
	if (dotrans) {
	    sqlite3_exec(sqlite, "COMMIT TRANSACTION", NULL, NULL, NULL);
	}
	if (accountsnb == naccounts * tps) {
            fprintf(stdout, "Already initialized\n");
	    fflush(stdout);
	    sqlite3_close(sqlite);
	    return;
        }
    }
    fprintf(stdout, "Drop old tables if they exist\n");
    fflush(stdout);
    if (sqlite3_exec(sqlite, "DROP TABLE history; "
		     "DROP TABLE accounts; "
		     "DROP TABLE tellers; "
		     "DROP TABLE branches; ", NULL, NULL, NULL)
	== SQLITE_OK) {
	if (dotrans) {
	    sqlite3_exec(sqlite, combegtrans, NULL, NULL, NULL);
	}
    }
    fprintf(stdout, "Create tables\n");
    fflush(stdout);
    sqlite3_exec(sqlite, "CREATE TABLE branches ("
		 "Bid INTEGER NOT NULL PRIMARY KEY, "
		 "Bbalance INTEGER, "
		 "filler CHAR(88))", NULL, NULL, NULL);
    sqlite3_exec(sqlite, "CREATE TABLE tellers ("
		 "Tid INTEGER NOT NULL PRIMARY KEY, "
		 "Bid INTEGER, "
		 "Tbalance INTEGER, "
		 "filler CHAR(84))", NULL, NULL, NULL);
    sqlite3_exec(sqlite, "CREATE TABLE accounts ("
		 "Aid INTEGER NOT NULL PRIMARY KEY, "
		 "Bid INTEGER, "
		 "Abalance INTEGER, "
		 "filler CHAR(84))", NULL, NULL, NULL);
    sqlite3_exec(sqlite, "CREATE TABLE history ("
		 "Tid INTEGER, "
		 "Bid INTEGER, "
		 "Aid INTEGER, "
		 "delta INTEGER, "
		 "tstime TIMESTAMP, "
		 "filler CHAR(22))", NULL, NULL, NULL);
    fprintf(stdout, "Delete elements in table in case DROP didn't work\n");
    fflush(stdout);
    sqlite3_exec(sqlite, "DELETE FROM history; "
		 "DELETE FROM accounts; "
		 "DELETE FROM tellers; "
		 "DELETE FROM branches ", NULL, NULL, NULL);
    if (dotrans) {
        sqlite3_exec(sqlite, combegtrans, NULL, NULL, NULL);
    }
    fprintf(stdout, "Insert data in branches table\n");
    fflush(stdout);
    for (i = 0; i < nbranches * tps; i++) {
        char *sql = sqlite3_mprintf("INSERT INTO branches(Bid,Bbalance) "
				    "VALUES (%d,0)", i);

        sqlite3_exec(sqlite, sql, NULL, NULL, NULL);
	sqlite3_free(sql);
	if (i % 100 == 0 && dotrans) {
	    sqlite3_exec(sqlite, combegtrans, NULL, NULL, NULL);
	}
    }
    if (dotrans) {
        sqlite3_exec(sqlite, combegtrans, NULL, NULL, NULL);
    }
    fprintf(stdout, "Insert data in tellers table\n");
    fflush(stdout);
    for (i = 0; i < ntellers * tps; i++) {
        char *sql = sqlite3_mprintf("INSERT INTO tellers(Tid,Bid,Tbalance) "
				    "VALUES (%d,%d,0)",
				    i, i / ntellers);

        sqlite3_exec(sqlite, sql, NULL, NULL, NULL);
	sqlite3_free(sql);
	if (i % 100 == 0 && dotrans) {
	    sqlite3_exec(sqlite, combegtrans, NULL, NULL, NULL);
	}
    }
    if (dotrans) {
        sqlite3_exec(sqlite, combegtrans, NULL, NULL, NULL);
    }
    fprintf(stdout, "Insert data in accounts table\n");
    fflush(stdout);
    for (i = 0; i < naccounts * tps; i++) {
        char *sql = sqlite3_mprintf("INSERT INTO accounts(Aid,Bid,Abalance) "
				    "VALUES (%d,%d,0)",
				    i, i / naccounts);

        sqlite3_exec(sqlite, sql, NULL, NULL, NULL);
	sqlite3_free(sql);
	if (i % 10000 == 0 && dotrans) {
	    sqlite3_exec(sqlite, combegtrans, NULL, NULL, NULL);
	}
	if (i > 0 && i % 10000 == 0) {
	    fprintf(stdout,"\t%d\trecords inserted\n", i);
	    fflush(stdout);
	}
    }
    if (dotrans) {
        sqlite3_exec(sqlite, "COMMIT TRANSACTION", NULL, NULL, NULL);
    }
    fprintf(stdout, "\t%d\trecords inserted\n", naccounts * tps);
    fflush(stdout);
    sqlite3_close(sqlite);
}
Ejemplo n.º 23
0
svn_error_t *
svn_sqlite__open(svn_sqlite__db_t **db, const char *path,
                 svn_sqlite__mode_t mode, const char * const statements[],
                 int latest_schema, const char * const *upgrade_sql,
                 apr_pool_t *result_pool, apr_pool_t *scratch_pool)
{
  SVN_ERR(svn_atomic__init_once(&sqlite_init_state,
                                init_sqlite, NULL, scratch_pool));

  *db = apr_palloc(result_pool, sizeof(**db));

#if SQLITE_VERSION_AT_LEAST(3,5,0)
  {
    int flags;

    if (mode == svn_sqlite__mode_readonly)
      flags = SQLITE_OPEN_READONLY;
    else if (mode == svn_sqlite__mode_readwrite)
      flags = SQLITE_OPEN_READWRITE;
    else if (mode == svn_sqlite__mode_rwcreate)
      flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
    else
      SVN_ERR_MALFUNCTION();

    /* If this flag is defined (3.6.x), then let's turn off SQLite's mutexes.
       All svn objects are single-threaded, so we can already guarantee that
       our use of the SQLite handle will be serialized properly.
       Note: in 3.6.x, we've already config'd SQLite into MULTITHREAD mode,
       so this is probably redundant... */
    /* ### yeah. remove when autoconf magic is done for init/config. */
#ifdef SQLITE_OPEN_NOMUTEX
    flags |= SQLITE_OPEN_NOMUTEX;
#endif

    /* Open the database. Note that a handle is returned, even when an error
       occurs (except for out-of-memory); thus, we can safely use it to
       extract an error message and construct an svn_error_t. */
    SQLITE_ERR(sqlite3_open_v2(path, &(*db)->db3, flags, NULL), *db);
  }
#else
  /* Older versions of SQLite (pre-3.5.x) will always create the database
     if it doesn't exist.  So, if we are asked to be read-only or read-write,
     we ensure the database already exists - if it doesn't, then we will
     explicitly error out before asking SQLite to do anything.

     Pre-3.5.x SQLite versions also don't support read-only ops either.
   */
  if (mode == svn_sqlite__mode_readonly || mode == svn_sqlite__mode_readwrite)
    {
      svn_node_kind_t kind;
      SVN_ERR(svn_io_check_path(path, &kind, scratch_pool));
      if (kind != svn_node_file) {
          return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
                                   _("Expected SQLite database not found: %s"),
                                   svn_path_local_style(path, scratch_pool));
      }
    }
  else if (mode == svn_sqlite__mode_rwcreate)
    {
      /* do nothing - older SQLite's will create automatically. */
    }
  else
    SVN_ERR_MALFUNCTION();

  SQLITE_ERR(sqlite3_open(path, &(*db)->db3), *db);
#endif

  /* Retry until timeout when database is busy. */
  SQLITE_ERR(sqlite3_busy_timeout((*db)->db3, BUSY_TIMEOUT), *db);
#ifdef SQLITE3_DEBUG
  sqlite3_trace((*db)->db3, sqlite_tracer, (*db)->db3);
#endif

  SVN_ERR(svn_sqlite__exec(*db, "PRAGMA case_sensitive_like=on;"));

  /* Validate the schema, upgrading if necessary. */
  SVN_ERR(check_format(*db, latest_schema, upgrade_sql, scratch_pool));

  /* Store the provided statements. */
  if (statements)
    {
      (*db)->statement_strings = statements;
      (*db)->nbr_statements = 0;
      while (*statements != NULL)
        {
          statements++;
          (*db)->nbr_statements++;
        }
      (*db)->prepared_stmts = apr_pcalloc(result_pool, (*db)->nbr_statements
                                                * sizeof(svn_sqlite__stmt_t *));
    }
  else
    (*db)->nbr_statements = 0;

  (*db)->result_pool = result_pool;
  apr_pool_cleanup_register(result_pool, *db, close_apr, apr_pool_cleanup_null);

  return SVN_NO_ERROR;
}