diff options
Diffstat (limited to 'src/wrap/sqlite')
-rw-r--r-- | src/wrap/sqlite/codec.cpp | 203 | ||||
-rw-r--r-- | src/wrap/sqlite/codec.h | 106 | ||||
-rw-r--r-- | src/wrap/sqlite/codec_c_interface.h | 90 | ||||
-rw-r--r-- | src/wrap/sqlite/codecext.c | 242 | ||||
-rw-r--r-- | src/wrap/sqlite/readme.txt | 35 | ||||
-rw-r--r-- | src/wrap/sqlite/sqlite3-amalgamation.patch | 15 | ||||
-rw-r--r-- | src/wrap/sqlite/test_sqlite.cpp | 103 |
7 files changed, 0 insertions, 794 deletions
diff --git a/src/wrap/sqlite/codec.cpp b/src/wrap/sqlite/codec.cpp deleted file mode 100644 index 70519ccfa..000000000 --- a/src/wrap/sqlite/codec.cpp +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Codec class for SQLite3 encryption codec. - * (C) 2010 Olivier de Gaalon - * - * Distributed under the terms of the Botan license - */ - -#include "codec.h" -#include <botan/init.h> - -Codec::Codec(void *db) -{ - InitializeCodec(db); -} - -Codec::Codec(const Codec *other, void *db) -{ - //Only used to copy main db key for an attached db - InitializeCodec(db); - m_hasReadKey = other->m_hasReadKey; - m_hasWriteKey = other->m_hasWriteKey; - m_readKey = other->m_readKey; - m_ivReadKey = other->m_ivReadKey; - m_writeKey = other->m_writeKey; - m_ivWriteKey = other->m_ivWriteKey; -} - -void Codec::InitializeCodec(void *db) -{ - m_hasReadKey = false; - m_hasWriteKey = false; - m_db = db; - - try - { - m_encipherFilter = get_cipher(BLOCK_CIPHER_STR, ENCRYPTION); - m_decipherFilter = get_cipher(BLOCK_CIPHER_STR, DECRYPTION); - m_cmac = new MAC_Filter(MAC_STR); - m_encipherPipe.append(m_encipherFilter); - m_decipherPipe.append(m_decipherFilter); - m_macPipe.append(m_cmac); - } - catch(Botan::Exception e) - { - m_botanErrorMsg = e.what(); - } -} - -void Codec::GenerateWriteKey(const char *userPassword, int passwordLength) -{ - try - { -#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,9,4) - PBKDF *pbkdf = get_pbkdf(PBKDF_STR); - SymmetricKey masterKey = - pbkdf->derive_key(KEY_SIZE + IV_DERIVATION_KEY_SIZE, std::string(userPassword, passwordLength), - (const byte*)SALT_STR.c_str(), SALT_SIZE, PBKDF_ITERATIONS); -#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,8,0) - S2K* s2k = get_s2k(PBKDF_STR); - s2k->set_iterations(PBKDF_ITERATIONS); - s2k->change_salt((const byte*)SALT_STR.c_str(), SALT_SIZE); - - SymmetricKey masterKey = - s2k->derive_key(KEY_SIZE + IV_DERIVATION_KEY_SIZE, std::string(userPassword, passwordLength)); -#else -#error "This code requires botan 1.8 or newer" -#endif - m_writeKey = SymmetricKey(masterKey.bits_of(), KEY_SIZE); - m_ivWriteKey = SymmetricKey(masterKey.bits_of() + KEY_SIZE, IV_DERIVATION_KEY_SIZE); - - m_hasWriteKey = true; - } - catch(Botan::Exception e) - { - m_botanErrorMsg = e.what(); - } -} - -void Codec::DropWriteKey() -{ - m_hasWriteKey = false; -} - -void Codec::SetReadIsWrite() -{ - m_readKey = m_writeKey; - m_ivReadKey = m_ivWriteKey; - m_hasReadKey = m_hasWriteKey; -} - -void Codec::SetWriteIsRead() -{ - m_writeKey = m_readKey; - m_ivWriteKey = m_ivReadKey; - m_hasWriteKey = m_hasReadKey; -} - -unsigned char* Codec::Encrypt(int page, unsigned char *data, bool useWriteKey) -{ - memcpy(m_page, data, m_pageSize); - - try - { - m_encipherFilter->set_key(useWriteKey ? m_writeKey : m_readKey); - m_encipherFilter->set_iv(GetIVForPage(page, useWriteKey)); - m_encipherPipe.process_msg(m_page, m_pageSize); - m_encipherPipe.read(m_page, m_encipherPipe.remaining(Pipe::LAST_MESSAGE), Pipe::LAST_MESSAGE); - } - catch(Botan::Exception e) - { - m_botanErrorMsg = e.what(); - } - - return m_page; //return location of newly ciphered data -} - -void Codec::Decrypt(int page, unsigned char *data) -{ - try - { - m_decipherFilter->set_key(m_readKey); - m_decipherFilter->set_iv(GetIVForPage(page, false)); - m_decipherPipe.process_msg(data, m_pageSize); - m_decipherPipe.read(data, m_decipherPipe.remaining(Pipe::LAST_MESSAGE), Pipe::LAST_MESSAGE); - } - catch(Botan::Exception e) - { - m_botanErrorMsg = e.what(); - } -} - -InitializationVector Codec::GetIVForPage(u32bit page, bool useWriteKey) -{ - try - { - static unsigned char *intiv[4]; - store_le(page, (byte*)intiv); - m_cmac->set_key(useWriteKey ? m_ivWriteKey : m_ivReadKey); - m_macPipe.process_msg((byte*)intiv, 4); - return m_macPipe.read_all(Pipe::LAST_MESSAGE); - } - catch(Botan::Exception e) - { - m_botanErrorMsg = e.what(); - } -} - -const char* Codec::GetAndResetError() -{ - const char *message = m_botanErrorMsg; - m_botanErrorMsg = 0; - return message; -} - -#include "codec_c_interface.h" - -void InitializeBotan() { - LibraryInitializer::initialize(); -} -void* InitializeNewCodec(void *db) { - return new Codec(db); -} -void* InitializeFromOtherCodec(const void *otherCodec, void *db) { - return new Codec((Codec*)otherCodec, db); -} -void GenerateWriteKey(void *codec, const char *userPassword, int passwordLength) { - ((Codec*)codec)->GenerateWriteKey(userPassword, passwordLength); -} -void DropWriteKey(void *codec) { - ((Codec*)codec)->DropWriteKey(); -} -void SetWriteIsRead(void *codec) { - ((Codec*)codec)->SetWriteIsRead(); -} -void SetReadIsWrite(void *codec) { - ((Codec*)codec)->SetReadIsWrite(); -} -unsigned char* Encrypt(void *codec, int page, unsigned char *data, Bool useWriteKey) { - return ((Codec*)codec)->Encrypt(page, data, useWriteKey); -} -void Decrypt(void *codec, int page, unsigned char *data) { - ((Codec*)codec)->Decrypt(page, data); -} -void SetPageSize(void *codec, int pageSize) { - ((Codec*)codec)->SetPageSize(pageSize); -} -Bool HasReadKey(void *codec) { - return ((Codec*)codec)->HasReadKey(); -} -Bool HasWriteKey(void *codec) { - return ((Codec*)codec)->HasWriteKey(); -} -void* GetDB(void *codec) { - return ((Codec*)codec)->GetDB(); -} -const char* GetAndResetError(void *codec) -{ - return ((Codec*)codec)->GetAndResetError(); -} -void DeleteCodec(void *codec) { - Codec *deleteThisCodec = (Codec*)codec; - delete deleteThisCodec; -} diff --git a/src/wrap/sqlite/codec.h b/src/wrap/sqlite/codec.h deleted file mode 100644 index 2f94bcc59..000000000 --- a/src/wrap/sqlite/codec.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Codec class for SQLite3 encryption codec. - * (C) 2010 Olivier de Gaalon - * - * Distributed under the terms of the Botan license - */ - -#ifndef _CODEC_H_ -#define _CODEC_H_ - -#include <string> -#include <botan/botan.h> -#include <botan/loadstor.h> - -using namespace std; -using namespace Botan; - -/*These constants can be used to tweak the codec behavior as follows - *Note that once you've encrypted a database with these settings, - *recompiling with any different settings will give you a library that - *cannot read that database, even given the same passphrase.*/ - -//BLOCK_CIPHER_STR: Cipher and mode used for encrypting the database -//make sure to add "/NoPadding" for modes that use padding schemes -const string BLOCK_CIPHER_STR = "Twofish/XTS"; - -//PBKDF_STR: Key derivation function used to derive both the encryption -//and IV derivation keys from the given database passphrase -const string PBKDF_STR = "PBKDF2(SHA-160)"; - -//SALT_STR: Hard coded salt used to derive the key from the passphrase. -const string SALT_STR = "&g#nB'9]"; - -//SALT_SIZE: Size of the salt in bytes (as given in SALT_STR) -const int SALT_SIZE = 64/8; //64 bit, 8 byte salt - -//MAC_STR: CMAC used to derive the IV that is used for db page -//encryption -const string MAC_STR = "CMAC(Twofish)"; - -//PBKDF_ITERATIONS: Number of hash iterations used in the key derivation -//process. -const int PBKDF_ITERATIONS = 10000; - -//KEY_SIZE: Size of the encryption key. Note that XTS splits the key -//between two ciphers, so if you're using XTS, double the intended key -//size. (ie, "AES-128/XTS" should have a 256 bit KEY_SIZE) -const int KEY_SIZE = 512/8; //512 bit, 64 byte key. (256 bit XTS key) - -//IV_DERIVATION_KEY_SIZE: Size of the key used with the CMAC (MAC_STR) -//above. -const int IV_DERIVATION_KEY_SIZE = 256/8; //256 bit, 32 byte key - -//This is definited in sqlite.h and very unlikely to change -#define SQLITE_MAX_PAGE_SIZE 32768 - -class Codec -{ -public: - Codec(void *db); - Codec(const Codec* other, void *db); - - void GenerateWriteKey(const char *userPassword, int passwordLength); - void DropWriteKey(); - void SetWriteIsRead(); - void SetReadIsWrite(); - - unsigned char* Encrypt(int page, unsigned char *data, bool useWriteKey); - void Decrypt(int page, unsigned char *data); - - void SetPageSize(int pageSize) { m_pageSize = pageSize; } - - bool HasReadKey() { return m_hasReadKey; } - bool HasWriteKey() { return m_hasWriteKey; } - void* GetDB() { return m_db; } - const char* GetAndResetError(); - -private: - bool m_hasReadKey; - bool m_hasWriteKey; - - SymmetricKey - m_readKey, - m_writeKey, - m_ivReadKey, - m_ivWriteKey; - - Pipe - m_encipherPipe, - m_decipherPipe, - m_macPipe; - - Keyed_Filter *m_encipherFilter; - Keyed_Filter *m_decipherFilter; - MAC_Filter *m_cmac; - - int m_pageSize; - unsigned char m_page[SQLITE_MAX_PAGE_SIZE]; - void *m_db; - const char *m_botanErrorMsg; - - InitializationVector GetIVForPage(u32bit page, bool useWriteKey); - void InitializeCodec(void *db); -}; - -#endif diff --git a/src/wrap/sqlite/codec_c_interface.h b/src/wrap/sqlite/codec_c_interface.h deleted file mode 100644 index 1d8c8706f..000000000 --- a/src/wrap/sqlite/codec_c_interface.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Encryption codec class C interface - * (C) 2010 Olivier de Gaalon - * - * Distributed under the terms of the Botan license - */ - -#ifndef _CODEC_C_INTERFACE_H_ -#define _CODEC_C_INTERFACE_H_ - -#ifdef __cplusplus -typedef unsigned char Bool; -#endif - -#ifdef __cplusplus -extern "C" -#endif -void InitializeBotan(); - -#ifdef __cplusplus -extern "C" -#endif -void* InitializeNewCodec(void *db); - -#ifdef __cplusplus -extern "C" -#endif -void* InitializeFromOtherCodec(const void *otherCodec, void *db); - -#ifdef __cplusplus -extern "C" -#endif -void GenerateWriteKey(void *codec, const char *userPassword, int passwordLength); - -#ifdef __cplusplus -extern "C" -#endif -void DropWriteKey(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -void SetWriteIsRead(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -void SetReadIsWrite(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -unsigned char* Encrypt(void *codec, int page, unsigned char *data, Bool useWriteKey); - -#ifdef __cplusplus -extern "C" -#endif -void Decrypt(void *codec, int page, unsigned char *data); - -#ifdef __cplusplus -extern "C" -#endif -void SetPageSize(void *codec, int pageSize); - -#ifdef __cplusplus -extern "C" -#endif -Bool HasReadKey(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -Bool HasWriteKey(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -void* GetDB(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -const char* GetAndResetError(void *codec); - -#ifdef __cplusplus -extern "C" -#endif -void DeleteCodec(void *codec); - -#endif
\ No newline at end of file diff --git a/src/wrap/sqlite/codecext.c b/src/wrap/sqlite/codecext.c deleted file mode 100644 index e32d60dc2..000000000 --- a/src/wrap/sqlite/codecext.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Encryption codec implementation - * (C) 2010 Olivier de Gaalon - * - * Distributed under the terms of the Botan license - */ - -#ifndef SQLITE_OMIT_DISKIO -#ifdef SQLITE_HAS_CODEC - -#include "codec_c_interface.h" - -Bool HandleError(void *pCodec) -{ - const char *error = GetAndResetError(pCodec); - if (error) { - sqlite3Error((sqlite3*)GetDB(pCodec), SQLITE_ERROR, "Botan Error: %s", error); - return 1; - } - return 0; -} - -// Guessing that "see" is related to SQLite Encryption Extension" (the semi-official, for-pay, encryption codec) -// Just as useful for initializing Botan. -void sqlite3_activate_see(const char *info) -{ - InitializeBotan(); -} - -// Free the encryption codec, called from pager.c (address passed in sqlite3PagerSetCodec) -void sqlite3PagerFreeCodec(void *pCodec) -{ - if (pCodec) - DeleteCodec(pCodec); -} - -// Report the page size to the codec, called from pager.c (address passed in sqlite3PagerSetCodec) -void sqlite3CodecSizeChange(void *pCodec, int pageSize, int nReserve) -{ - SetPageSize(pCodec, pageSize); -} - -// Encrypt/Decrypt functionality, called by pager.c -void* sqlite3Codec(void *pCodec, void *data, Pgno nPageNum, int nMode) -{ - if (pCodec == NULL) //Db not encrypted - return data; - - switch(nMode) - { - case 0: // Undo a "case 7" journal file encryption - case 2: // Reload a page - case 3: // Load a page - if (HasReadKey(pCodec)) - Decrypt(pCodec, nPageNum, (unsigned char*) data); - break; - case 6: // Encrypt a page for the main database file - if (HasWriteKey(pCodec)) - data = Encrypt(pCodec, nPageNum, (unsigned char*) data, 1); - break; - case 7: // Encrypt a page for the journal file - /* - *Under normal circumstances, the readkey is the same as the writekey. However, - *when the database is being rekeyed, the readkey is not the same as the writekey. - *(The writekey is the "destination key" for the rekey operation and the readkey - *is the key the db is currently encrypted with) - *Therefore, for case 7, when the rollback is being written, always encrypt using - *the database's readkey, which is guaranteed to be the same key that was used to - *read and write the original data. - */ - if (HasReadKey(pCodec)) - data = Encrypt(pCodec, nPageNum, (unsigned char*) data, 0); - break; - } - - HandleError(pCodec); - - return data; -} - -int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *zKey, int nKey) -{ - void *pCodec; - - if (zKey == NULL || nKey <= 0) - { - // No key specified, could mean either use the main db's encryption or no encryption - if (nDb != 0 && nKey < 0) - { - //Is an attached database, therefore use the key of main database, if main database is encrypted - void *pMainCodec = sqlite3PagerGetCodec(sqlite3BtreePager(db->aDb[0].pBt)); - if (pMainCodec != NULL) - { - pCodec = InitializeFromOtherCodec(pMainCodec, db); - sqlite3PagerSetCodec(sqlite3BtreePager(db->aDb[nDb].pBt), - sqlite3Codec, - sqlite3CodecSizeChange, - sqlite3PagerFreeCodec, pCodec); - } - } - } - else - { - // Key specified, setup encryption key for database - pCodec = InitializeNewCodec(db); - GenerateWriteKey(pCodec, (const char*) zKey, nKey); - SetReadIsWrite(pCodec); - sqlite3PagerSetCodec(sqlite3BtreePager(db->aDb[nDb].pBt), - sqlite3Codec, - sqlite3CodecSizeChange, - sqlite3PagerFreeCodec, pCodec); - } - - if (HandleError(pCodec)) - return SQLITE_ERROR; - - return SQLITE_OK; -} - -void sqlite3CodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) -{ - // The unencrypted password is not stored for security reasons - // therefore always return NULL - *zKey = NULL; - *nKey = -1; -} - -int sqlite3_key(sqlite3 *db, const void *zKey, int nKey) -{ - // The key is only set for the main database, not the temp database - return sqlite3CodecAttach(db, 0, zKey, nKey); -} - -int sqlite3_rekey(sqlite3 *db, const void *zKey, int nKey) -{ - // Changes the encryption key for an existing database. - int rc = SQLITE_ERROR; - Btree *pbt = db->aDb[0].pBt; - Pager *pPager = sqlite3BtreePager(pbt); - void *pCodec = sqlite3PagerGetCodec(pPager); - - if ((zKey == NULL || nKey == 0) && pCodec == NULL) - { - // Database not encrypted and key not specified. Do nothing - return SQLITE_OK; - } - - if (pCodec == NULL) - { - // Database not encrypted, but key specified. Encrypt database - pCodec = InitializeNewCodec(db); - GenerateWriteKey(pCodec, (const char*) zKey, nKey); - - if (HandleError(pCodec)) - return SQLITE_ERROR; - - sqlite3PagerSetCodec(pPager, sqlite3Codec, sqlite3CodecSizeChange, sqlite3PagerFreeCodec, pCodec); - } - else if (zKey == NULL || nKey == 0) - { - // Database encrypted, but key not specified. Decrypt database - // Keep read key, drop write key - DropWriteKey(pCodec); - } - else - { - // Database encrypted and key specified. Re-encrypt database with new key - // Keep read key, change write key to new key - GenerateWriteKey(pCodec, (const char*) zKey, nKey); - if (HandleError(pCodec)) - return SQLITE_ERROR; - } - - // Start transaction - rc = sqlite3BtreeBeginTrans(pbt, 1); - if (rc == SQLITE_OK) - { - // Rewrite all pages using the new encryption key (if specified) - int nPageCount = -1; - sqlite3PagerPagecount(pPager, &nPageCount); - Pgno nPage = (Pgno) nPageCount; - - Pgno nSkip = PAGER_MJ_PGNO(pPager); - DbPage *pPage; - - Pgno n; - for (n = 1; rc == SQLITE_OK && n <= nPage; n++) - { - if (n == nSkip) - continue; - - rc = sqlite3PagerGet(pPager, n, &pPage); - - if (!rc) - { - rc = sqlite3PagerWrite(pPage); - sqlite3PagerUnref(pPage); - } - else - sqlite3Error(db, SQLITE_ERROR, "%s", "Error while rekeying database page. Transaction Canceled."); - } - } - else - sqlite3Error(db, SQLITE_ERROR, "%s", "Error beginning rekey transaction. Make sure that the current encryption key is correct."); - - if (rc == SQLITE_OK) - { - // All good, commit - rc = sqlite3BtreeCommit(pbt); - - if (rc == SQLITE_OK) - { - //Database rekeyed and committed successfully, update read key - if (HasWriteKey(pCodec)) - SetReadIsWrite(pCodec); - else //No write key == no longer encrypted - sqlite3PagerSetCodec(pPager, NULL, NULL, NULL, NULL); - } - else - { - //FIXME: can't trigger this, not sure if rollback is needed, reference implementation didn't rollback - sqlite3Error(db, SQLITE_ERROR, "%s", "Could not commit rekey transaction."); - } - } - else - { - // Rollback, rekey failed - sqlite3BtreeRollback(pbt, SQLITE_ERROR); - - // go back to read key - if (HasReadKey(pCodec)) - SetWriteIsRead(pCodec); - else //Database wasn't encrypted to start with - sqlite3PagerSetCodec(pPager, NULL, NULL, NULL, NULL); - } - - return rc; -} - -#endif // SQLITE_HAS_CODEC - -#endif // SQLITE_OMIT_DISKIO diff --git a/src/wrap/sqlite/readme.txt b/src/wrap/sqlite/readme.txt deleted file mode 100644 index 4971fd44b..000000000 --- a/src/wrap/sqlite/readme.txt +++ /dev/null @@ -1,35 +0,0 @@ -Build instructions for BotanSqlite3 ---- - -Requirements: - 1. Botan 1.9.0 or later - 2. SQLite3 amalgamation source, version 3.7.12.1 or later (previous versions may work, some will need minor changes) - - -Building: - -1. Extract sqlite3 amalgamation to a directory and add BotanSqlite3 source files - - If desired, codec.h can be modified to tweak the encryption algothrithms and parameters. (Defaults to Twofish/XTS with 256 bit key) - -2. Apply the patch "sqlite3.diff": - $ patch -p0 < sqlite3-amalgamation.patch - - If the patching fails for some reason (ie, changes in SQLite3), it should be trivial to do it manually. - -3. Compile the sqlite3 library with Botan encryption support: - $ gcc -c sqlite3.c -o botansqlite3.o && gcc -c codec.cpp -o codec.o `pkg-config --cflags botan-1.10` && ar rcs libbotansqlite3.a botansqlite3.o codec.o - - (replace "botan-1.10" with appropriate version) - -Testing: - -1. Build the test: - $ g++ test_sqlite.cpp -o test_sqlite `botan-config-1.10 --libs` ./libbotansqlite3.a - - (replace botan-config-1.10 w/ appropriate version) - -2. Run the test - $ ./test_sqlite - -3. Look for "All seems good" diff --git a/src/wrap/sqlite/sqlite3-amalgamation.patch b/src/wrap/sqlite/sqlite3-amalgamation.patch deleted file mode 100644 index 1c2a5c69d..000000000 --- a/src/wrap/sqlite/sqlite3-amalgamation.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- ./sqlite3.c.orig 2011-05-12 10:03:32.051879390 +0800 -+++ ./sqlite3.c 2011-05-12 10:09:04.028550281 +0800 -@@ -17,6 +17,7 @@ - ** language. The code for the "sqlite3" command-line shell is also in a - ** separate file. This file contains only code for the core SQLite library. - */ -+#define SQLITE_HAS_CODEC 1 - #define SQLITE_CORE 1 - #define SQLITE_AMALGAMATION 1 - #ifndef SQLITE_PRIVATE -@@ -125956,3 +125957,4 @@ - #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ - - /************** End of fts3_icu.c ********************************************/ -+#include "codecext.c" diff --git a/src/wrap/sqlite/test_sqlite.cpp b/src/wrap/sqlite/test_sqlite.cpp deleted file mode 100644 index a516fd82b..000000000 --- a/src/wrap/sqlite/test_sqlite.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Quick and dirty test for SQLite3 encryption codec. - * (C) 2010 Olivier de Gaalon - * - * Distributed under the terms of the Botan license - */ - -#define SQLITE_HAS_CODEC 1 - -#include <sqlite3.h> -#include <stdio.h> - -namespace SQL -{ - const char * CREATE_TABLE_TEST = - "create table 'test' (id INTEGER PRIMARY KEY, name TEXT, creationtime TEXT);"; - const char * CREATE_TABLE_TEST2 = - "create table 'test2' (id INTEGER PRIMARY KEY, name TEXT, creationtime TEXT);"; - const char * INSERT_INTO_TEST = - "INSERT INTO test (name, creationtime) VALUES ('widget', '1st time');\ - INSERT INTO test (name, creationtime) VALUES ('widget', '2nd time');\ - INSERT INTO test (name, creationtime) VALUES ('widget', '3rd time');\ - INSERT INTO test (name, creationtime) VALUES ('widget', '4th time');\ - INSERT INTO test (name, creationtime) VALUES ('widget', '5th time');"; - const char * INSERT_INTO_TEST2 = - "INSERT INTO test2 (name, creationtime) VALUES ('widget2', '1st time2');\ - INSERT INTO test2 (name, creationtime) VALUES ('widget2', '2nd time2');\ - INSERT INTO test2 (name, creationtime) VALUES ('widget2', '3rd time2');\ - INSERT INTO test2 (name, creationtime) VALUES ('widget2', '4th time2');\ - INSERT INTO test2 (name, creationtime) VALUES ('widget2', '5th time2');"; - const char * SELECT_FROM_TEST = - "SELECT * FROM test;"; - const char * SELECT_FROM_TEST2 = - "SELECT * FROM test2;"; -}; - -static int callback(void *NotUsed, int argc, char **argv, char **azColName){ - int i; - fprintf(stderr, "\t"); - for(i=0; i<argc; i++){ - fprintf(stderr, "%s = %s | ", azColName[i], argv[i] ? argv[i] : "NULL"); - } - fprintf(stderr, "\n"); - return 0; -} - -int main(int argc, char** argv) -{ - sqlite3 * db; - const char * key = "anotherkey"; - 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; -} |