/* ** 2017-01-18 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code used to implement key/value access interface. */ #include "sqliteInt.h" #ifndef SQLITE_OMIT_KEYVALUE_ACCESSOR /* ** An sqlite3_kv object is an accessor for key/value pairs. ** ** This is an opaque object. The public interface sees pointers to this ** object, but not the internals. So the internal composition of this ** object is free to change from one release to the next without breaking ** compatibility. */ struct sqlite3_kv { sqlite3 *db; /* The database holding the table to be accessed */ u8 iDb; /* Database containing the table to access */ u32 iRoot; /* Root page of the table */ sqlite3_int64 iRowid; /* Current rowid */ }; /* ** Create a new sqlite3_kv object open on zDb.zTable and return ** a pointer to that object. */ int sqlite3_kv_open( sqlite3 *db, /* The database connection */ const char *zDb, /* Schema containing zTable. NULL for "main" */ const char *zTable, /* Name of table the key/value table */ unsigned int flags, /* Must be zero. Reserved for future expansion. */ sqlite3_kv **ppKvOut /* Store the new sqlite3_kv object here */ ){ sqlite3_kv *pKv; Table *pTab; int rc = SQLITE_ERROR; #ifdef SQLITE_ENABLE_API_ARMOR if( ppKvOut==0 ){ return SQLITE_MISUSE_BKPT; } #endif *ppKvOut = 0; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) || zTable==0 ){ return SQLITE_MISUSE_BKPT; } #endif sqlite3_mutex_enter(db->mutex); sqlite3BtreeEnterAll(db); pTab = sqlite3FindTable(db, zTable, zDb); if( pTab==0 ){ goto kv_open_done; } if( !((pTab->nCol==1 && pTab->iPKey<0) || (pTab->nCol==2 && pTab->iPKey==0)) ){ /* Must be an single-column table without an INTEGER PRIMARY KEY, ** or a two-column table where the first column is the INTEGER PRIMARY KEY */ goto kv_open_done; } if( pTab->pIndex!=0 || pTab->pFKey!=0 || pTab->pCheck!=0 ){ /* Do not allow secondary indexes, foreign keys, or CHECK constraints */ goto kv_open_done; } if( pTab->tabFlags & (TF_Autoincrement|TF_Virtual|TF_WithoutRowid) ){ /* Must not have autoincrement. Must not be a virtual table or a ** without rowid table */ goto kv_open_done; } *ppKvOut = pKv = sqlite3_malloc(sizeof(*pKv)); if( pKv==0 ){ rc = SQLITE_NOMEM; goto kv_open_done; } pKv->db = db; rc = SQLITE_OK; kv_open_done: sqlite3BtreeLeaveAll(db); sqlite3_mutex_leave(db->mutex); return rc; } /* ** Free the key/value accessor at pKv */ int sqlite3_kv_close(sqlite3_kv *pKv){ sqlite3_free(pKv); return SQLITE_OK; } int sqlite3_kv_seek(sqlite3_kv *pKv, sqlite3_int64 rowid){ return SQLITE_MISUSE; } int sqlite3_kv_bytes(sqlite3_kv *pKv){ return -1; } int sqlite3_kv_read(sqlite3_kv *pKv, void *pBuf, int amt, int offset){ return SQLITE_MISUSE; } int sqlite3_kv_insert(sqlite3_kv *pKv, sqlite3_int64 rid, int sz, void *pBuf){ return SQLITE_MISUSE; } #endif /* #ifndef SQLITE_OMIT_KEYVALU_ACCESSOR */