/* mozIStorageConnection openUnsharedDatabase(in nsIFile aDatabaseFile); */
NS_IMETHODIMP
mozStorageService::OpenUnsharedDatabase(nsIFile *aDatabaseFile, mozIStorageConnection **_retval)
{
    nsRefPtr<mozStorageConnection> msc = new mozStorageConnection(this);
    if (!msc)
        return NS_ERROR_OUT_OF_MEMORY;

    // Initialize the connection, temporarily turning off shared caches so the
    // new connection gets its own cache.  Database connections are assigned
    // caches when they are opened, and they retain those caches for their
    // lifetimes, unaffected by changes to the shared caches setting, so we can
    // disable shared caches temporarily while we initialize the new connection
    // without affecting the caches currently in use by other connections.
    nsresult rv;
    {
        nsAutoLock lock(mLock);
        int rc = sqlite3_enable_shared_cache(0);
        if (rc != SQLITE_OK)
            return ConvertResultCode(rc);

        rv = msc->Initialize(aDatabaseFile);

        rc = sqlite3_enable_shared_cache(1);
        if (rc != SQLITE_OK)
            return ConvertResultCode(rc);
    }
    NS_ENSURE_SUCCESS(rv, rv);

    NS_ADDREF(*_retval = msc);
    return NS_OK;
}
Beispiel #2
0
    void DbConn::Open()
    {
      ++m_nCounter;
      if (m_nCounter > 1)
      {
        return;
      }

      STAFF_ASSERT(m_pDb == NULL, "Staff database is already opened");
      sqlite3_enable_shared_cache(1);

      // open db
      int nResult = sqlite3_open((Runtime::Inst().GetStaffHome() + "/db/staff.db").c_str(), &m_pDb);
      STAFF_ASSERT(nResult == SQLITE_OK, "Failed to open staff database");

      sqlite3_stmt* pVm = NULL;

      nResult = sqlite3_prepare_v2(m_pDb, "PRAGMA foreign_keys = ON;", -1, &pVm, NULL);
      STAFF_ASSERT(nResult == SQLITE_OK, sqlite3_errmsg(m_pDb));

      try
      {
        STAFF_ASSERT(sqlite3_step(pVm) == SQLITE_DONE, "Failed to enable foreign keys: "
                     + std::string(sqlite3_errmsg(m_pDb)));
      }
      catch(...)
      {
        sqlite3_finalize(pVm);
        throw;
      }

      STAFF_ASSERT(sqlite3_finalize(pVm) == SQLITE_OK, sqlite3_errmsg(m_pDb));
    }
Beispiel #3
0
    sqlite_connection (const std::string& file)
        : db_(0)
    {
        spatialite_init (0);

        // sqlite3_open_v2 is available earlier but 
        // shared cache not available until >= 3.6.18
        #if SQLITE_VERSION_NUMBER >= 3006018
        int rc = sqlite3_enable_shared_cache(1);
        if (rc != SQLITE_OK)
        {
           throw mapnik::datasource_exception (sqlite3_errmsg (db_));
        }
        
        int mode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_SHAREDCACHE;
        if (sqlite3_open_v2 (file.c_str(), &db_, mode, NULL))
        #else
        #warning "Mapnik's sqlite plugin is compiling against an version of sqlite older than 3.6.18 which may make rendering slow..."
        if (sqlite3_open (file.c_str(), &db_))
        #endif
        {
            std::ostringstream s;
            s << "Spatialite Plugin: ";
            throw mapnik::datasource_exception (sqlite3_errmsg (db_));
        }
        //sqlite3_enable_load_extension(db_, 1);
    }
Beispiel #4
0
int CSQLite::Open(LPCTSTR lpszFileName)
{
	int nRtVal;

#ifdef UNICODE
	char szFileNameA[MAX_PATH];
	WideCharToMultiByte(	CP_ACP,
							0,
							lpszFileName,
							-1,
							szFileNameA,
							MAX_PATH,
							NULL,
							NULL	);
	nRtVal = sqlite3_open(szFileNameA, &m_pDb);
#else
	nRtVal = sqlite3_open(lpszFileName, &m_pDb);
#endif

	sqlite3_busy_timeout(m_pDb, 60000);
	sqlite3_enable_shared_cache(1);

	sqlite3_exec(m_pDb, "PRAGMA journal_mode=OFF;", NULL, NULL, NULL);
	sqlite3_exec(m_pDb, "PRAGMA synchronous=OFF;", NULL, NULL, NULL);

	return nRtVal;
}
void SqliteFinalize(TPerfTestMode aMode)
	{
	if(aMode == EPerfTestSqliteSqlMode)
		{
		(void)sqlite3_enable_shared_cache(0);
		sqlite3_soft_heap_limit(0);
		}
	sqlite3_shutdown();
	}
Beispiel #6
0
void SqDriver::Shutdown()
{
	if (m_pOpenLock)
	{
		m_pOpenLock->DestroyThis();
	}

	if (m_bThreadSafe)
	{
		sqlite3_enable_shared_cache(0);
	}
}
Beispiel #7
0
 sqlite_connection (const std::string& file)
     : db_(0)
 {
     sqlite3_enable_shared_cache(1);
     if (sqlite3_open_v2 (file.c_str(), &db_, SQLITE_OPEN_NOMUTEX|SQLITE_OPEN_SHAREDCACHE, 0))
     {
         std::ostringstream s;
         s << "Sqlite Plugin: ";
         throw mapnik::datasource_exception (sqlite3_errmsg (db_));
     }
     //sqlite3_enable_load_extension(db_, 1);
 }
SWIGEXPORT jint JNICALL Java_com_almworks_sqlite4java__1SQLiteSwiggedJNI_sqlite3_1enable_1shared_1cache(JNIEnv *jenv, jclass jcls, jint jarg1) {
  jint jresult = 0 ;
  int arg1 ;
  int result;
  
  (void)jenv;
  (void)jcls;
  arg1 = (int)jarg1; 
  result = (int)sqlite3_enable_shared_cache(arg1);
  jresult = (jint)result; 
  return jresult;
}
Beispiel #9
0
RmSwapTable *rm_swap_table_open(gboolean in_memory, GError **error) {
    RmSwapTable *self = NULL;

    char *path = NULL;

    if(in_memory) {
        path = g_strdup(":memory:");
    } else {
        char pid[20] = {0};
        memset(pid, 0, sizeof(pid));

        g_snprintf(pid, sizeof(pid), "%d", getpid());
        path = g_build_filename(g_get_user_cache_dir(), "rmlint", pid, NULL);

        /* Make sure that path actually exists */
        rm_swap_table_create_cachedir(error);
    }

    /* Might happen if no tmp file could be created */
    if(error && *error) {
        goto cleanup;
    }

    /* We do locking ourselves */
    sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);

    sqlite3 *handle = NULL;
    if(sqlite3_open(path, &handle) != SQLITE_OK) {
        SET_ERROR("Cannot open swap table db");
        goto cleanup;
    }

    /* Finetune sqlite (quite slow without these) */
    sqlite3_extended_result_codes(handle, TRUE);
    sqlite3_exec(handle, "PRAGMA cache_size = 8000;", 0, 0, 0);
    sqlite3_exec(handle, "PRAGMA synchronous = OFF;", 0, 0, 0);
    sqlite3_exec(handle, "PRAGMA journal_mode = MEMORY;", 0, 0, 0);
    sqlite3_enable_shared_cache(TRUE);

    size_t path_len = strlen(path) + 1;
    self = g_malloc(sizeof(RmSwapTable) + path_len);
    self->cache = handle;
    self->attrs = g_ptr_array_new();
    self->transaction_running = FALSE;
    strncpy(self->path, path, path_len);
    g_mutex_init(&self->mtx);

cleanup:
    g_free(path);
    return self;
}
void SqliteInitialize(TPerfTestMode aMode)
	{
	if(aMode == EPerfTestSqliteSqlMode)
		{
		const TInt KSqliteLookAsideCellSize = 128;
		const TInt KSqliteLookAsideCellCount = 512;
		int err;
		err = sqlite3_config(SQLITE_CONFIG_LOOKASIDE, KSqliteLookAsideCellSize, KSqliteLookAsideCellCount);
		TEST2(err, SQLITE_OK);
		sqlite3_soft_heap_limit(1024 * 1024);
		err = sqlite3_enable_shared_cache(1);
		TEST2(err, SQLITE_OK);
		}
	}
Beispiel #11
0
FsckDB::FsckDB(const std::string& databasePath)
{
   this->log.setContext("FsckDB");

   // add an additional subdir beegfs-fsck to database path
   this->databasePath = databasePath;

   int sqlRes = sqlite3_enable_shared_cache(true);

   if (sqlRes != SQLITE_OK)
      log.log(Log_WARNING, "Unable to enable shared cache mode for SQLite.");

   this->dbHandlePool = new DBHandlePool(databasePath);
}
Beispiel #12
0
static void vacuum1(int nMs){
  Error err = {0};
  Sqlite db = {0};
  Threadset threads = {0};

  opendb(&err, &db, "test.db", 1);
  sql_script(&err, &db, 
     "CREATE TABLE t1(x PRIMARY KEY, y BLOB);"
     "CREATE INDEX i1 ON t1(y);"
  );
  closedb(&err, &db);

  setstoptime(&err, nMs);

  sqlite3_enable_shared_cache(1);
  launch_thread(&err, &threads, vacuum1_thread_writer, 0);
  launch_thread(&err, &threads, vacuum1_thread_writer, 0);
  launch_thread(&err, &threads, vacuum1_thread_writer, 0);
  launch_thread(&err, &threads, vacuum1_thread_vacuumer, 0);
  join_all_threads(&err, &threads);
  sqlite3_enable_shared_cache(0);

  print_and_free_err(&err);
}
Beispiel #13
0
result_t SQLite::open(const char *file)
{
    sqlite3_enable_shared_cache(1);
    if (sqlite3_open_v2(file, &m_db, SQLITE_OPEN_FLAGS, 0))
    {
        result_t hr = CHECK_ERROR(Runtime::setError(sqlite3_errmsg(m_db)));
        sqlite3_close(m_db);
        m_db = NULL;
        return hr;
    }

    m_file = file;

    return 0;
}
Beispiel #14
0
js::Oracle::Oracle(int id)
{
	index = id;
	int rc = 0;
	char *zErrMsg = 0;

	rc = sqlite3_enable_shared_cache(1);
	if( rc != SQLITE_OK ){
		fprintf(stderr, "SQL error: Could not enable shared cache %s\n", zErrMsg);
		sqlite3_free(zErrMsg);
	}

	db = nullptr;
	index = id;
	Init(id);
}
nsresult
mozStorageService::Init()
{
    mLock = PR_NewLock();
    if (!mLock)
        return NS_ERROR_OUT_OF_MEMORY;

    // This makes multiple connections to the same database share the same pager
    // cache.  We do not need to lock here with mLock because this function is
    // only ever called from mozStorageService::GetSingleton, which will only
    // call this function once, and will not return until this function returns.
    int rc = sqlite3_enable_shared_cache(1);
    if (rc != SQLITE_OK)
        return ConvertResultCode(rc);

    return NS_OK;
}
Beispiel #16
0
result_t SQLite::open(const char *file)
{
    sqlite3_enable_shared_cache(1);
    if (sqlite3_open_v2(file, &m_db, SQLITE_OPEN_FLAGS, 0))
    {
        result_t hr = CHECK_ERROR(Runtime::setError(sqlite3_errmsg(m_db)));
        sqlite3_close(m_db);
        m_db = NULL;
        return hr;
    }

    obj_ptr<DBResult_base> retVal;
    execute("PRAGMA journal_mode=WAL;", 24, retVal);

    m_file = file;

    return 0;
}
Beispiel #17
0
    Connection::Connection(const char* path, bool create):
      m_handle(0)
    {
      sqlite3_enable_shared_cache(1);

      int flags = create ? SQLITE_OPEN_CREATE : 0;
      flags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_SHAREDCACHE;

      if (sqlite3_open_v2(path, &m_handle, flags, 0) != SQLITE_OK)
      {
        Error e(lastError());
        sqlite3_close(m_handle);
        m_handle = 0;
        throw e;
      }

      m_tbegin_stmt = new Statement("begin transaction", *this);
      m_tcommit_stmt = new Statement("commit", *this);
      m_trollback_stmt = new Statement("rollback", *this);
    }
Beispiel #18
0
bool SqDriver::InitializeThreadSafety()
{
	if (m_bThreadSafe)
	{
		return true;
	}

	if (sqlite3_threadsafe() == 0)
	{
		return false;
	}

	if (sqlite3_enable_shared_cache(1) != SQLITE_OK)
	{
		return false;
	}

	m_bThreadSafe = true;

	return true;
}
static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject*
        kwargs)
{
    static char *kwlist[] = {"do_enable", NULL, NULL};
    int do_enable;
    int rc;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &do_enable))
    {
        return NULL; 
    }

    rc = sqlite3_enable_shared_cache(do_enable);

    if (rc != SQLITE_OK) {
        PyErr_SetString(OperationalError, "Changing the shared_cache flag failed");
        return NULL;
    } else {
        Py_INCREF(Py_None);
        return Py_None;
    }
}
Beispiel #20
0
/*
   SQLite dbs have no user name, passwords, hosts or ports.
   just file names.
*/
bool QSpatiaLiteDriver::open(const QString & db, const QString &, const QString &, const QString &, int, const QString &conOpts)
{
    if (isOpen())
        close();

    if (db.isEmpty())
        return false;

    bool sharedCache = false;
    int openMode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, timeOut=5000;
    QStringList opts=QString(conOpts).remove(QLatin1Char(' ')).split(QLatin1Char(';'));
    foreach(const QString &option, opts) {
        if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) {
            bool ok;
            int nt = option.mid(21).toInt(&ok);
            if (ok)
                timeOut = nt;
        }
        if (option == QLatin1String("QSQLITE_OPEN_READONLY"))
            openMode = SQLITE_OPEN_READONLY;
        if (option == QLatin1String("QSQLITE_ENABLE_SHARED_CACHE"))
            sharedCache = true;
    }

    sqlite3_enable_shared_cache(sharedCache);

    if (QgsSLConnect::sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, NULL) == SQLITE_OK) {
        sqlite3_busy_timeout(d->access, timeOut);
        setOpen(true);
        setOpenError(false);
        return true;
    } else {
        setLastError(qMakeError(d->access, tr("Error opening database"),
                     QSqlError::ConnectionError));
        setOpenError(true);
        return false;
    }
}
int CSqldalImpl::Open( const char* p_pDbFile, const char* p_pkszMode )
{
	int srv, mode ;
	// pre
	if ( ! p_pDbFile || *p_pDbFile==0 )
	{
		FERR("NULL file name");
		Close();
		return false ;
	}
	if ( ! p_pkszMode || *p_pkszMode==0 )
	{
		FERR("NULL opening mode");
		Close();
		return false ;
	}

	mode = strModeToInt(p_pkszMode);
	if ( m_pDBConn && mode == m_mode ) return true ;

	m_mode = mode ;
	memmove( m_pDbFile, p_pDbFile, strlen(p_pDbFile) );
	srv = sqlite3_enable_shared_cache( false );
	if (srv != SQLITE_OK)
	{
		WARN("FAIL:sqlite3_enable_shared_cache:[%d]:[%s]",  sqlite3_errcode(m_pDBConn), sqlite3_errmsg(m_pDBConn) );
	}
	srv = sqlite3_open_v2 ( m_pDbFile, &m_pDBConn, m_mode, NULL );
	if (srv != SQLITE_OK)
	{
		ERR("sqlite3_open:[%d]:[%s]", sqlite3_errcode(m_pDBConn), sqlite3_errmsg(m_pDBConn) );
		Close();
		return false ;
	}
	LOG("[%s] Openned in [%s] mode", m_pDbFile, p_pkszMode );
	return true ;
}
Beispiel #22
0
/*
   SQLite dbs have no user name, passwords, hosts or ports.
   just file names.
*/
bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, const QString &, int, const QString &conOpts)
{
    if (isOpen())
        close();

    if (db.isEmpty())
        return false;
    bool sharedCache = false;
    int openMode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, timeOut=5000;
    QStringList opts=QString(conOpts).remove(QLatin1Char(' ')).split(QLatin1Char(';'));
    foreach(const QString &option, opts) {
        if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) {
            bool ok;
            int nt = option.mid(21).toInt(&ok);
            if (ok)
                timeOut = nt;
        }
        if (option == QLatin1String("QSQLITE_OPEN_READONLY"))
            openMode = SQLITE_OPEN_READONLY;
        if (option == QLatin1String("QSQLITE_ENABLE_SHARED_CACHE"))
            sharedCache = true;
    }

    sqlite3_enable_shared_cache(sharedCache);

#ifndef QT_WEBOS
    if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, NULL) == SQLITE_OK) {
#else // QT_WEBOS
#if SQLITE_VERSION_NUMBER >= 3005000
    if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, NULL) == SQLITE_OK) {
#else
	if (sqlite3_open(db.toUtf8().constData(), &d->access) == SQLITE_OK) {
#endif
#endif // QT_WEBOS
        sqlite3_busy_timeout(d->access, timeOut);
        setOpen(true);
        setOpenError(false);
        return true;
    } else {
        setLastError(qMakeError(d->access, tr("Error opening database"),
                     QSqlError::ConnectionError));
        setOpenError(true);
        return false;
    }
}

void QSQLiteDriver::close()
{
    if (isOpen()) {
        foreach (QSQLiteResult *result, d->results)
            result->d->finalize();

        if (sqlite3_close(d->access) != SQLITE_OK)
            setLastError(qMakeError(d->access, tr("Error closing database"),
                                    QSqlError::ConnectionError));
        d->access = 0;
        setOpen(false);
        setOpenError(false);
    }
}

QSqlResult *QSQLiteDriver::createResult() const
{
    return new QSQLiteResult(this);
}

bool QSQLiteDriver::beginTransaction()
{
    if (!isOpen() || isOpenError())
        return false;

    QSqlQuery q(createResult());
    if (!q.exec(QLatin1String("BEGIN"))) {
        setLastError(QSqlError(tr("Unable to begin transaction"),
                               q.lastError().databaseText(), QSqlError::TransactionError));
        return false;
    }

    return true;
}

bool QSQLiteDriver::commitTransaction()
{
    if (!isOpen() || isOpenError())
        return false;

    QSqlQuery q(createResult());
    if (!q.exec(QLatin1String("COMMIT"))) {
        setLastError(QSqlError(tr("Unable to commit transaction"),
                               q.lastError().databaseText(), QSqlError::TransactionError));
        return false;
    }

    return true;
}

bool QSQLiteDriver::rollbackTransaction()
{
    if (!isOpen() || isOpenError())
        return false;

    QSqlQuery q(createResult());
    if (!q.exec(QLatin1String("ROLLBACK"))) {
        setLastError(QSqlError(tr("Unable to rollback transaction"),
                               q.lastError().databaseText(), QSqlError::TransactionError));
        return false;
    }

    return true;
}

QStringList QSQLiteDriver::tables(QSql::TableType type) const
{
    QStringList res;
    if (!isOpen())
        return res;

    QSqlQuery q(createResult());
    q.setForwardOnly(true);

    QString sql = QLatin1String("SELECT name FROM sqlite_master WHERE %1 "
                                "UNION ALL SELECT name FROM sqlite_temp_master WHERE %1");
    if ((type & QSql::Tables) && (type & QSql::Views))
        sql = sql.arg(QLatin1String("type='table' OR type='view'"));
    else if (type & QSql::Tables)
        sql = sql.arg(QLatin1String("type='table'"));
    else if (type & QSql::Views)
        sql = sql.arg(QLatin1String("type='view'"));
    else
        sql.clear();

    if (!sql.isEmpty() && q.exec(sql)) {
        while(q.next())
            res.append(q.value(0).toString());
    }

    if (type & QSql::SystemTables) {
        // there are no internal tables beside this one:
        res.append(QLatin1String("sqlite_master"));
    }

    return res;
}

static QSqlIndex qGetTableInfo(QSqlQuery &q, const QString &tableName, bool onlyPIndex = false)
{
    QString schema;
    QString table(tableName);
    int indexOfSeparator = tableName.indexOf(QLatin1Char('.'));
    if (indexOfSeparator > -1) {
        schema = tableName.left(indexOfSeparator).append(QLatin1Char('.'));
        table = tableName.mid(indexOfSeparator + 1);
    }
    q.exec(QLatin1String("PRAGMA ") + schema + QLatin1String("table_info (") + _q_escapeIdentifier(table) + QLatin1String(")"));

    QSqlIndex ind;
    while (q.next()) {
        bool isPk = q.value(5).toInt();
        if (onlyPIndex && !isPk)
            continue;
        QString typeName = q.value(2).toString().toLower();
        QSqlField fld(q.value(1).toString(), qGetColumnType(typeName));
        if (isPk && (typeName == QLatin1String("integer")))
            // INTEGER PRIMARY KEY fields are auto-generated in sqlite
            // INT PRIMARY KEY is not the same as INTEGER PRIMARY KEY!
            fld.setAutoValue(true);
        fld.setRequired(q.value(3).toInt() != 0);
        fld.setDefaultValue(q.value(4));
        ind.append(fld);
    }
    return ind;
}
Beispiel #23
0
static gboolean
rspamd_sqlite3_wait (rspamd_mempool_t *pool, const gchar *lock)
{
	gint fd;
	struct timespec sleep_ts = {
		.tv_sec = 0,
		.tv_nsec = 1000000
	};

	fd = open (lock, O_RDONLY);

	if (fd == -1) {

		if (errno == ENOENT) {
			/* Lock is already released, so we can continue */
			return TRUE;
		}

		msg_err_pool_check ("cannot open lock file %s: %s", lock, strerror (errno));

		return FALSE;
	}

	while (!rspamd_file_lock (fd, TRUE)) {
		if (nanosleep (&sleep_ts, NULL) == -1 && errno != EINTR) {
			close (fd);
			msg_err_pool_check ("cannot sleep open lock file %s: %s", lock,
					strerror (errno));

			return FALSE;
		}
	}

	rspamd_file_unlock (fd, FALSE);
	unlink (lock);
	close (fd);

	return TRUE;
}

#define RSPAMD_SQLITE_MMAP_LIMIT 268435456
#define RSPAMD_SQLITE_CACHE_SIZE 262144

sqlite3 *
rspamd_sqlite3_open_or_create (rspamd_mempool_t *pool, const gchar *path, const
		gchar *create_sql, GError **err)
{
	sqlite3 *sqlite;
	gint rc, flags, lock_fd;
	gchar lock_path[PATH_MAX], dbdir[PATH_MAX], *pdir;
	static const char sqlite_wal[] =
									"PRAGMA journal_mode=\"wal\";"
									"PRAGMA wal_autocheckpoint = 16;"
									"PRAGMA journal_size_limit = 1536;",
			exclusive_lock_sql[] =	"PRAGMA locking_mode=\"exclusive\";",

			fsync_sql[] = 			"PRAGMA synchronous=\"NORMAL\";",

			foreign_keys[] = 		"PRAGMA foreign_keys=\"ON\";",

			enable_mmap[] = 		"PRAGMA mmap_size="
									G_STRINGIFY(RSPAMD_SQLITE_MMAP_LIMIT) ";",

			other_pragmas[] = 		"PRAGMA read_uncommitted=\"ON\";"
									"PRAGMA cache_size="
									G_STRINGIFY(RSPAMD_SQLITE_CACHE_SIZE) ";";
	gboolean create = FALSE, has_lock = FALSE;

	flags = SQLITE_OPEN_READWRITE;
#ifdef SQLITE_OPEN_SHAREDCACHE
	flags |= SQLITE_OPEN_SHAREDCACHE;
#endif
#ifdef SQLITE_OPEN_WAL
	flags |= SQLITE_OPEN_WAL;
#endif

	rspamd_strlcpy (dbdir, path, sizeof (dbdir));
	pdir = dirname (dbdir);

	if (access (pdir, W_OK) == -1) {
		g_set_error (err, rspamd_sqlite3_quark (),
				errno, "cannot open sqlite directory %s: %s",
				pdir, strerror (errno));

		return NULL;
	}

	rspamd_snprintf (lock_path, sizeof (lock_path), "%s.lock", path);

	if (access (path, R_OK) == -1) {
		flags |= SQLITE_OPEN_CREATE;
		create = TRUE;
	}


	rspamd_snprintf (lock_path, sizeof (lock_path), "%s.lock", path);
	lock_fd = open (lock_path, O_WRONLY|O_CREAT|O_EXCL, 00600);

	if (lock_fd == -1 && (errno == EEXIST || errno == EBUSY)) {
		msg_debug_pool_check ("checking %s to wait for db being initialized", lock_path);

		if (!rspamd_sqlite3_wait (pool, lock_path)) {
			g_set_error (err, rspamd_sqlite3_quark (),
					errno, "cannot create sqlite file %s: %s",
					path, strerror (errno));

			return NULL;
		}

		/* At this point we have database created */
		create = FALSE;
		has_lock = FALSE;
	}
	else {
		msg_debug_pool_check ("locking %s to block other processes", lock_path);

		g_assert (rspamd_file_lock (lock_fd, FALSE));
		has_lock = TRUE;
	}

	sqlite3_enable_shared_cache (1);

	if ((rc = sqlite3_open_v2 (path, &sqlite,
			flags, NULL)) != SQLITE_OK) {
#if SQLITE_VERSION_NUMBER >= 3008000
		g_set_error (err, rspamd_sqlite3_quark (),
				rc, "cannot open sqlite db %s: %s",
				path, sqlite3_errstr (rc));
#else
		g_set_error (err, rspamd_sqlite3_quark (),
				rc, "cannot open sqlite db %s: %d",
				path, rc);
#endif

		return NULL;
	}

	if (create && has_lock) {
		if (sqlite3_exec (sqlite, sqlite_wal, NULL, NULL, NULL) != SQLITE_OK) {
			msg_warn_pool_check ("WAL mode is not supported (%s), locking issues might occur",
					sqlite3_errmsg (sqlite));
		}

		if (sqlite3_exec (sqlite, exclusive_lock_sql, NULL, NULL, NULL) != SQLITE_OK) {
			msg_warn_pool_check ("cannot exclusively lock database to create schema: %s",
					sqlite3_errmsg (sqlite));
		}

		if (create_sql) {
			if (sqlite3_exec (sqlite, create_sql, NULL, NULL, NULL) != SQLITE_OK) {
				g_set_error (err, rspamd_sqlite3_quark (),
						-1, "cannot execute create sql `%s`: %s",
						create_sql, sqlite3_errmsg (sqlite));
				sqlite3_close (sqlite);
				rspamd_file_unlock (lock_fd, FALSE);
				unlink (lock_path);
				close (lock_fd);

				return NULL;
			}
		}

		sqlite3_close (sqlite);

		/* Reopen in normal mode */
		msg_debug_pool_check ("reopening %s in normal mode", path);
		flags &= ~SQLITE_OPEN_CREATE;

		if ((rc = sqlite3_open_v2 (path, &sqlite,
				flags, NULL)) != SQLITE_OK) {
	#if SQLITE_VERSION_NUMBER >= 3008000
			g_set_error (err, rspamd_sqlite3_quark (),
					rc, "cannot open sqlite db after creation %s: %s",
					path, sqlite3_errstr (rc));
	#else
			g_set_error (err, rspamd_sqlite3_quark (),
					rc, "cannot open sqlite db after creation %s: %d",
					path, rc);
	#endif
			rspamd_file_unlock (lock_fd, FALSE);
			unlink (lock_path);
			close (lock_fd);
			return NULL;
		}
	}

	if (sqlite3_exec (sqlite, sqlite_wal, NULL, NULL, NULL) != SQLITE_OK) {
		msg_warn_pool_check ("WAL mode is not supported (%s), locking issues might occur",
				sqlite3_errmsg (sqlite));
	}

	if (sqlite3_exec (sqlite, fsync_sql, NULL, NULL, NULL) != SQLITE_OK) {
		msg_warn_pool_check ("cannot set synchronous: %s",
				sqlite3_errmsg (sqlite));
	}

	if ((rc = sqlite3_exec (sqlite, foreign_keys, NULL, NULL, NULL)) !=
			SQLITE_OK) {
		msg_warn_pool_check ("cannot enable foreign keys: %s",
				sqlite3_errmsg (sqlite));
	}

#if defined(__LP64__) || defined(_LP64)
	if ((rc = sqlite3_exec (sqlite, enable_mmap, NULL, NULL, NULL)) != SQLITE_OK) {
		msg_warn_pool_check ("cannot enable mmap: %s",
				sqlite3_errmsg (sqlite));
	}
#endif

	if ((rc = sqlite3_exec (sqlite, other_pragmas, NULL, NULL, NULL)) !=
			SQLITE_OK) {
		msg_warn_pool_check ("cannot execute tuning pragmas: %s",
				sqlite3_errmsg (sqlite));
	}

	if (has_lock) {
		msg_debug_pool_check ("removing lock from %s", lock_path);
		rspamd_file_unlock (lock_fd, FALSE);
		unlink (lock_path);
		close (lock_fd);
	}

	return sqlite;
}
Beispiel #24
0
cr_SqliteDb *
cr_db_open(const char *path, cr_DatabaseType db_type, GError **err)
{
    cr_SqliteDb *sqlitedb = NULL;
    int exists;
    sqlite3 *db = NULL;
    GError *tmp_err = NULL;
    void *statements;

    assert(path);
    assert(db_type < CR_DB_SENTINEL);
    assert(!err || *err == NULL);

    if (path[0] == '\0') {
        g_set_error(err, ERR_DOMAIN, CRE_BADARG, "Bad path: \"%s\"", path);
        return NULL;
    }

    exists = g_file_test(path, G_FILE_TEST_IS_REGULAR);
    if (exists) {
        struct stat stat_buf;
        if (stat(path, &stat_buf) == -1) {
            g_set_error(err, ERR_DOMAIN, CRE_IO,
                        "Cannot stat %s: %s", path, g_strerror(errno));
            return NULL;
        }

        if (stat_buf.st_size == 0)
            // File exists, but is just a placeholder created by g_mkstemp()
            // because --local-sqlite option was used
            exists = FALSE;
    }

    sqlite3_enable_shared_cache(1);

    db = open_sqlite_db(path, &tmp_err);
    if (tmp_err) {
        g_propagate_error(err, tmp_err);
        return NULL;
    }

    sqlite3_exec(db, "BEGIN", NULL, NULL, NULL);

    db_tweak(db, &tmp_err);
    if (tmp_err) {
        g_propagate_error(err, tmp_err);
        sqlite3_close(db);
        return NULL;
    }

    db_create_dbinfo_table(db, &tmp_err);
    if (tmp_err) {
        g_propagate_error(err, tmp_err);
        sqlite3_close(db);
        return NULL;
    }

    if (!exists) {
        // Do not recreate tables, indexes and triggers if db has existed.
        switch (db_type) {
            case CR_DB_PRIMARY:
                db_create_primary_tables(db, &tmp_err);
                break;
            case CR_DB_FILELISTS:
                db_create_filelists_tables(db, &tmp_err);
                break;
            case CR_DB_OTHER:
                db_create_other_tables(db, &tmp_err);
                break;
            default:
                g_critical("%s: Bad db_type", __func__);
                assert(0);
                g_set_error(err, ERR_DOMAIN, CRE_ASSERT, "Bad db type");
                return NULL;
        }

        if (tmp_err) {
            g_propagate_error(err, tmp_err);
            sqlite3_close(db);
            return NULL;
        }
    }

    // Compile SQL statements
    switch (db_type) {
        case CR_DB_PRIMARY:
            statements = cr_db_prepare_primary_statements(db, &tmp_err);
            break;
        case CR_DB_FILELISTS:
            statements = cr_db_prepare_filelists_statements(db, &tmp_err);
            break;
        case CR_DB_OTHER:
            statements = cr_db_prepare_other_statements(db, &tmp_err);
            break;
        default:
            g_critical("%s: Bad db_type", __func__);
            assert(0);
            g_set_error(err, ERR_DOMAIN, CRE_ASSERT, "Bad db type");
            return NULL;
    }

    if (!statements) {
            g_propagate_error(err, tmp_err);
            sqlite3_close(db);
            return NULL;
    }

    sqlitedb       = g_new0(cr_SqliteDb, 1);
    sqlitedb->db   = db;
    sqlitedb->type = db_type;

    switch (db_type) {
        case CR_DB_PRIMARY:
            sqlitedb->statements.pri = statements;
            break;
        case CR_DB_FILELISTS:
            sqlitedb->statements.fil = statements;
            break;
        case CR_DB_OTHER:
            sqlitedb->statements.oth = statements;
            break;
        default:
            g_critical("%s: Bad db_type", __func__);
            assert(0);
            g_set_error(err, ERR_DOMAIN, CRE_ASSERT, "Bad db type");
            return NULL;
    }

    return sqlitedb;
}
void Connector::enableSharedCache(bool flag)
{
	sqlite3_enable_shared_cache(flag ? 1 : 0);
}
Beispiel #26
0
 int enable_shared_cache(bool fenable)
 {
     return sqlite3_enable_shared_cache(fenable);
 }
/*
** This routine implements the server.  To start the server, first
** make sure g.serverHalt is false, then create a new detached thread
** on this procedure.  See the sqlite3_server_start() routine below
** for an example.  This procedure loops until g.serverHalt becomes
** true.
*/
void *sqlite3_server(void *NotUsed){
  sqlite3_enable_shared_cache(1);
  if( pthread_mutex_trylock(&g.serverMutex) ){
    sqlite3_enable_shared_cache(0);
    return 0;  /* Another server is already running */
  }
  while( !g.serverHalt ){
    SqlMessage *pMsg;

    /* Remove the last message from the message queue.
    */
    pthread_mutex_lock(&g.queueMutex);
    while( g.pQueueTail==0 && g.serverHalt==0 ){
      pthread_cond_wait(&g.serverWakeup, &g.queueMutex);
    }
    pMsg = g.pQueueTail;
    if( pMsg ){
      if( pMsg->pPrev ){
        pMsg->pPrev->pNext = 0;
      }else{
        g.pQueueHead = 0;
      }
      g.pQueueTail = pMsg->pPrev;
    }
    pthread_mutex_unlock(&g.queueMutex);
    if( pMsg==0 ) break;

    /* Process the message just removed
    */
    pthread_mutex_lock(&pMsg->clientMutex);
    switch( pMsg->op ){
      case MSG_Open: {
        pMsg->errCode = sqlite3_open(pMsg->zIn, &pMsg->pDb);
        break;
      }
      case MSG_Prepare: {
        pMsg->errCode = sqlite3_prepare(pMsg->pDb, pMsg->zIn, pMsg->nByte,
                                        &pMsg->pStmt, &pMsg->zOut);
        break;
      }
      case MSG_Step: {
        pMsg->errCode = sqlite3_step(pMsg->pStmt);
        break;
      }
      case MSG_Reset: {
        pMsg->errCode = sqlite3_reset(pMsg->pStmt);
        break;
      }
      case MSG_Finalize: {
        pMsg->errCode = sqlite3_finalize(pMsg->pStmt);
        break;
      }
      case MSG_Close: {
        pMsg->errCode = sqlite3_close(pMsg->pDb);
        break;
      }
    }

    /* Signal the client that the message has been processed.
    */
    pMsg->op = MSG_Done;
    pthread_mutex_unlock(&pMsg->clientMutex);
    pthread_cond_signal(&pMsg->clientWakeup);
  }
  pthread_mutex_unlock(&g.serverMutex);
  sqlite3_thread_cleanup();
  return 0;
}