blob: 5fde1064ba4c47686a838c4c34b3cf9bfb06c471 [file] [log] [blame] [edit]
/*
** 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 */
u32 iRoot; /* Root page of the table */
int iGen; /* Schema generation number */
int iCookie; /* Schema cookie number from the database file */
Schema *pSchema; /* Schema holding 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;
pKv->iGen = pTab->pSchema->iGeneration;
pKv->iCookie = pTab->pSchema->schema_cookie;
pKv->pSchema = pTab->pSchema;
pKv->iRoot = pTab->tnum;
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_reset(sqlite3_kv *pKv){
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 */