void test(int newdb) { const char * sSQL; char * pErrMsg = 0; int ret = 0; sqlite3 * db = 0; if(newdb) { ::DeleteFileA("encrypt.db"); } //创建数据库 ret = sqlite3_open("encrypt.db", &db); //添加密码 if(newdb) { ret = sqlite3_key( db, "dcg", 3 ); } else { ret = sqlite3_key(db, "abc", 3); } //在内存数据库中创建表 sSQL = "create table files(path TEXT PRIMARY KEY, content BLOB, time INTEGER);"; sqlite3_exec( db, sSQL, _callback_exec, 0, &pErrMsg ); if(newdb) { //插入数据 sSQL = "insert into files values(?,?,?);"; sqlite3_stmt* stmt; int src; src = sqlite3_prepare_v2(db, sSQL, strlen(sSQL), &stmt, NULL); src = sqlite3_bind_text(stmt,1, "/global.dat", -1, SQLITE_STATIC); src = sqlite3_bind_blob(stmt,2, "zhaoyun", 7, SQLITE_STATIC); src = sqlite3_bind_int(stmt, 3, 100); src = sqlite3_step(stmt); src = sqlite3_total_changes(db); sqlite3_finalize(stmt); // sqlite3_exec( db, sSQL, _callback_exec, 0, &pErrMsg ); } if(newdb) { ret = sqlite3_rekey( db, "abc", 3); } //取得数据并显示 sSQL = "select * from files;"; sqlite3_exec( db, sSQL, _callback_exec, 0, &pErrMsg ); //关闭数据库 sqlite3_close(db); db = 0; }
database::database(const std::string &path, const void *pKey, int nKey) : m_path(path) { // create database sqlite3* handle = NULL; int err = sqlite3_open_v2(path.c_str(), &handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); if (err != SQLITE_OK) { // error! } else { if (pKey && (nKey > 0)) { err = sqlite3_key(handle, pKey, nKey); std::cout << "sqlite key error " << err << "\n"; if (err != SQLITE_OK) { sqlite3_close(handle); return ; } } m_dbHandle = handle; } }
void HHVM_METHOD(SQLite3, open, const String& filename, int64_t flags /* = SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE */, const Variant& encryption_key /* = null */) { auto *data = Native::data<SQLite3>(this_); if (data->m_raw_db) { throw Exception("Already initialized DB Object"); } String fname; if (strncmp(filename.data(), ":memory:", 8) != 0) { fname = File::TranslatePath(filename); } else { fname = filename; // in-memory db } if (sqlite3_open_v2(fname.data(), &data->m_raw_db, flags, nullptr) != SQLITE_OK) { throw Exception("Unable to open database: %s", sqlite3_errmsg(data->m_raw_db)); } #ifdef SQLITE_HAS_CODEC const String& str_encryption_key = encryption_key.isNull() ? null_string : encryption_key.toString(); if (!str_encryption_key.empty() && sqlite3_key(data->m_raw_db, str_encryption_key.data(), str_encryption_key.size()) != SQLITE_OK) { throw Exception("Unable to open database: %s", sqlite3_errmsg(data->m_raw_db)); } #endif }
void c_SQLite3::t_open(CStrRef filename, int64 flags /* = k_SQLITE3_OPEN_READWRITE | k_SQLITE3_OPEN_CREATE */, CStrRef encryption_key /* = null_string */) { INSTANCE_METHOD_INJECTION_BUILTIN(SQLite3, SQLite3::open); if (m_raw_db) { throw Exception("Already initialized DB Object"); } String fname; if (strncmp(filename.data(), ":memory:", 8) != 0) { fname = File::TranslatePath(filename); } else { fname = filename; // in-memory db } if (sqlite3_open_v2(fname.data(), &m_raw_db, flags, NULL) != SQLITE_OK) { throw Exception("Unable to open database: %s", sqlite3_errmsg(m_raw_db)); } #ifdef SQLITE_HAS_CODEC if (!encryption_key.empty() && sqlite3_key(m_raw_db, encryption_key.data(), encryption_key.size()) != SQLITE_OK) { throw Exception("Unable to open database: %s", sqlite3_errmsg(m_raw_db)); } #endif }
void $CMD_NAME$::open() { #ifdef WIN32 string despath = CCFileUtils::sharedFileUtils()->fullPathForFilename(dbsrcFileName.c_str()) ; #else string despath = CCFileUtils::sharedFileUtils()->getWritablePath()+dbdesFileName; if (!Utils::isFileExist(despath)) { string srcpath = CCFileUtils::sharedFileUtils()->fullPathForFilename(dbsrcFileName.c_str()) ; Utils::FileCopy( srcpath, despath); } #endif result = sqlite3_open( despath.c_str() , &pDB); CCAssert( result == SQLITE_OK , "打开数据库失败($CMD_NAME$)"); sqlite3_key(pDB, "1234", 4); resultArray = CCArray::create(); resultArray->retain(); resultDictionary = CCDictionary::create(); resultDictionary->retain(); }
// DBをオープン sqlite3* DataManager::openDB() { // DBファイルを開いた時間を記憶しておく(処理時間計測のため) _dbOpenTime = std::chrono::system_clock::now(); // SQLiteから読込 std::string dbPath = FileUtils::getInstance()->getWritablePath() + DB_FILE_NAME_ENC; sqlite3 *db = nullptr; // DBファイルオープン auto status = sqlite3_open(dbPath.c_str(), &db); if(status != SQLITE_OK) { CCLOG("▼sqlite3_open failed."); return nullptr; } // 暗号化する status = sqlite3_key(db, ENCRYPT_DB_PASSWORD, (int)strlen(ENCRYPT_DB_PASSWORD)); if(status != SQLITE_OK) { CCLOG("▼sqlite3_key failed."); return nullptr; } CCLOG("○DB opened successfully. File : %s",dbPath.c_str()); return db; }
void np_config_remove_section(NetPhoneConfig *npconfig, LpSection *section){ #ifdef HAVE_SQLITE3 char szSQL[128]; sprintf(szSQL,"DELETE FROM ua_config WHERE section = '%s';",section->name); if(!npconfig->db) { if (sqlite3_open(npconfig->filename,&npconfig->db) == SQLITE_OK) { sqlite3_key(npconfig->db,SQLITE3_KEY,SQLITE3_KEY_LEN); sqlite3_exec(npconfig->db,szSQL,0,0, 0); np_message("np_config_remove_section: sqlite3_exec %s\n", szSQL); sqlite3_close(npconfig->db); } npconfig->db = NULL; }else { sqlite3_exec(npconfig->db,szSQL,0,0, 0); np_message("np_config_remove_section: sqlite3_exec %s\n", szSQL); } #endif npconfig->sections=np_list_remove(npconfig->sections,(void *)section); np_section_destroy(section); }
int sqlite3_key_v2(sqlite3 *db, const char *zDbName, const void *zKey, int nKey) { BOTANSQLITE_TRACE("sqlite3_key_v2"); //We don't use zDbName. Pass-through to the old sqlite_key (void)(zDbName); return sqlite3_key(db, zKey, nKey); }
void lp_config_remove_section(LpConfig *lpconfig, LpSection *section){ #ifdef HAVE_SQLITE3 char szSQL[128]; sprintf(szSQL,"DELETE FROM ua_config WHERE section = '%s';",section->name); if(!lpconfig->db) { if (sqlite3_open(lpconfig->filename,&lpconfig->db) == SQLITE_OK) { sqlite3_key(lpconfig->db,SQLITE3_KEY,SQLITE3_KEY_LEN); sqlite3_exec(lpconfig->db,szSQL,0,0, 0); ms_message("lp_config_remove_section: sqlite3_exec %s", szSQL); sqlite3_close(lpconfig->db); } lpconfig->db = NULL; }else { sqlite3_exec(lpconfig->db,szSQL,0,0, 0); ms_message("lp_config_remove_section: sqlite3_exec %s", szSQL); } #endif lpconfig->sections=ms_list_remove(lpconfig->sections,(void *)section); lp_section_destroy(section); }
void DB_Bianse::open() { #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) // sqlite不能读取ANDROID apk里的db文件 string despath = CCFileUtils::sharedFileUtils()->getWritablePath() + dbdesFileName; string despathMD5 = CCFileUtils::sharedFileUtils()->getWritablePath() + CCFileUtils::sharedFileUtils()->MD5Filename(dbdesFileName.c_str()); string newValue = CCUserDefault::sharedUserDefault()->getStringForKey(KEY_OF_CODEVERSION); newValue += "_" + Utils::itos(CCUserDefault::sharedUserDefault()->getIntegerForKey(KEY_OF_RESOURCEVERSION)); string key = dbdesFileName; string value = CCUserDefault::sharedUserDefault()->getStringForKey(key.c_str()); if (!CCFileUtils::sharedFileUtils()->isFileExist(despath) || value.empty() || value.compare(newValue) != 0) { Utils::FileCopy(dbsrcFileName, despathMD5); CCUserDefault::sharedUserDefault()->setStringForKey(key.c_str(), newValue); } despath = despathMD5; #else string despath = CCFileUtils::sharedFileUtils()->MD5fullPathForFilename(dbsrcFileName.c_str()); #endif result = sqlite3_open( despath.c_str() , &pDB); CCAssert( result == SQLITE_OK , "打开数据库失败(DB_Bianse)"); sqlite3_key(pDB, "woshixiaopingguo", 4); resultArray = CCArray::create(); resultArray->retain(); resultDictionary = CCDictionary::create(); resultDictionary->retain(); }
int CppSQLite3DB::setKey(const char* szPass, int length) { int nRet = sqlite3_key(mpDB, szPass, length ); if (nRet != SQLITE_OK) { const char* szError = sqlite3_errmsg(mpDB); throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG); } return nRet; }
void testSQL() { sqlite3* db=NULL; int success = sqlite3_open("my.db", &db); if(success != SQLITE_OK) { log("DB failed2"); return; } if(!db) { log("DB failed"); return; } std::string key="abadgsfdg"; sqlite3_key(db, key.c_str(), key.size()); success = sqlite3_exec(db, "SELECT count(*) FROM sqlite_master;", NULL, NULL, NULL); if(success == SQLITE_OK) { log("DB success"); success = sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS mytbl(mid INTEGER PRIMARY KEY AUTOINCREMENT, val TEXT)", NULL, NULL, NULL); if(success == SQLITE_OK) { log("DB query"); sqlite3_exec(db, "BEGIN IMMEDIATE TRANSACTION", NULL, NULL, NULL); for(int i=0; i<100; ++i) { success = sqlite3_exec(db, "INSERT INTO mytbl(val) VALUES ('aaa')", NULL, NULL, NULL); if(success != SQLITE_OK) { log("insert err %d", i); } // else // { // std::cout << i << std::endl; // std::cout.flush(); // } } sqlite3_exec(db, "COMMIT TRANSACTION", NULL, NULL, NULL); } } else { log("DB failed"); } sqlite3_close(db); }
// Set the key for the current sqlite database instance. void Database::key(const std::string& aKey) const { int pass_len = static_cast<int>(aKey.length()); #ifdef SQLITE_HAS_CODEC if (pass_len > 0) { const int ret = sqlite3_key(mpSQLite, aKey.c_str(), pass_len); check(ret); } #else // SQLITE_HAS_CODEC if (pass_len > 0) { const SQLite::Exception exception("No encryption support, recompile with SQLITE_HAS_CODEC to enable."); throw exception; } #endif // SQLITE_HAS_CODEC }
void native_key_str(JNIEnv* env, jobject object, jstring jKey) { sqlite3 * handle = (sqlite3 *)env->GetIntField(object, offset_db_handle); char const * key = env->GetStringUTFChars(jKey, NULL); jsize keyLen = env->GetStringUTFLength(jKey); if ( keyLen > 0 ) { int status = sqlite3_key(handle, key, keyLen); if ( status != SQLITE_OK ) { throw_sqlite3_exception(env, handle); } } env->ReleaseStringUTFChars(jKey, key); }
bool CppSQLite3DB::setkey(const char *key) { #ifdef SQLITE_HAS_CODEC if (!key) { return false; } int rc = sqlite3_key(mpDB, key, (int)strlen(key)); if (rc != SQLITE_OK) { throw CppSQLite3Exception(rc, "setkey error"); } return (rc == SQLITE_OK); #else return false; #endif }
void native_key_char(JNIEnv* env, jobject object, jcharArray jKey) { char *keyUtf8 = 0; int lenUtf8 = 0; jchar* keyUtf16 = 0; jsize lenUtf16 = 0; UErrorCode status = U_ZERO_ERROR; UConverter *encoding = 0; sqlite3 * handle = (sqlite3 *)env->GetIntField(object, offset_db_handle); keyUtf16 = env->GetCharArrayElements(jKey, 0); lenUtf16 = env->GetArrayLength(jKey); // no key, bailing out. if ( lenUtf16 == 0 ) goto done; encoding = ucnv_open("UTF-8", &status); if( U_FAILURE(status) ) { throw_sqlite3_exception(env, "native_key_char: opening encoding converter failed"); goto done; } lenUtf8 = ucnv_fromUChars(encoding, NULL, 0, keyUtf16, lenUtf16, &status); status = (status == U_BUFFER_OVERFLOW_ERROR) ? U_ZERO_ERROR : status; if( U_FAILURE(status) ) { throw_sqlite3_exception(env, "native_key_char: utf8 length unknown"); goto done; } keyUtf8 = (char*) malloc(lenUtf8 * sizeof(char)); ucnv_fromUChars(encoding, keyUtf8, lenUtf8, keyUtf16, lenUtf16, &status); if( U_FAILURE(status) ) { throw_sqlite3_exception(env, "native_key_char: utf8 conversion failed"); goto done; } if ( sqlite3_key(handle, keyUtf8, lenUtf8) != SQLITE_OK ) { throw_sqlite3_exception(env, handle); } done: env->ReleaseCharArrayElements(jKey, keyUtf16, 0); if(encoding != 0) ucnv_close(encoding); if(keyUtf8 != 0) free(keyUtf8); }
int lp_config_sync(LpConfig *lpconfig){ #ifdef HAVE_SQLITE3 lpconfig->db = NULL; if (lpconfig->filename==NULL) return -1; if (sqlite3_open(lpconfig->filename,&lpconfig->db) == SQLITE_OK) { sqlite3_key(lpconfig->db,SQLITE3_KEY,SQLITE3_KEY_LEN); if (!sqlite3_table_new(lpconfig->db)) { //sqlite3_table_empty(lpconfig->db); //ms_warning("Database update: %s\n", sqlite3_errmsg(lpconfig->db)); } ms_list_for_each2(lpconfig->sections,(void (*)(void *,void*))lp_section_write,(void *)lpconfig->db); sqlite3_close(lpconfig->db); }else{ ms_warning("Can't open database: %s\n", sqlite3_errmsg(lpconfig->db)); } lpconfig->db = NULL; #else FILE *file; if (lpconfig->filename==NULL) return -1; #ifndef WIN32 /* don't create group/world-accessible files */ (void) umask(S_IRWXG | S_IRWXO); #endif #ifdef _MSC_VER file=fopen(lpconfig->filename,"w+b"); #else file=fopen(lpconfig->filename,"w"); #endif // _MSC_VER if (file==NULL){ ms_warning("Could not write %s !",lpconfig->filename); return -1; } ms_list_for_each2(lpconfig->sections,(void (*)(void *,void*))lp_section_write,(void *)file); fclose(file); #endif // HAVE_SQLITE3 lpconfig->modified=0; return 0; }
int np_config_sync(NetPhoneConfig *npconfig){ #ifdef HAVE_SQLITE3 npconfig->db = NULL; if (npconfig->filename==NULL) return -1; if (sqlite3_open(npconfig->filename,&npconfig->db) == SQLITE_OK) { sqlite3_key(npconfig->db,SQLITE3_KEY,SQLITE3_KEY_LEN); if (!sqlite3_table_new(npconfig->db)) { } np_list_for_each2(npconfig->sections,(void (*)(void *,void*))np_section_write,(void *)npconfig->db); sqlite3_close(npconfig->db); }else{ np_warning("Can't open database: %s\n", sqlite3_errmsg(npconfig->db)); } npconfig->db = NULL; #else FILE *file; if (npconfig->filename==NULL) return -1; #ifndef WIN32 /* don't create group/world-accessible files */ (void) umask(S_IRWXG | S_IRWXO); #endif #ifdef _MSC_VER file=fopen(npconfig->filename,"w+b"); #else file=fopen(npconfig->filename,"w"); #endif // _MSC_VER if (file==NULL){ np_warning("Could not write %s !\n",npconfig->filename); return -1; } np_list_for_each2(npconfig->sections,(void (*)(void *,void*))np_section_write,(void *)file); fclose(file); #endif // HAVE_SQLITE3 npconfig->modified=0; return 0; }
int IniFileTransToSqlFileMain() { char szValue[MAX_PATH]; char szCfgFile[MAX_PATH]; SKNL3GetCurrentAppPath(szCfgFile, sizeof(szCfgFile)); sprintf(szCfgFile, "%s%s", szCfgFile, "inisql.ini"); DWORD dwRet = 0; ::GetPrivateProfileString("OUTPUT", "SQLFILE", "", szValue, sizeof(szValue), szCfgFile); if(strlen(szValue) == 0) { printf("无法获取SQL输出文件信息In file[%s]\n", szCfgFile); return -1; } if(PathFileExists(szValue)) { DeleteFile(szValue); } sqlite3* sql; if(SQLITE_OK != sqlite3_open(szValue, &sql)) { printf("无法创建%s\n", szValue); return -2; } ::GetPrivateProfileString("OUTPUT", "SQLPASSWORD", "", szValue, sizeof(szValue), szCfgFile); if(strlen(szValue) != 0) { printf("设置SQL密码为%s\n", szValue); if(SQLITE_OK != sqlite3_key(sql, szValue, strlen(szValue))) { printf("设置SQL密码失败\n"); sqlite3_close(sql); return -3; } } IniFileTransToSqlFile(szCfgFile, sql); sqlite3_close(sql); return 0; }
void native_key(JNIEnv* env, jobject object, jbyteArray jKey) { int rc = 0; int index = 0; jsize size = 0; jbyte *key = 0; sqlite3 *handle = NULL; handle = (sqlite3 *)env->GetLongField(object, offset_db_handle); if(handle == NULL){ LOGE("env->GetLongField returned NULL when retrieving sqlite3 *\n"); } key = env->GetByteArrayElements(jKey, NULL); size = env->GetArrayLength(jKey); if(key == NULL || size == 0) goto done; rc = sqlite3_key(handle, key, size); if(rc != SQLITE_OK) { throw_sqlite3_exception(env, handle); } done: if(key) env->ReleaseByteArrayElements(jKey, key, JNI_ABORT); }
void native_key_mutf8(JNIEnv* env, jobject object, jcharArray jKey) { int rc; int idx; jint releaseElements = 0; jboolean arrayIsCopy; sqlite3 *handle = (sqlite3 *)env->GetLongField(object, offset_db_handle); jsize sz = env->GetArrayLength(jKey); jchar* jKeyChar = env->GetCharArrayElements(jKey, &arrayIsCopy); jstring key = env->NewString(jKeyChar, sz); const char* password = env->GetStringUTFChars(key, JNI_FALSE); int password_sz = env->GetStringUTFLength(key); if(password_sz > 0){ rc = sqlite3_key(handle, password, password_sz); if(rc != SQLITE_OK){ throw_sqlite3_exception(env, handle); } } env->ReleaseCharArrayElements(jKey, jKeyChar, JNI_ABORT); env->ReleaseStringUTFChars(key, password); }
bool Handle::setCipherKey(const void *data, int size) { #ifdef SQLITE_HAS_CODEC int rc = sqlite3_key((sqlite3 *) m_handle, data, size); if (rc == SQLITE_OK) { m_error.reset(); return true; } Error::ReportSQLite(m_tag, path, Error::HandleOperation::SetCipherKey, rc, sqlite3_extended_errcode((sqlite3 *) m_handle), sqlite3_errmsg((sqlite3 *) m_handle), &m_error); return false; #else //SQLITE_HAS_CODEC Error::ReportSQLite(m_tag, path, Error::HandleOperation::SetCipherKey, SQLITE_MISUSE, SQLITE_MISUSE, "[sqlite3_key] is not supported for current config", &m_error); return false; #endif //SQLITE_HAS_CODEC }
NetPhoneConfig * np_config_new(const char *filename){ NetPhoneConfig *npconfig=np_new0(NetPhoneConfig,1); if (filename!=NULL){ npconfig->filename=strdup(filename); #ifdef HAVE_SQLITE3 npconfig->db = NULL; if (sqlite3_open(filename,&npconfig->db) == SQLITE_OK){ sqlite3_key(npconfig->db,SQLITE3_KEY,SQLITE3_KEY_LEN); if(!sqlite3_table_new(npconfig->db)); np_config_parse(npconfig); sqlite3_close(npconfig->db); }else{ //np_warning("Can't open database: %s\n", sqlite3_errmsg(npconfig->db)); } npconfig->db = NULL; #else #ifdef _MSC_VER npconfig->file=fopen(npconfig->filename,"a+b"); #else npconfig->file=fopen(npconfig->filename,"rw"); #endif // _MSC_VER if (npconfig->file!=NULL){ np_config_parse(npconfig); fclose(npconfig->file); /* make existing configuration files non-group/world-accessible */ //if (chmod(filename, S_IRUSR | S_IWUSR) == -1) // np_warning("unable to correct permissions on " // "configuration file: %s", // strerror(errno)); npconfig->file=NULL; npconfig->modified=0; } #endif // HAVE_SQLITE3 } return npconfig; }
connection_handle::connection_handle(connection_config conf) : config(conf), sqlite(nullptr) { auto rc = sqlite3_open_v2(conf.path_to_database.c_str(), &sqlite, conf.flags, conf.vfs.empty() ? nullptr : conf.vfs.c_str()); if (rc != SQLITE_OK) { const std::string msg = sqlite3_errmsg(sqlite); sqlite3_close(sqlite); throw sqlpp::exception("Sqlite3 error: Can't open database: " + msg); } #ifdef SQLITE_HAS_CODEC if (conf.password.size()>0) { int ret = sqlite3_key(sqlite, conf.password.data(),conf.password.size()+1); if (ret!=SQLITE_OK) { const std::string msg = sqlite3_errmsg(sqlite); sqlite3_close(sqlite); throw sqlpp::exception("Sqlite3 error: Can't set password to database: " + msg); } } #endif }
static int sqlcipher_check_connection(const char *filename, char *key, int key_sz, char *sql, int *user_version) { int rc; sqlite3 *db = NULL; sqlite3_stmt *statement = NULL; char *query_user_version = "PRAGMA user_version;"; rc = sqlite3_open(filename, &db); if(rc != SQLITE_OK){ goto cleanup; } rc = sqlite3_key(db, key, key_sz); if(rc != SQLITE_OK){ goto cleanup; } rc = sqlite3_exec(db, sql, NULL, NULL, NULL); if(rc != SQLITE_OK){ goto cleanup; } rc = sqlite3_prepare(db, query_user_version, -1, &statement, NULL); if(rc != SQLITE_OK){ goto cleanup; } rc = sqlite3_step(statement); if(rc == SQLITE_ROW){ *user_version = sqlite3_column_int(statement, 0); rc = SQLITE_OK; } cleanup: if(statement){ sqlite3_finalize(statement); } if(db){ sqlite3_close(db); } return rc; }
int sqlite3_key_v2(sqlite3 *db, const char *zDbName, const void *zKey, int nKey) { /* The key is only set for the main database, not the temp database */ return sqlite3_key(db, zKey, nKey); }
int main(int argc, char** argv) { sqlite3 * db; const char * key = "testkey"; const char * dbname = "./testdb"; int keylen = 7; char * error=0; fprintf(stderr, "Creating Database \"%s\"\n", dbname); int rc = sqlite3_open(dbname, &db); if (rc != SQLITE_OK) { fprintf(stderr, "Can't open/create database: %s\n", sqlite3_errmsg(db)); return 1; } fprintf(stderr, "Keying Database with key \"%s\"\n", key); rc = sqlite3_key(db, key, keylen); if (rc != SQLITE_OK) { fprintf(stderr, "Can't key database: %s\n", sqlite3_errmsg(db)); return 1; } fprintf(stderr, "Creating table \"test\"\n"); rc = sqlite3_exec(db, SQL::CREATE_TABLE_TEST, 0, 0, &error); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", error); return 1; } fprintf(stderr, "Creating table \"test2\"\n"); rc = sqlite3_exec(db, SQL::CREATE_TABLE_TEST2, 0, 0, &error); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", error); return 1; } fprintf(stderr, "Inserting into table \"test\"\n"); rc = sqlite3_exec(db, SQL::INSERT_INTO_TEST, 0, 0, &error); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", error); return 1; } fprintf(stderr, "Inserting into table \"test2\"\n"); rc = sqlite3_exec(db, SQL::INSERT_INTO_TEST2, 0, 0, &error); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", error); return 1; } fprintf(stderr, "Closing Database \"%s\"\n", dbname); sqlite3_close(db); fprintf(stderr, "Opening Database \"%s\"\n", dbname); rc = sqlite3_open(dbname, &db); if (rc != SQLITE_OK) { fprintf(stderr, "Can't open/create database: %s\n", sqlite3_errmsg(db)); return 1; } fprintf(stderr, "Keying Database with key \"%s\"\n", key); rc = sqlite3_key(db, key, keylen); if (rc != SQLITE_OK) { fprintf(stderr, "Can't key database: %s\n", sqlite3_errmsg(db)); return 1; } fprintf(stderr, "Selecting all from test\n"); rc = sqlite3_exec(db, SQL::SELECT_FROM_TEST, callback, 0, &error); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", error); return 1; } fprintf(stderr, "Selecting all from test2\n"); rc = sqlite3_exec(db, SQL::SELECT_FROM_TEST2, callback, 0, &error); if (rc != SQLITE_OK) { fprintf(stderr, "SQL error: %s\n", error); return 1; } fprintf(stderr, "Closing Database \"%s\"\n", dbname); sqlite3_close(db); fprintf(stderr, "All Seems Good \n"); return 0; }
int main(int argc, char* argv[]) { sqlite3 *db; char *zErrMsg = 0; int rc; char *sql; /* Open database */ rc = sqlite3_open("test.db", &db); if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stdout, "Opened database successfully\n"); } rc = sqlite3_key(db, passwd, strlen(passwd)); if( rc ){ fprintf(stderr, "Can't encrypt database: %s\n", sqlite3_errmsg(db)); exit(0); }else{ fprintf(stdout, "Encrypt database successfully\n"); } /* Create SQL statement */ sql = "CREATE TABLE IF NOT EXISTS COMPANY (" \ "ID INT PRIMARY KEY NOT NULL," \ "NAME TEXT NOT NULL," \ "AGE INT NOT NULL," \ "ADDRESS CHAR(50)," \ "SALARY REAL );"; //Create table /* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Table created successfully\n"); } sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \ "VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \ "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \ "VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); " \ "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \ "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \ "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \ "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );"; //Insert data /* Execute SQL statement */ rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Records created successfully\n"); } /* Create SQL statement */ sql = "SELECT * from COMPANY"; //Select data /* Execute SQL statement */ const char* data = "Callback function called"; rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg); if( rc != SQLITE_OK ){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); }else{ fprintf(stdout, "Operation done successfully\n"); } sqlite3_close(db); return 0; }
/* ** Process a pragma statement. ** ** Pragmas are of this form: ** ** PRAGMA [database.]id [= value] ** ** The identifier might also be a string. The value is a string, and ** identifier, or a number. If minusFlag is true, then the value is ** a number that was preceded by a minus sign. ** ** If the left side is "database.id" then pId1 is the database name ** and pId2 is the id. If the left side is just "id" then pId1 is the ** id and pId2 is any empty string. */ void sqlite3Pragma( Parse *pParse, Token *pId1, /* First part of [database.]id field */ Token *pId2, /* Second part of [database.]id field, or NULL */ Token *pValue, /* Token for <value>, or NULL */ int minusFlag /* True if a '-' sign preceded <value> */ ){ char *zLeft = 0; /* Nul-terminated UTF-8 string <id> */ char *zRight = 0; /* Nul-terminated UTF-8 string <value>, or NULL */ const char *zDb = 0; /* The database name */ Token *pId; /* Pointer to <id> token */ int iDb; /* Database index for <database> */ sqlite3 *db = pParse->db; Db *pDb; Vdbe *v = sqlite3GetVdbe(pParse); if( v==0 ) return; /* Interpret the [database.] part of the pragma statement. iDb is the ** index of the database this pragma is being applied to in db.aDb[]. */ iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); if( iDb<0 ) return; pDb = &db->aDb[iDb]; zLeft = sqlite3NameFromToken(pId); if( !zLeft ) return; if( minusFlag ){ zRight = sqlite3MPrintf("-%T", pValue); }else{ zRight = sqlite3NameFromToken(pValue); } zDb = ((iDb>0)?pDb->zName:0); if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ goto pragma_out; } #ifndef SQLITE_OMIT_PAGER_PRAGMAS /* ** PRAGMA [database.]default_cache_size ** PRAGMA [database.]default_cache_size=N ** ** The first form reports the current persistent setting for the ** page cache size. The value returned is the maximum number of ** pages in the page cache. The second form sets both the current ** page cache size value and the persistent page cache size value ** stored in the database file. ** ** The default cache size is stored in meta-value 2 of page 1 of the ** database file. The cache size is actually the absolute value of ** this memory location. The sign of meta-value 2 determines the ** synchronous setting. A negative value means synchronous is off ** and a positive value means synchronous is on. */ if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ static const VdbeOpList getCacheSize[] = { { OP_ReadCookie, 0, 2, 0}, /* 0 */ { OP_AbsValue, 0, 0, 0}, { OP_Dup, 0, 0, 0}, { OP_Integer, 0, 0, 0}, { OP_Ne, 0, 6, 0}, { OP_Integer, 0, 0, 0}, /* 5 */ { OP_Callback, 1, 0, 0}, }; int addr; if( sqlite3ReadSchema(pParse) ) goto pragma_out; if( !zRight ){ sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", P3_STATIC); addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP1(v, addr+5, MAX_PAGES); }else{ int size = atoi(zRight); if( size<0 ) size = -size; sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3VdbeAddOp(v, OP_Integer, size, 0); sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 2); addr = sqlite3VdbeAddOp(v, OP_Integer, 0, 0); sqlite3VdbeAddOp(v, OP_Ge, 0, addr+3); sqlite3VdbeAddOp(v, OP_Negative, 0, 0); sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 2); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } }else /* ** PRAGMA [database.]page_size ** PRAGMA [database.]page_size=N ** ** The first form reports the current setting for the ** database page size in bytes. The second form sets the ** database page size value. The value can only be set if ** the database has not yet been created. */ if( sqlite3StrICmp(zLeft,"page_size")==0 ){ Btree *pBt = pDb->pBt; if( !zRight ){ int size = pBt ? sqlite3BtreeGetPageSize(pBt) : 0; returnSingleInt(pParse, "page_size", size); }else{ sqlite3BtreeSetPageSize(pBt, atoi(zRight), -1); } }else #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ /* ** PRAGMA [database.]auto_vacuum ** PRAGMA [database.]auto_vacuum=N ** ** Get or set the (boolean) value of the database 'auto-vacuum' parameter. */ #ifndef SQLITE_OMIT_AUTOVACUUM if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){ Btree *pBt = pDb->pBt; if( !zRight ){ int auto_vacuum = pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM; returnSingleInt(pParse, "auto_vacuum", auto_vacuum); }else{ sqlite3BtreeSetAutoVacuum(pBt, getBoolean(zRight)); } }else #endif #ifndef SQLITE_OMIT_PAGER_PRAGMAS /* ** PRAGMA [database.]cache_size ** PRAGMA [database.]cache_size=N ** ** The first form reports the current local setting for the ** page cache size. The local setting can be different from ** the persistent cache size value that is stored in the database ** file itself. The value returned is the maximum number of ** pages in the page cache. The second form sets the local ** page cache size value. It does not change the persistent ** cache size stored on the disk so the cache size will revert ** to its default value when the database is closed and reopened. ** N should be a positive integer. */ if( sqlite3StrICmp(zLeft,"cache_size")==0 ){ if( sqlite3ReadSchema(pParse) ) goto pragma_out; if( !zRight ){ returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); }else{ int size = atoi(zRight); if( size<0 ) size = -size; pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } }else /* ** PRAGMA temp_store ** PRAGMA temp_store = "default"|"memory"|"file" ** ** Return or set the local value of the temp_store flag. Changing ** the local value does not make changes to the disk file and the default ** value will be restored the next time the database is opened. ** ** Note that it is possible for the library compile-time options to ** override this setting */ if( sqlite3StrICmp(zLeft, "temp_store")==0 ){ if( !zRight ){ returnSingleInt(pParse, "temp_store", db->temp_store); }else{ changeTempStorage(pParse, zRight); } }else /* ** PRAGMA temp_store_directory ** PRAGMA temp_store_directory = ""|"directory_name" ** ** Return or set the local value of the temp_store_directory flag. Changing ** the value sets a specific directory to be used for temporary files. ** Setting to a null string reverts to the default temporary directory search. ** If temporary directory is changed, then invalidateTempStorage. ** */ if( sqlite3StrICmp(zLeft, "temp_store_directory")==0 ){ if( !zRight ){ if( sqlite3_temp_directory ){ sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "temp_store_directory", P3_STATIC); sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3_temp_directory, 0); sqlite3VdbeAddOp(v, OP_Callback, 1, 0); } }else{ if( zRight[0] && !sqlite3OsIsDirWritable(zRight) ){ sqlite3ErrorMsg(pParse, "not a writable directory"); goto pragma_out; } if( TEMP_STORE==0 || (TEMP_STORE==1 && db->temp_store<=1) || (TEMP_STORE==2 && db->temp_store==1) ){ invalidateTempStorage(pParse); } sqliteFree(sqlite3_temp_directory); if( zRight[0] ){ sqlite3_temp_directory = zRight; zRight = 0; }else{ sqlite3_temp_directory = 0; } } }else /* ** PRAGMA [database.]synchronous ** PRAGMA [database.]synchronous=OFF|ON|NORMAL|FULL ** ** Return or set the local value of the synchronous flag. Changing ** the local value does not make changes to the disk file and the ** default value will be restored the next time the database is ** opened. */ if( sqlite3StrICmp(zLeft,"synchronous")==0 ){ if( sqlite3ReadSchema(pParse) ) goto pragma_out; if( !zRight ){ returnSingleInt(pParse, "synchronous", pDb->safety_level-1); }else{ if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); }else{ pDb->safety_level = getSafetyLevel(zRight)+1; } } }else #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ #ifndef SQLITE_OMIT_FLAG_PRAGMAS if( flagPragma(pParse, zLeft, zRight) ){ /* The flagPragma() subroutine also generates any necessary code ** there is nothing more to do here */ }else #endif /* SQLITE_OMIT_FLAG_PRAGMAS */ #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS /* ** PRAGMA table_info(<table>) ** ** Return a single row for each column of the named table. The columns of ** the returned data set are: ** ** cid: Column id (numbered from left to right, starting at 0) ** name: Column name ** type: Column declaration type. ** notnull: True if 'NOT NULL' is part of column declaration ** dflt_value: The default value for the column, if any. */ if( sqlite3StrICmp(zLeft, "table_info")==0 && zRight ){ Table *pTab; if( sqlite3ReadSchema(pParse) ) goto pragma_out; pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ int i; Column *pCol; sqlite3VdbeSetNumCols(v, 6); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cid", P3_STATIC); sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC); sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "type", P3_STATIC); sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "notnull", P3_STATIC); sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "dflt_value", P3_STATIC); sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "pk", P3_STATIC); sqlite3ViewGetColumnNames(pParse, pTab); for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){ sqlite3VdbeAddOp(v, OP_Integer, i, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zName, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pCol->zType ? pCol->zType : "numeric", 0); sqlite3VdbeAddOp(v, OP_Integer, pCol->notNull, 0); sqlite3ExprCode(pParse, pCol->pDflt); sqlite3VdbeAddOp(v, OP_Integer, pCol->isPrimKey, 0); sqlite3VdbeAddOp(v, OP_Callback, 6, 0); } } }else if( sqlite3StrICmp(zLeft, "index_info")==0 && zRight ){ Index *pIdx; Table *pTab; if( sqlite3ReadSchema(pParse) ) goto pragma_out; pIdx = sqlite3FindIndex(db, zRight, zDb); if( pIdx ){ int i; pTab = pIdx->pTable; sqlite3VdbeSetNumCols(v, 3); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", P3_STATIC); sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", P3_STATIC); sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", P3_STATIC); for(i=0; i<pIdx->nColumn; i++){ int cnum = pIdx->aiColumn[i]; sqlite3VdbeAddOp(v, OP_Integer, i, 0); sqlite3VdbeAddOp(v, OP_Integer, cnum, 0); assert( pTab->nCol>cnum ); sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[cnum].zName, 0); sqlite3VdbeAddOp(v, OP_Callback, 3, 0); } } }else if( sqlite3StrICmp(zLeft, "index_list")==0 && zRight ){ Index *pIdx; Table *pTab; if( sqlite3ReadSchema(pParse) ) goto pragma_out; pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ v = sqlite3GetVdbe(pParse); pIdx = pTab->pIndex; if( pIdx ){ int i = 0; sqlite3VdbeSetNumCols(v, 3); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC); sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC); sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", P3_STATIC); while(pIdx){ sqlite3VdbeAddOp(v, OP_Integer, i, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pIdx->zName, 0); sqlite3VdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0); sqlite3VdbeAddOp(v, OP_Callback, 3, 0); ++i; pIdx = pIdx->pNext; } } } }else if( sqlite3StrICmp(zLeft, "database_list")==0 ){ int i; if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3VdbeSetNumCols(v, 3); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC); sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC); sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "file", P3_STATIC); for(i=0; i<db->nDb; i++){ if( db->aDb[i].pBt==0 ) continue; assert( db->aDb[i].zName!=0 ); sqlite3VdbeAddOp(v, OP_Integer, i, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3BtreeGetFilename(db->aDb[i].pBt), 0); sqlite3VdbeAddOp(v, OP_Callback, 3, 0); } }else if( sqlite3StrICmp(zLeft, "collation_list")==0 ){ int i = 0; HashElem *p; sqlite3VdbeSetNumCols(v, 2); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", P3_STATIC); sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", P3_STATIC); for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ CollSeq *pColl = (CollSeq *)sqliteHashData(p); sqlite3VdbeAddOp(v, OP_Integer, i++, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pColl->zName, 0); sqlite3VdbeAddOp(v, OP_Callback, 2, 0); } }else #endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */ #ifndef SQLITE_OMIT_FOREIGN_KEY if( sqlite3StrICmp(zLeft, "foreign_key_list")==0 && zRight ){ FKey *pFK; Table *pTab; if( sqlite3ReadSchema(pParse) ) goto pragma_out; pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ v = sqlite3GetVdbe(pParse); pFK = pTab->pFKey; if( pFK ){ int i = 0; sqlite3VdbeSetNumCols(v, 5); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "id", P3_STATIC); sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "seq", P3_STATIC); sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "table", P3_STATIC); sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "from", P3_STATIC); sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "to", P3_STATIC); while(pFK){ int j; for(j=0; j<pFK->nCol; j++){ char *zCol = pFK->aCol[j].zCol; sqlite3VdbeAddOp(v, OP_Integer, i, 0); sqlite3VdbeAddOp(v, OP_Integer, j, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pFK->zTo, 0); sqlite3VdbeOp3(v, OP_String8, 0, 0, pTab->aCol[pFK->aCol[j].iFrom].zName, 0); sqlite3VdbeOp3(v, zCol ? OP_String8 : OP_Null, 0, 0, zCol, 0); sqlite3VdbeAddOp(v, OP_Callback, 5, 0); } ++i; pFK = pFK->pNextFrom; } } } }else #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ #ifndef NDEBUG if( sqlite3StrICmp(zLeft, "parser_trace")==0 ){ extern void sqlite3ParserTrace(FILE*, char *); if( zRight ){ if( getBoolean(zRight) ){ sqlite3ParserTrace(stderr, "parser: "); }else{ sqlite3ParserTrace(0, 0); } } }else #endif /* Reinstall the LIKE and GLOB functions. The variant of LIKE ** used will be case sensitive or not depending on the RHS. */ if( sqlite3StrICmp(zLeft, "case_sensitive_like")==0 ){ if( zRight ){ sqlite3RegisterLikeFunctions(db, getBoolean(zRight)); } }else #ifndef SQLITE_OMIT_INTEGRITY_CHECK if( sqlite3StrICmp(zLeft, "integrity_check")==0 ){ int i, j, addr; /* Code that appears at the end of the integrity check. If no error ** messages have been generated, output OK. Otherwise output the ** error message */ static const VdbeOpList endCode[] = { { OP_MemLoad, 0, 0, 0}, { OP_Integer, 0, 0, 0}, { OP_Ne, 0, 0, 0}, /* 2 */ { OP_String8, 0, 0, "ok"}, { OP_Callback, 1, 0, 0}, }; /* Initialize the VDBE program */ if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "integrity_check", P3_STATIC); sqlite3VdbeAddOp(v, OP_MemInt, 0, 0); /* Initialize error count to 0 */ /* Do an integrity check on each database file */ for(i=0; i<db->nDb; i++){ HashElem *x; Hash *pTbls; int cnt = 0; if( OMIT_TEMPDB && i==1 ) continue; sqlite3CodeVerifySchema(pParse, i); /* Do an integrity check of the B-Tree */ pTbls = &db->aDb[i].pSchema->tblHash; for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; sqlite3VdbeAddOp(v, OP_Integer, pTab->tnum, 0); cnt++; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ sqlite3VdbeAddOp(v, OP_Integer, pIdx->tnum, 0); cnt++; } } assert( cnt>0 ); sqlite3VdbeAddOp(v, OP_IntegrityCk, cnt, i); sqlite3VdbeAddOp(v, OP_Dup, 0, 1); addr = sqlite3VdbeOp3(v, OP_String8, 0, 0, "ok", P3_STATIC); sqlite3VdbeAddOp(v, OP_Eq, 0, addr+7); sqlite3VdbeOp3(v, OP_String8, 0, 0, sqlite3MPrintf("*** in database %s ***\n", db->aDb[i].zName), P3_DYNAMIC); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); sqlite3VdbeAddOp(v, OP_Concat, 0, 1); sqlite3VdbeAddOp(v, OP_Callback, 1, 0); sqlite3VdbeAddOp(v, OP_MemIncr, 1, 0); /* Make sure all the indices are constructed correctly. */ sqlite3CodeVerifySchema(pParse, i); for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); Index *pIdx; int loopTop; if( pTab->pIndex==0 ) continue; sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead); sqlite3VdbeAddOp(v, OP_MemInt, 0, 1); loopTop = sqlite3VdbeAddOp(v, OP_Rewind, 1, 0); sqlite3VdbeAddOp(v, OP_MemIncr, 1, 1); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2; static const VdbeOpList idxErr[] = { { OP_MemIncr, 1, 0, 0}, { OP_String8, 0, 0, "rowid "}, { OP_Rowid, 1, 0, 0}, { OP_String8, 0, 0, " missing from index "}, { OP_String8, 0, 0, 0}, /* 4 */ { OP_Concat, 2, 0, 0}, { OP_Callback, 1, 0, 0}, }; sqlite3GenerateIndexKey(v, pIdx, 1); jmp2 = sqlite3VdbeAddOp(v, OP_Found, j+2, 0); addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr); sqlite3VdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC); sqlite3VdbeJumpHere(v, jmp2); } sqlite3VdbeAddOp(v, OP_Next, 1, loopTop+1); sqlite3VdbeJumpHere(v, loopTop); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ static const VdbeOpList cntIdx[] = { { OP_MemInt, 0, 2, 0}, { OP_Rewind, 0, 0, 0}, /* 1 */ { OP_MemIncr, 1, 2, 0}, { OP_Next, 0, 0, 0}, /* 3 */ { OP_MemLoad, 1, 0, 0}, { OP_MemLoad, 2, 0, 0}, { OP_Eq, 0, 0, 0}, /* 6 */ { OP_MemIncr, 1, 0, 0}, { OP_String8, 0, 0, "wrong # of entries in index "}, { OP_String8, 0, 0, 0}, /* 9 */ { OP_Concat, 0, 0, 0}, { OP_Callback, 1, 0, 0}, }; if( pIdx->tnum==0 ) continue; addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx); sqlite3VdbeChangeP1(v, addr+1, j+2); sqlite3VdbeChangeP2(v, addr+1, addr+4); sqlite3VdbeChangeP1(v, addr+3, j+2); sqlite3VdbeChangeP2(v, addr+3, addr+2); sqlite3VdbeJumpHere(v, addr+6); sqlite3VdbeChangeP3(v, addr+9, pIdx->zName, P3_STATIC); } } } addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode); sqlite3VdbeJumpHere(v, addr+2); }else #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ #ifndef SQLITE_OMIT_UTF16 /* ** PRAGMA encoding ** PRAGMA encoding = "utf-8"|"utf-16"|"utf-16le"|"utf-16be" ** ** In it's first form, this pragma returns the encoding of the main ** database. If the database is not initialized, it is initialized now. ** ** The second form of this pragma is a no-op if the main database file ** has not already been initialized. In this case it sets the default ** encoding that will be used for the main database file if a new file ** is created. If an existing main database file is opened, then the ** default text encoding for the existing database is used. ** ** In all cases new databases created using the ATTACH command are ** created to use the same default text encoding as the main database. If ** the main database has not been initialized and/or created when ATTACH ** is executed, this is done before the ATTACH operation. ** ** In the second form this pragma sets the text encoding to be used in ** new database files created using this database handle. It is only ** useful if invoked immediately after the main database i */ if( sqlite3StrICmp(zLeft, "encoding")==0 ){ static struct EncName { char *zName; u8 enc; } encnames[] = { { "UTF-8", SQLITE_UTF8 }, { "UTF8", SQLITE_UTF8 }, { "UTF-16le", SQLITE_UTF16LE }, { "UTF16le", SQLITE_UTF16LE }, { "UTF-16be", SQLITE_UTF16BE }, { "UTF16be", SQLITE_UTF16BE }, { "UTF-16", 0 /* Filled in at run-time */ }, { "UTF16", 0 /* Filled in at run-time */ }, { 0, 0 } }; struct EncName *pEnc; encnames[6].enc = encnames[7].enc = SQLITE_UTF16NATIVE; if( !zRight ){ /* "PRAGMA encoding" */ if( sqlite3ReadSchema(pParse) ) goto pragma_out; sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "encoding", P3_STATIC); sqlite3VdbeAddOp(v, OP_String8, 0, 0); for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ if( pEnc->enc==ENC(pParse->db) ){ sqlite3VdbeChangeP3(v, -1, pEnc->zName, P3_STATIC); break; } } sqlite3VdbeAddOp(v, OP_Callback, 1, 0); }else{ /* "PRAGMA encoding = XXX" */ /* Only change the value of sqlite.enc if the database handle is not ** initialized. If the main database exists, the new sqlite.enc value ** will be overwritten when the schema is next loaded. If it does not ** already exists, it will be created to use the new encoding value. */ if( !(DbHasProperty(db, 0, DB_SchemaLoaded)) || DbHasProperty(db, 0, DB_Empty) ){ for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ ENC(pParse->db) = pEnc->enc; break; } } if( !pEnc->zName ){ sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight); } } } }else #endif /* SQLITE_OMIT_UTF16 */ #ifndef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS /* ** PRAGMA [database.]schema_version ** PRAGMA [database.]schema_version = <integer> ** ** PRAGMA [database.]user_version ** PRAGMA [database.]user_version = <integer> ** ** The pragma's schema_version and user_version are used to set or get ** the value of the schema-version and user-version, respectively. Both ** the schema-version and the user-version are 32-bit signed integers ** stored in the database header. ** ** The schema-cookie is usually only manipulated internally by SQLite. It ** is incremented by SQLite whenever the database schema is modified (by ** creating or dropping a table or index). The schema version is used by ** SQLite each time a query is executed to ensure that the internal cache ** of the schema used when compiling the SQL query matches the schema of ** the database against which the compiled query is actually executed. ** Subverting this mechanism by using "PRAGMA schema_version" to modify ** the schema-version is potentially dangerous and may lead to program ** crashes or database corruption. Use with caution! ** ** The user-version is not used internally by SQLite. It may be used by ** applications for any purpose. */ if( sqlite3StrICmp(zLeft, "schema_version")==0 || sqlite3StrICmp(zLeft, "user_version")==0 ){ int iCookie; /* Cookie index. 0 for schema-cookie, 6 for user-cookie. */ if( zLeft[0]=='s' || zLeft[0]=='S' ){ iCookie = 0; }else{ iCookie = 5; } if( zRight ){ /* Write the specified cookie value */ static const VdbeOpList setCookie[] = { { OP_Transaction, 0, 1, 0}, /* 0 */ { OP_Integer, 0, 0, 0}, /* 1 */ { OP_SetCookie, 0, 0, 0}, /* 2 */ }; int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie); sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP1(v, addr+1, atoi(zRight)); sqlite3VdbeChangeP1(v, addr+2, iDb); sqlite3VdbeChangeP2(v, addr+2, iCookie); }else{ /* Read the specified cookie value */ static const VdbeOpList readCookie[] = { { OP_ReadCookie, 0, 0, 0}, /* 0 */ { OP_Callback, 1, 0, 0} }; int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie); sqlite3VdbeChangeP1(v, addr, iDb); sqlite3VdbeChangeP2(v, addr, iCookie); sqlite3VdbeSetNumCols(v, 1); } } #endif /* SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS */ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* ** Report the current state of file logs for all databases */ if( sqlite3StrICmp(zLeft, "lock_status")==0 ){ static const char *const azLockName[] = { "unlocked", "shared", "reserved", "pending", "exclusive" }; int i; Vdbe *v = sqlite3GetVdbe(pParse); sqlite3VdbeSetNumCols(v, 2); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "database", P3_STATIC); sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "status", P3_STATIC); for(i=0; i<db->nDb; i++){ Btree *pBt; Pager *pPager; if( db->aDb[i].zName==0 ) continue; sqlite3VdbeOp3(v, OP_String8, 0, 0, db->aDb[i].zName, P3_STATIC); pBt = db->aDb[i].pBt; if( pBt==0 || (pPager = sqlite3BtreePager(pBt))==0 ){ sqlite3VdbeOp3(v, OP_String8, 0, 0, "closed", P3_STATIC); }else{ int j = sqlite3pager_lockstate(pPager); sqlite3VdbeOp3(v, OP_String8, 0, 0, (j>=0 && j<=4) ? azLockName[j] : "unknown", P3_STATIC); } sqlite3VdbeAddOp(v, OP_Callback, 2, 0); } }else #endif #ifdef SQLITE_SSE /* ** Check to see if the sqlite_statements table exists. Create it ** if it does not. */ if( sqlite3StrICmp(zLeft, "create_sqlite_statement_table")==0 ){ extern int sqlite3CreateStatementsTable(Parse*); sqlite3CreateStatementsTable(pParse); }else #endif #if SQLITE_HAS_CODEC if( sqlite3StrICmp(zLeft, "key")==0 ){ sqlite3_key(db, zRight, strlen(zRight)); }else #endif {} if( v ){ /* Code an OP_Expire at the end of each PRAGMA program to cause ** the VDBE implementing the pragma to expire. Most (all?) pragmas ** are only valid for a single execution. */ sqlite3VdbeAddOp(v, OP_Expire, 1, 0); /* ** Reset the safety level, in case the fullfsync flag or synchronous ** setting changed. */ if( db->autoCommit ){ sqlite3BtreeSetSafetyLevel(pDb->pBt, pDb->safety_level, (db->flags&SQLITE_FullFSync)!=0); } } pragma_out: sqliteFree(zLeft); sqliteFree(zRight); }
/* ** Copy nPage pages from the source b-tree to the destination. */ int sqlite3_backup_step(sqlite3_backup *p, int nPage) { int returnCode, pages; Parse parse; DB_ENV *dbenv; BtShared *pBtDest, *pBtSrc; pBtDest = pBtSrc = NULL; if (p->rc != SQLITE_OK || nPage == 0) return p->rc; sqlite3_mutex_enter(p->pSrcDb->mutex); sqlite3_mutex_enter(p->pDestDb->mutex); /* * Make sure the schema has been read in, so the keyInfo * can be retrieved for the indexes. No-op if already read. * If the schema has not been read then an update must have * changed it, so backup will restart. */ memset(&parse, 0, sizeof(parse)); parse.db = p->pSrcDb; p->rc = sqlite3ReadSchema(&parse); if (p->rc != SQLITE_OK) goto err; /* * This process updated the source database, so * the backup process has to restart. */ if (p->pSrc->updateDuringBackup > p->lastUpdate) { p->rc = SQLITE_LOCKED; if ((p->rc = backupCleanup(p)) != SQLITE_OK) goto err; else backupReset(p); } pages = nPage; if (!p->cleaned) { const char *home; const char inmem[9] = ":memory:"; int storage; pBtDest = p->pDest->pBt; storage = p->pDest->pBt->dbStorage; if (storage == DB_STORE_NAMED) p->openDest = 1; p->rc = btreeDeleteEnvironment(p->pDest, p->fullName, 1); if (storage == DB_STORE_INMEM && strcmp(p->destName, "temp") != 0) home = inmem; else home = p->fullName; p->pDest = p->pDestDb->aDb[p->iDb].pBt; if (p->rc != SQLITE_OK) goto err; /* * Call sqlite3OpenTempDatabase instead of * sqlite3BtreeOpen, because sqlite3OpenTempDatabase * automatically chooses the right flags before calling * sqlite3BtreeOpen. */ if (strcmp(p->destName, "temp") == 0) { memset(&parse, 0, sizeof(parse)); parse.db = p->pDestDb; p->rc = sqlite3OpenTempDatabase(&parse); p->pDest = p->pDestDb->aDb[p->iDb].pBt; } else { p->rc = sqlite3BtreeOpen(home, p->pDestDb, &p->pDest, SQLITE_DEFAULT_CACHE_SIZE | SQLITE_OPEN_MAIN_DB, p->pDestDb->openFlags); p->pDestDb->aDb[p->iDb].pBt = p->pDest; if (p->rc == SQLITE_OK) { p->pDestDb->aDb[p->iDb].pSchema = sqlite3SchemaGet(p->pDestDb, p->pDest); if (!p->pDestDb->aDb[p->iDb].pSchema) p->rc = SQLITE_NOMEM; } else p->pDestDb->aDb[p->iDb].pSchema = NULL; } if (p->pDest) p->pDest->nBackup++; #ifdef SQLITE_HAS_CODEC /* * In the case of a temporary source database, use the * encryption of the main database. */ if (strcmp(p->srcName, "temp") == 0) { int iDb = sqlite3FindDbName(p->pSrcDb, "main"); pBtSrc = p->pSrcDb->aDb[iDb].pBt->pBt; } else pBtSrc = p->pSrc->pBt; if (p->rc == SQLITE_OK) { if (p->iDb == 0) p->rc = sqlite3_key(p->pDestDb, pBtSrc->encrypt_pwd, pBtSrc->encrypt_pwd_len); else p->rc = sqlite3CodecAttach(p->pDestDb, p->iDb, pBtSrc->encrypt_pwd, pBtSrc->encrypt_pwd_len); } #endif if (p->rc != SQLITE_OK) goto err; p->cleaned = 1; } /* * Begin a transaction, unfortuantely the lock on * the schema has to be released to allow the sqlite_master * table to be cleared, which could allow another thread to * alter it, however accessing the backup database during * backup is already an illegal condition with undefined * results. */ if (!sqlite3BtreeIsInTrans(p->pDest)) { if (!p->pDest->connected) { p->rc = btreeOpenEnvironment(p->pDest, 1); if (p->rc != SQLITE_OK) goto err; } if ((p->rc = sqlite3BtreeBeginTrans(p->pDest, 2)) != SQLITE_OK) goto err; } /* Only this process should be accessing the backup environment. */ if (p->pDest->pBt->nRef > 1) { p->rc = SQLITE_BUSY; goto err; } /* * Begin a transaction, a lock error or update could have caused * it to be released in a previous call to step. */ if (!p->srcTxn) { dbenv = p->pSrc->pBt->dbenv; if ((p->rc = dberr2sqlite(dbenv->txn_begin(dbenv, p->pSrc->family_txn, &p->srcTxn, 0))) != SQLITE_OK) goto err; } /* * An update could have dropped or created a table, so recalculate * the list of tables. */ if (!p->tables) { if ((p->rc = btreeGetPageCount(p->pSrc, &p->tables, &p->nPagecount, p->srcTxn)) != SQLITE_OK) { sqlite3Error(p->pSrcDb, p->rc, 0); goto err; } p->nRemaining = p->nPagecount; } /* Copy the pages. */ p->rc = btreeCopyPages(p, &pages); if (p->rc == SQLITE_DONE) { p->nRemaining = 0; sqlite3ResetInternalSchema(p->pDestDb, p->iDb); memset(&parse, 0, sizeof(parse)); parse.db = p->pDestDb; p->rc = sqlite3ReadSchema(&parse); if (p->rc == SQLITE_OK) p->rc = SQLITE_DONE; } else if (p->rc != SQLITE_OK) goto err; /* * The number of pages left to copy is an estimate, so * do not let the number go to zero unless we are really * done. */ if (p->rc != SQLITE_DONE) { if ((u32)pages >= p->nRemaining) p->nRemaining = 1; else p->nRemaining -= pages; } err: /* * This process updated the source database, so * the backup process has to restart. */ if (p->pSrc->updateDuringBackup > p->lastUpdate && (p->rc == SQLITE_OK || p->rc == SQLITE_DONE)) { int cleanCode; returnCode = p->rc; p->rc = SQLITE_LOCKED; if ((cleanCode = backupCleanup(p)) != SQLITE_OK) returnCode = p->rc = cleanCode; else backupReset(p); } else { returnCode = backupCleanup(p); if (returnCode == SQLITE_OK || (p->rc != SQLITE_OK && p->rc != SQLITE_DONE)) returnCode = p->rc; else p->rc = returnCode; } /* * On a locked or busy error the backup process is rolled back, * but can be restarted by the user. */ if ( returnCode == SQLITE_LOCKED || returnCode == SQLITE_BUSY ) backupReset(p); else if ( returnCode != SQLITE_OK && returnCode != SQLITE_DONE ) { sqlite3Error(p->pDestDb, p->rc, 0); } sqlite3_mutex_leave(p->pDestDb->mutex); sqlite3_mutex_leave(p->pSrcDb->mutex); return (returnCode); }