internal static extern int sqlite3_prepare_v2( sqlite3* db, /* Database handle */ string zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ out sqlite3_stmt* ppStmt, /* OUT: Statement handle */ out char* pzTail /* OUT: Pointer to unused portion of zSql */ );
/* ** The following routine destroys a virtual machine that is created by ** the sqlite3_compile() routine. The integer returned is an SQLITE_ ** success/failure code that describes the result of executing the virtual ** machine. ** ** This routine sets the error code and string returned by ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ public static int sqlite3_finalize( ref sqlite3_stmt pStmt ) { int rc; if ( pStmt == null ) { rc = SQLITE_OK; } else { Vdbe v = pStmt; sqlite3 db = v.db; #if SQLITE_THREADSAFE sqlite3_mutex mutex; #endif if ( db == null ) return SQLITE_MISUSE; #if SQLITE_THREADSAFE mutex = v.db.mutex; #endif sqlite3_mutex_enter( mutex ); rc = sqlite3VdbeFinalize( v ); rc = sqlite3ApiExit( db, rc ); sqlite3_mutex_leave( mutex ); } return rc; }
/* ** 2003 April 6 ** ** 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 the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ************************************************************************* ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart ** C#-SQLite is an independent reimplementation of the SQLite software library ** ** SQLITE_SOURCE_ID: 2011-05-19 13:26:54 ed1da510a239ea767a01dc332b667119fa3c908e ** ************************************************************************* */ //#include "sqliteInt.h" //#include "vdbeInt.h" #if !SQLITE_OMIT_VACUUM && !SQLITE_OMIT_ATTACH /* ** Finalize a prepared statement. If there was an error, store the ** text of the error message in *pzErrMsg. Return the result code. */ static int vacuumFinalize( sqlite3 db, sqlite3_stmt pStmt, string pzErrMsg ) { int rc; rc = sqlite3VdbeFinalize( ref pStmt ); if ( rc != 0 ) { sqlite3SetString( ref pzErrMsg, db, sqlite3_errmsg( db ) ); } return rc; }
public static void bind(this sqlite3_stmt stmt, int ndx, double v) { stmt.bind_double(ndx, v); }
public static string sqlite3_column_text(sqlite3_stmt pStmt, int i) { string val = sqlite3_value_text(columnMem(pStmt, i)); columnMallocFailure(pStmt); if (String.IsNullOrEmpty(val)) return null; return val; }
public static int sqlite3_column_bytes16( sqlite3_stmt pStmt, int i ) { int val = sqlite3_value_bytes16( columnMem( pStmt, i ) ); columnMallocFailure( pStmt ); return val; }
static int sqlite3LockAndPrepare( sqlite3 db, /* Database handle. */ string zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ Vdbe pOld, /* VM being reprepared */ ref sqlite3_stmt ppStmt, /* OUT: A pointer to the prepared statement */ ref string pzTail /* OUT: End of parsed string */ ) { int rc; // assert( ppStmt!=0 ); ppStmt = null; if ( !sqlite3SafetyCheckOk( db ) ) { return SQLITE_MISUSE_BKPT(); } sqlite3_mutex_enter( db.mutex ); sqlite3BtreeEnterAll( db ); rc = sqlite3Prepare( db, zSql, nBytes, saveSqlFlag, pOld, ref ppStmt, ref pzTail ); if ( rc == SQLITE_SCHEMA ) { sqlite3_finalize( ppStmt ); rc = sqlite3Prepare( db, zSql, nBytes, saveSqlFlag, pOld, ref ppStmt, ref pzTail ); } sqlite3BtreeLeaveAll( db ); sqlite3_mutex_leave( db.mutex ); return rc; }
/* ** 2004 May 26 ** ** 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 use to implement APIs that are part of the ** VDBE. ************************************************************************* ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart ** C#-SQLite is an independent reimplementation of the SQLite software library ** ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2 ** ************************************************************************* */ //#include "sqliteInt.h" //#include "vdbeInt.h" #if !SQLITE_OMIT_DEPRECATED /* ** Return TRUE (non-zero) of the statement supplied as an argument needs ** to be recompiled. A statement needs to be recompiled whenever the ** execution environment changes in a way that would alter the program ** that sqlite3_prepare() generates. For example, if new functions or ** collating sequences are registered or if an authorizer function is ** added or changed. */ static int sqlite3_expired( sqlite3_stmt pStmt ) { Vdbe p = (Vdbe)pStmt; return ( p == null || p.expired ) ? 1 : 0; }
/* ** Check to see if column iCol of the given statement is valid. If ** it is, return a pointer to the Mem for the value of that column. ** If iCol is not valid, return a pointer to a Mem which has a value ** of NULL. */ static Mem columnMem( sqlite3_stmt pStmt, int i ) { Vdbe pVm; Mem pOut; pVm = (Vdbe)pStmt; if ( pVm != null && pVm.pResultSet != null && i < pVm.nResColumn && i >= 0 ) { sqlite3_mutex_enter( pVm.db.mutex ); pOut = pVm.pResultSet[i]; } else { /* If the value passed as the second argument is out of range, return ** a pointer to the following public static Mem object which contains the ** value SQL NULL. Even though the Mem structure contains an element ** of type i64, on certain architecture (x86) with certain compiler ** switches (-Os), gcc may align this Mem object on a 4-byte boundary ** instead of an 8-byte one. This all works fine, except that when ** running with SQLITE_DEBUG defined the SQLite code sometimes Debug.Assert()s ** that a Mem structure is located on an 8-byte boundary. To prevent ** this Debug.Assert() from failing, when building with SQLITE_DEBUG defined ** using gcc, force nullMem to be 8-byte aligned using the magical ** __attribute__((aligned(8))) macro. */ // static const Mem nullMem //#if defined(SQLITE_DEBUG) && defined(__GNUC__) // __attribute__((aligned(8))) //#endif // = {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0, //#if SQLITE_DEBUG // 0, 0, /* pScopyFrom, pFiller */ //#endif // 0, 0 }; Mem nullMem = new Mem( null, string.Empty, (double)0, 0, 0, MEM_Null, SQLITE_NULL, 0 #if SQLITE_DEBUG , null, null /* pScopyFrom, pFiller */ #endif ); if ( pVm != null && ALWAYS( pVm.db != null ) ) { sqlite3_mutex_enter( pVm.db.mutex ); sqlite3Error( pVm.db, SQLITE_RANGE, 0 ); } pOut = nullMem; } return pOut; }
internal BindParameterImpl(sqlite3_stmt stmt, int index) { this.stmt = stmt; this.index = index; }
/* ** Constraint: If you have ENABLE_COLUMN_METADATA then you must ** not define OMIT_DECLTYPE. */ #if SQLITE_OMIT_DECLTYPE && SQLITE_ENABLE_COLUMN_METADATA # error "Must not define both SQLITE_OMIT_DECLTYPE and SQLITE_ENABLE_COLUMN_METADATA" #endif #if !SQLITE_OMIT_DECLTYPE /* ** Return the column declaration type (if applicable) of the 'i'th column ** of the result set of SQL statement pStmt. */ public static string sqlite3_column_decltype( sqlite3_stmt pStmt, int N ) { return columnName( pStmt, N, sqlite3_value_text, COLNAME_DECLTYPE ); }
/// <summary> /// /// </summary> /// <param name="args"> /// args[0] - .inpx file /// args[1] - directory for hlc2 files /// </param> static void Main(string[] args) { int rc; if (args.Length == 0) { Console.WriteLine("Неверное число параметров. inpxscan <.inpx file>"); Console.ReadKey(); return; } string scriptText; using (var scriptStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("inpxscan.CreateCollectionDB_SQLite.sql")) { using (var sr = new StreamReader(scriptStream, Encoding.UTF8)) { scriptText = sr.ReadToEnd(); } } string newbaseName = Path.Combine(args[1], "tinyopdscore_" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-ff") + ".hlc2"); raw.SetProvider(new SQLite3Provider_e_sqlite3()); rc = raw.sqlite3_open(newbaseName, out db); if (rc != raw.SQLITE_OK) { throw new Exception(raw.sqlite3_errmsg(db).utf8_to_string()); } raw.sqlite3_create_collation(db, "MHL_SYSTEM", null, mhl_system_collation); raw.sqlite3_create_collation(db, "MHL_SYSTEM_NOCASE", null, mhl_system_nocase_collation); raw.sqlite3_create_function(db, "MHL_UPPER", 1, null, mhl_upper); raw.sqlite3_create_function(db, "MHL_LOWER", 1, null, mhl_lower); rc = raw.sqlite3_exec(db, scriptText); if (rc != raw.SQLITE_OK) { throw new Exception(raw.sqlite3_errmsg(db).utf8_to_string()); } rc = raw.sqlite3_exec(db, "BEGIN"); InsertGenres(); sqlite3_stmt stmt = null; string cSql = "INSERT INTO Books " + "(LibID, Title, SeqNumber, UpdateDate, Lang, Folder, FileName, Ext, BookSize, IsDeleted, KeyWords, " + "SearchTitle, SearchLang, SearchFolder, SearchFileName, SearchExt, SearchKeyWords, SearchAnnotation, InsideNo) " + "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; if (raw.sqlite3_prepare_v2(db, cSql, out stmt) != raw.SQLITE_OK) { throw new Exception(raw.sqlite3_errmsg(db).utf8_to_string()); } int booksCount = FillList(args[0], stmt); Console.WriteLine($"Книг - {booksCount}"); Console.WriteLine($"Необработанных жанров - {9999 - new_genre}"); raw.sqlite3_finalize(stmt); rc = raw.sqlite3_exec(db, "COMMIT"); raw.sqlite3_close_v2(db); Console.WriteLine("Загрузка окончена."); Console.ReadKey(); }
private static int FillList(string fname, sqlite3_stmt stmt) { int booksCount = 0; int insideno = 0; using (var zipArchive = ZipFile.OpenRead(fname)) { foreach (var entry in zipArchive.Entries) { if (entry.Name.Contains(".inp")) { Console.WriteLine($"Обрабатывается файл {entry.Name}"); using (var stream = entry.Open()) { using (var sr = new StreamReader(stream, Encoding.UTF8)) { string s; while ((s = sr.ReadLine()) != null) { var o = new Books(); var mas = s.Split('\x04'); var authors = mas[0].Split(':'); foreach (var a in authors) { if (!string.IsNullOrWhiteSpace(a)) { var names = a.Split(','); var nameL = names.Length; var oa = new Author(); if (nameL > 2) { oa.Middle = names[2] ?? ""; } if (nameL > 1) { oa.First = names[1] ?? ""; } if (nameL > 0) { oa.Last = names[0] ?? ""; } o.author.Add(oa); } } var genres = mas[1].Split(':'); foreach (var g in genres) { if (!string.IsNullOrWhiteSpace(g)) { o.genre.Add(g); } } o.title = mas[2]; o.series = mas[3]; if (int.TryParse(mas[4], out int serno)) { o.serno = serno; } o.file = mas[5]; if (int.TryParse(mas[6], out int size)) { o.size = size; } o.libid = mas[7]; if (int.TryParse(mas[8], out int del)) { o.del = del; } else { o.del = 0; } o.ext = mas[9]; o.date = mas[10]; o.lang = mas[11]; o.keywords = mas[12]; o.bookid = InsertBook(o, entry.Name, insideno++, stmt); booksCount++; InsertGenreList(o.bookid, o.genre); InsertAuthorList(o.bookid, o.author); if (!string.IsNullOrWhiteSpace(o.series)) { int seriesid; if (!d_series.ContainsKey(o.series.ToUpper())) { seriesid = InsertSeries(o.series); d_series.Add(o.series.ToUpper(), seriesid); } else { seriesid = d_series[o.series.ToUpper()]; } UpdateBook(o.bookid, seriesid); } } } } } } } return(booksCount); }
public SqlStatement(SqlConnection connection, sqlite3_stmt statement) { _connection = connection; _rawStatement = statement; }
public DbStatement(sqlite3_stmt stmtPtr) : this() { StmtPtr = stmtPtr; }
public static void bind(this sqlite3_stmt stmt, int ndx, byte[] v) { stmt.bind_blob(ndx, v); }
public static void bind(this sqlite3_stmt stmt, int ndx, string v) { stmt.bind_text(ndx, v); }
private void Finalize(sqlite3_stmt stmt) { SQLite3.Finalize(stmt); }
/* The following function is experimental and subject to change or ** removal */ /*int sqlite3_column_numeric_type(sqlite3_stmt pStmt, int i){ ** return sqlite3_value_numeric_type( columnMem(pStmt,i) ); **} */ /* ** Convert the N-th element of pStmt.pColName[] into a string using ** xFunc() then return that string. If N is out of range, return 0. ** ** There are up to 5 names for each column. useType determines which ** name is returned. Here are the names: ** ** 0 The column name as it should be displayed for output ** 1 The datatype name for the column ** 2 The name of the database that the column derives from ** 3 The name of the table that the column derives from ** 4 The name of the table column that the result column derives from ** ** If the result is not a simple column reference (if it is an expression ** or a constant) then useTypes 2, 3, and 4 return NULL. */ public static string columnName( sqlite3_stmt pStmt, int N, dxColname xFunc, int useType ) { string ret = null; Vdbe p = pStmt; int n; sqlite3 db = p.db; Debug.Assert( db != null ); n = sqlite3_column_count( pStmt ); if ( N < n && N >= 0 ) { N += useType * n; sqlite3_mutex_enter( db.mutex ); //Debug.Assert( db.mallocFailed == 0 ); ret = xFunc( p.aColName[N] ); /* A malloc may have failed inside of the xFunc() call. If this ** is the case, clear the mallocFailed flag and return NULL. */ //if ( db.mallocFailed != 0 ) //{ // //db.mallocFailed = 0; // ret = null; //} sqlite3_mutex_leave( db.mutex ); } return ret; }
internal static void BindParameter(sqlite3_stmt stmt, int index, object value, bool storeDateTimeAsTicks, string dateTimeStringFormat, bool storeTimeSpanAsTicks) { if (value == null) { SQLite3.BindNull(stmt, index); } else { if (value is BaseTableQuery.Condition condition) { BindParameter(stmt, index, condition.Value, storeDateTimeAsTicks, dateTimeStringFormat, storeTimeSpanAsTicks); } else if (value is Int32) { SQLite3.BindInt(stmt, index, (int)value); } else if (value is String) { SQLite3.BindText(stmt, index, (string)value, -1, NegativePointer); } else if (value is Byte || value is UInt16 || value is SByte || value is Int16) { SQLite3.BindInt(stmt, index, Convert.ToInt32(value)); } else if (value is Boolean) { SQLite3.BindInt(stmt, index, (bool)value ? 1 : 0); } else if (value is UInt32 || value is Int64) { SQLite3.BindInt64(stmt, index, Convert.ToInt64(value)); } else if (value is Single || value is Double || value is Decimal) { SQLite3.BindDouble(stmt, index, Convert.ToDouble(value)); } else if (value is TimeSpan) { if (storeTimeSpanAsTicks) { SQLite3.BindInt64(stmt, index, ((TimeSpan)value).Ticks); } else { SQLite3.BindText(stmt, index, ((TimeSpan)value).ToString(), -1, NegativePointer); } } else if (value is DateTime) { if (storeDateTimeAsTicks) { SQLite3.BindInt64(stmt, index, ((DateTime)value).Ticks); } else { SQLite3.BindText(stmt, index, ((DateTime)value).ToString(dateTimeStringFormat, System.Globalization.CultureInfo.InvariantCulture), -1, NegativePointer); } } else if (value is DateTimeOffset) { SQLite3.BindInt64(stmt, index, ((DateTimeOffset)value).UtcTicks); } else if (value is byte[]) { SQLite3.BindBlob(stmt, index, (byte[])value, ((byte[])value).Length, NegativePointer); } else if (value is Guid) { SQLite3.BindText(stmt, index, ((Guid)value).ToString(), 72, NegativePointer); } else if (value is Uri) { SQLite3.BindText(stmt, index, ((Uri)value).ToString(), -1, NegativePointer); } else if (value is StringBuilder) { SQLite3.BindText(stmt, index, ((StringBuilder)value).ToString(), -1, NegativePointer); } else if (value is UriBuilder) { SQLite3.BindText(stmt, index, ((UriBuilder)value).ToString(), -1, NegativePointer); } else { // Now we could possibly get an enum, retrieve cached info var valueType = value.GetType(); var enumInfo = EnumCache.GetInfo(valueType); if (enumInfo.IsEnum) { var enumIntValue = Convert.ToInt32(value); if (enumInfo.StoreAsText) { SQLite3.BindText(stmt, index, enumInfo.EnumValues[enumIntValue], -1, NegativePointer); } else { SQLite3.BindInt(stmt, index, enumIntValue); } } else { throw new NotSupportedException("Cannot store type: " + Orm.GetType(value)); } } } }
/* ** Terminate the current execution of an SQL statement and reset it ** back to its starting state so that it can be reused. A success code from ** the prior execution is returned. ** ** This routine sets the error code and string returned by ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ public static int sqlite3_reset( sqlite3_stmt pStmt ) { int rc; if ( pStmt == null ) { rc = SQLITE_OK; } else { Vdbe v = (Vdbe)pStmt; sqlite3_mutex_enter( v.db.mutex ); rc = sqlite3VdbeReset( v ); sqlite3VdbeRewind( v ); Debug.Assert( ( rc & ( v.db.errMask ) ) == rc ); rc = sqlite3ApiExit( v.db, rc ); sqlite3_mutex_leave( v.db.mutex ); } return rc; }
private object ReadCol(sqlite3_stmt stmt, int index, SQLite3.ColType type, Type clrType) { if (type == SQLite3.ColType.Null) { return(null); } else { var clrTypeInfo = clrType.GetTypeInfo(); if (clrTypeInfo.IsGenericType && clrTypeInfo.GetGenericTypeDefinition() == typeof(Nullable <>)) { clrType = clrTypeInfo.GenericTypeArguments[0]; clrTypeInfo = clrType.GetTypeInfo(); } if (clrType == typeof(String)) { return(SQLite3.ColumnString(stmt, index)); } else if (clrType == typeof(Int32)) { return((int)SQLite3.ColumnInt(stmt, index)); } else if (clrType == typeof(Boolean)) { return(SQLite3.ColumnInt(stmt, index) == 1); } else if (clrType == typeof(double)) { return(SQLite3.ColumnDouble(stmt, index)); } else if (clrType == typeof(float)) { return((float)SQLite3.ColumnDouble(stmt, index)); } else if (clrType == typeof(TimeSpan)) { if (_conn.StoreTimeSpanAsTicks) { return(new TimeSpan(SQLite3.ColumnInt64(stmt, index))); } else { var text = SQLite3.ColumnString(stmt, index); TimeSpan resultTime; if (!TimeSpan.TryParseExact(text, "c", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.TimeSpanStyles.None, out resultTime)) { resultTime = TimeSpan.Parse(text); } return(resultTime); } } else if (clrType == typeof(DateTime)) { if (_conn.StoreDateTimeAsTicks) { return(new DateTime(SQLite3.ColumnInt64(stmt, index))); } else { var text = SQLite3.ColumnString(stmt, index); DateTime resultDate; if (!DateTime.TryParseExact(text, _conn.DateTimeStringFormat, System.Globalization.CultureInfo.InvariantCulture, _conn.DateTimeStyle, out resultDate)) { resultDate = DateTime.Parse(text); } return(resultDate); } } else if (clrType == typeof(DateTimeOffset)) { return(new DateTimeOffset(SQLite3.ColumnInt64(stmt, index), TimeSpan.Zero)); } else if (clrTypeInfo.IsEnum) { if (type == SQLite3.ColType.Text) { var value = SQLite3.ColumnString(stmt, index); return(Enum.Parse(clrType, value.ToString(), true)); } else { return(SQLite3.ColumnInt(stmt, index)); } } else if (clrType == typeof(Int64)) { return(SQLite3.ColumnInt64(stmt, index)); } else if (clrType == typeof(UInt32)) { return((uint)SQLite3.ColumnInt64(stmt, index)); } else if (clrType == typeof(decimal)) { return((decimal)SQLite3.ColumnDouble(stmt, index)); } else if (clrType == typeof(Byte)) { return((byte)SQLite3.ColumnInt(stmt, index)); } else if (clrType == typeof(UInt16)) { return((ushort)SQLite3.ColumnInt(stmt, index)); } else if (clrType == typeof(Int16)) { return((short)SQLite3.ColumnInt(stmt, index)); } else if (clrType == typeof(sbyte)) { return((sbyte)SQLite3.ColumnInt(stmt, index)); } else if (clrType == typeof(byte[])) { return(SQLite3.ColumnByteArray(stmt, index)); } else if (clrType == typeof(Guid)) { var text = SQLite3.ColumnString(stmt, index); return(new Guid(text)); } else if (clrType == typeof(Uri)) { var text = SQLite3.ColumnString(stmt, index); return(new Uri(text)); } else if (clrType == typeof(StringBuilder)) { var text = SQLite3.ColumnString(stmt, index); return(new StringBuilder(text)); } else if (clrType == typeof(UriBuilder)) { var text = SQLite3.ColumnString(stmt, index); return(new UriBuilder(text)); } else { throw new NotSupportedException("Don't know how to read " + clrType); } } }
/* ** Return the number of columns in the result set for the statement pStmt. */ public static int sqlite3_column_count( sqlite3_stmt pStmt ) { Vdbe pVm = pStmt; return pVm != null ? (int)pVm.nResColumn : 0; }
// /* // ** c_realloc_test // */ // static int c_realloc_test( // object clientdata, /* Pointer to sqlite3_enable_XXX function */ // Tcl_Interp interp, /* The TCL interpreter that invoked this command */ // int objc, /* Number of arguments */ // Tcl_Obj[] objv /* Command arguments */ // ) // { // object p; // string zErrFunction = "N/A"; // if ( objc != 1 ) // { // TCL.Tcl_WrongNumArgs( interp, 1, objv, "" ); // return TCL.TCL_ERROR; // } // p = sqlite3Malloc( 5 ); // if ( p == null ) // { // zErrFunction = "sqlite3Malloc"; // goto error_out; // } // /* Test that realloc()ing a block of memory to a negative size is // ** the same as free()ing that memory. // */ // //TODO -- ignore realloc // //p = sqlite3_realloc(p, -1); // //if( p!=null ){ // // zErrFunction = "sqlite3_realloc"; // // goto error_out; // //} // return TCL.TCL_OK; //error_out: // TCL.Tcl_ResetResult( interp ); // TCL.Tcl_AppendResult( interp, "Error testing function: ", zErrFunction ); // return TCL.TCL_ERROR; // } /* ** c_misuse_test */ static int c_misuse_test( object clientdata, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj[] objv /* Command arguments */ ) { string zErrFunction = "N/A"; sqlite3 db = null; sqlite3_stmt pStmt; string dummyS = ""; int rc; if (objc != 1) { TCL.Tcl_WrongNumArgs(interp, 1, objv, ""); return(TCL.TCL_ERROR); } /* Open a database. Then close it again. We need to do this so that ** we have a "closed database handle" to pass to various API functions. */ rc = sqlite3_open(":memory:", ref db); if (rc != SQLITE_OK) { zErrFunction = "sqlite3_open"; goto error_out; } sqlite3_close(db); rc = sqlite3_errcode(db); if (rc != SQLITE_MISUSE) { zErrFunction = "sqlite3_errcode"; goto error_out; } pStmt = new sqlite3_stmt(); pStmt.pc = 1234; rc = sqlite3_prepare(db, null, 0, ref pStmt, ref dummyS); if (rc != SQLITE_MISUSE) { zErrFunction = "sqlite3_prepare"; goto error_out; } Debug.Assert(pStmt == null); /* Verify that pStmt is zeroed even on a MISUSE error */ pStmt = new sqlite3_stmt(); pStmt.pc = 1234; rc = sqlite3_prepare_v2(db, null, 0, ref pStmt, ref dummyS); if (rc != SQLITE_MISUSE) { zErrFunction = "sqlite3_prepare_v2"; goto error_out; } Debug.Assert(pStmt == null); #if !SQLITE_OMIT_UTF16 pStmt = (sqlite3_stmt)1234; rc = sqlite3_prepare16(db, null, 0, ref pStmt, ref dummyS); if (rc != SQLITE_MISUSE) { zErrFunction = "sqlite3_prepare16"; goto error_out; } assert(pStmt == 0); pStmt = (sqlite3_stmt)1234; rc = sqlite3_prepare16_v2(db, null, 0, ref pStmt, ref dummyS); if (rc != SQLITE_MISUSE) { zErrFunction = "sqlite3_prepare16_v2"; goto error_out; } assert(pStmt == 0); #endif return(TCL.TCL_OK); error_out: TCL.Tcl_ResetResult(interp); TCL.Tcl_AppendResult(interp, "Error testing function: ", zErrFunction); return(TCL.TCL_ERROR); }
/**************************** sqlite3_column_ ******************************* ** The following routines are used to access elements of the current row ** in the result set. */ public static byte[] sqlite3_column_blob( sqlite3_stmt pStmt, int i ) { byte[] val; val = sqlite3_value_blob( columnMem( pStmt, i ) ); /* Even though there is no encoding conversion, value_blob() might ** need to call malloc() to expand the result of a zeroblob() ** expression. */ columnMallocFailure( pStmt ); return val; }
internal void ImportInfo() { //TODO: Revisit this once pluggable storage is finished // CREATE TABLE info (key TEXT PRIMARY KEY, value TEXT); sqlite3_stmt infoQuery = null; PrepareSQL(ref infoQuery, "SELECT key, value FROM info"); int err = raw.sqlite3_step(infoQuery); if (err != raw.SQLITE_ROW) { raw.sqlite3_finalize(infoQuery); throw new CouchbaseLiteException(String.Format("SQLite error {0} ({1}) reading info table from source database '{2}'", err, raw.sqlite3_errmsg(_sqlite), _path), SqliteErrToStatus(err).Code); } string privateUUID = null, publicUUID = null; var key = raw.sqlite3_column_text(infoQuery, 0); var val = raw.sqlite3_column_text(infoQuery, 1); if (key.Equals("privateUUID")) { privateUUID = val; } else if (key.Equals("publicUUID")) { publicUUID = val; } err = raw.sqlite3_step(infoQuery); if (err != raw.SQLITE_ROW) { raw.sqlite3_finalize(infoQuery); throw new CouchbaseLiteException(String.Format("SQLite error {0} ({1}) reading info table from source database '{2}'", err, raw.sqlite3_errmsg(_sqlite), _path), SqliteErrToStatus(err).Code); } key = raw.sqlite3_column_text(infoQuery, 0); val = raw.sqlite3_column_text(infoQuery, 1); if (key.Equals("privateUUID")) { privateUUID = val; } else if (key.Equals("publicUUID")) { publicUUID = val; } raw.sqlite3_finalize(infoQuery); if (publicUUID == null || privateUUID == null) { throw new CouchbaseLiteException("UUIDs missing from source database", StatusCode.CorruptError); } try { _db.ReplaceUUIDs(privateUUID, publicUUID); } catch (CouchbaseLiteException) { Log.W(TAG, "Failed to replace UUIDs in database"); throw; } catch (Exception e) { throw new CouchbaseLiteException("Error replacing UUIDs in database", e) { Code = StatusCode.DbError }; } }
/* ** c_misuse_test */ static int c_misuse_test( object clientdata, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj[] objv /* Command arguments */ ) { string zErrFunction = "N/A"; sqlite3 db = null; sqlite3_stmt pStmt; int rc; if ( objc != 1 ) { TCL.Tcl_WrongNumArgs( interp, 1, objv, "" ); return TCL.TCL_ERROR; } /* Open a database. Then close it again. We need to do this so that ** we have a "closed database handle" to pass to various API functions. */ rc = sqlite3_open( ":memory:", out db ); if ( rc != SQLITE_OK ) { zErrFunction = "sqlite3_open"; goto error_out; } sqlite3_close( db ); rc = sqlite3_errcode( db ); if ( rc != SQLITE_MISUSE ) { zErrFunction = "sqlite3_errcode"; goto error_out; } pStmt = new sqlite3_stmt(); pStmt.pc = 1234; rc = sqlite3_prepare( db, (StringBuilder)null, 0, ref pStmt, 0 ); if ( rc != SQLITE_MISUSE ) { zErrFunction = "sqlite3_prepare"; goto error_out; } Debug.Assert( pStmt == null ); /* Verify that pStmt is zeroed even on a MISUSE error */ pStmt = new sqlite3_stmt(); pStmt.pc = 1234; rc = sqlite3_prepare_v2( db, null, 0, ref pStmt, 0 ); if ( rc != SQLITE_MISUSE ) { zErrFunction = "sqlite3_prepare_v2"; goto error_out; } Debug.Assert( pStmt == null ); #if !SQLITE_OMIT_UTF16 pStmt = (sqlite3_stmt)1234; rc = sqlite3_prepare16( db, null, 0, ref pStmt, 0 ); if( rc!=SQLITE_MISUSE ){ zErrFunction = "sqlite3_prepare16"; goto error_out; } Debug.Assert( pStmt==0 ); pStmt = (sqlite3_stmt)1234; rc = sqlite3_prepare16_v2( db, null, 0, ref pStmt, 0 ); if( rc!=SQLITE_MISUSE ){ zErrFunction = "sqlite3_prepare16_v2"; goto error_out; } Debug.Assert( pStmt==0 ); #endif return TCL.TCL_OK; error_out: TCL.Tcl_ResetResult( interp ); TCL.Tcl_AppendResult( interp, "Error testing function: ", zErrFunction ); return TCL.TCL_ERROR; }
private void AddAttachmentsToSequence(long sequence, List<byte> json) { // CREATE TABLE attachments ( // sequence INTEGER NOT NULL REFERENCES revs(sequence) ON DELETE CASCADE, // filename TEXT NOT NULL, // key BLOB NOT NULL, // type TEXT, // length INTEGER NOT NULL, // revpos INTEGER DEFAULT 0, // encoding INTEGER DEFAULT 0, // encoded_length INTEGER ); sqlite3_stmt attQuery = null; try { PrepareSQL(ref attQuery, "SELECT filename, key, type, length," + " revpos, encoding, encoded_length FROM attachments WHERE sequence=?"); } catch(CouchbaseLiteException) { Log.To.Upgrade.E(TAG, "Failed to create SQLite query for attachments table in " + "source database '{0}', rethrowing...", _path); throw; } catch(Exception e) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, e, TAG, "Error creating SQLite query for attachments table in source database '{0}'", _path); } raw.sqlite3_bind_int64(attQuery, 1, sequence); var attachments = new Dictionary<string, object>(); int err; while (raw.SQLITE_ROW == (err = raw.sqlite3_step(attQuery))) { string name = raw.sqlite3_column_text(attQuery, 0); var key = raw.sqlite3_column_blob(attQuery, 1); string mimeType = raw.sqlite3_column_text(attQuery, 2); long length = raw.sqlite3_column_int64(attQuery, 3); int revpos = raw.sqlite3_column_int(attQuery, 4); int encoding = raw.sqlite3_column_int(attQuery, 5); long encodedLength = raw.sqlite3_column_int64(attQuery, 6); if (key.Length != SHA1.Create().HashSize / 8) { raw.sqlite3_finalize(attQuery); throw Misc.CreateExceptionAndLog(Log.To.Upgrade, StatusCode.CorruptError, TAG, "Digest key length incorrect ({0})", Convert.ToBase64String(key)); } var blobKey = new BlobKey(key); var att = new NonNullDictionary<string, object> { { "type", mimeType }, { "digest", blobKey.Base64Digest() }, { "length", length }, { "revpos", revpos }, { "follows", true }, { "encoding", encoding != 0 ? "gzip" : null }, { "encoded_length", encoding != 0 ? (object)encodedLength : null } }; attachments[name] = att; } raw.sqlite3_finalize(attQuery); if (err != raw.SQLITE_DONE) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, SqliteErrToStatus(err).Code, TAG, "Failed to finalize attachment query ({0}: {1})", err, raw.sqlite3_errmsg(_sqlite)); } if (attachments.Count > 0) { // Splice attachment JSON into the document JSON: var attJson = Manager.GetObjectMapper().WriteValueAsBytes(new Dictionary<string, object> { { "_attachments", attachments } }); if (json.Count > 2) { json.Insert(json.Count - 1, (byte)','); } json.InsertRange(json.Count - 1, attJson.Skip(1).Take(attJson.Count() - 2)); } }
public static int sqlite3_prepare_v2( sqlite3 db, /* Database handle. */ string zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ ref sqlite3_stmt ppStmt, /* OUT: A pointer to the prepared statement */ ref string pzTail /* OUT: End of parsed string */ ) { int rc; rc = sqlite3LockAndPrepare( db, zSql, nBytes, 1, null, ref ppStmt, ref pzTail ); Debug.Assert( rc == SQLITE_OK || ppStmt == null ); /* VERIFY: F13021 */ return rc; }
public static sqlite_int64 sqlite3_column_int64( sqlite3_stmt pStmt, int i ) { sqlite_int64 val = sqlite3_value_int64( columnMem( pStmt, i ) ); columnMallocFailure( pStmt ); return val; }
public static void bind(this sqlite3_stmt stmt, int ndx, long v) { stmt.bind_int64(ndx, v); }
public static sqlite3_value sqlite3_column_value( sqlite3_stmt pStmt, int i ) { Mem pOut = columnMem( pStmt, i ); if ( ( pOut.flags & MEM_Static ) != 0 ) { pOut.flags = (u16)( pOut.flags & ~MEM_Static ); pOut.flags |= MEM_Ephem; } columnMallocFailure( pStmt ); return (sqlite3_value)pOut; }
public void Import() { // Rename the old database file for migration: var destPath = Path.ChangeExtension(_path, Manager.DatabaseSuffixv1 + "-mgr"); if (!MoveSqliteFiles(_path, destPath)) { MoveSqliteFiles(destPath, _path); throw Misc.CreateExceptionAndLog(Log.To.Upgrade, StatusCode.InternalServerError, TAG, "Upgrade failed: Cannot rename the old sqlite files"); } int version = DatabaseUpgraderFactory.SchemaVersion(destPath); if (version < 0) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, StatusCode.CorruptError, TAG, "Cannot determine database schema version"); } // Open source (SQLite) database: var err = raw.sqlite3_open_v2(destPath, out _sqlite, raw.SQLITE_OPEN_READWRITE, null); if (err > 0) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, SqliteErrToStatus(err).Code, TAG, "SQLite error while opening source database ({0})", err); } raw.sqlite3_create_collation(_sqlite, "JSON", raw.SQLITE_UTF8, CollateRevIDs); sqlite3_stmt stmt = null; PrepareSQL(ref stmt, "SELECT name FROM sqlite_master WHERE type='table' AND name='maps'"); err = raw.sqlite3_step(stmt); if (err == raw.SQLITE_ROW) { sqlite3_stmt stmt2 = null; PrepareSQL(ref stmt2, "SELECT * FROM maps"); while ((err = raw.sqlite3_step(stmt2)) == raw.SQLITE_ROW) { int viewId = raw.sqlite3_column_int(stmt2, 0); sqlite3_stmt stmt3 = null; PrepareSQL(ref stmt3, "CREATE TABLE IF NOT EXISTS maps_" + viewId + " (sequence INTEGER NOT NULL REFERENCES revs(sequence) ON DELETE CASCADE," + "key TEXT NOT NULL COLLATE JSON," + "value TEXT," + "fulltext_id INTEGER, " + "bbox_id INTEGER, " + "geokey BLOB)"); raw.sqlite3_step(stmt3); raw.sqlite3_finalize(stmt3); stmt3 = null; var sequence = raw.sqlite3_column_int64(stmt2, 1); var key = raw.sqlite3_column_text(stmt2, 2); var value = raw.sqlite3_column_text(stmt2, 3); var insertSql = String.Format("INSERT INTO maps_{0} (sequence, key, value) VALUES (?, ?, ?)", viewId); PrepareSQL(ref stmt3, insertSql); raw.sqlite3_bind_int64(stmt3, 0, sequence); raw.sqlite3_bind_text(stmt3, 1, key); raw.sqlite3_bind_text(stmt3, 2, value); raw.sqlite3_step(stmt3); raw.sqlite3_finalize(stmt3); } raw.sqlite3_finalize(stmt2); stmt2 = null; PrepareSQL(ref stmt2, "DROP TABLE maps"); raw.sqlite3_step(stmt2); raw.sqlite3_finalize(stmt2); } raw.sqlite3_finalize(stmt); raw.sqlite3_close(_sqlite); if (err != raw.SQLITE_DONE) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, SqliteErrToStatus(err).Code, TAG, "SQLite error during upgrade process ({0})", err); } if (version >= 101) { _db.Delete(); MoveSqliteFiles(destPath, _path); var secondaryUpgrade = new v11_upgrader(_db, _path); secondaryUpgrade.Import(); var newPath = Path.Combine(Path.GetDirectoryName(_path), _db.Name + Manager.DatabaseSuffix); if (newPath != _db.DbDirectory) { Directory.Move(Path.Combine(Path.GetDirectoryName(_path), _db.Name + Manager.DatabaseSuffix), _db.DbDirectory); } return; } Log.To.Upgrade.I(TAG, "Upgrading database v1.0 ({0}) to v1.1 at {1} ...", version, _path); err = raw.sqlite3_open_v2(destPath, out _sqlite, raw.SQLITE_OPEN_READONLY, null); if (err > 0) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, SqliteErrToStatus(err).Code, TAG, "Error opening destination SQLite file ({0})", err); } raw.sqlite3_create_collation(_sqlite, "REVID", raw.SQLITE_UTF8, CollateRevIDs); // Open destination database: try { _db.Open(); } catch(CouchbaseLiteException) { Log.To.Upgrade.E(TAG, "Upgrade failed: Couldn't open new db, rethrowing..."); throw; } catch(Exception e) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, e, TAG, "Error during upgrade; couldn't open new db"); } try { MoveAttachmentsDir(); } catch(CouchbaseLiteException) { Log.To.Upgrade.E(TAG, "Failed to move attachments directory for database at '{0}', rethrowing...", _path); throw; } catch(Exception e) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, e, TAG, "Error moving attachments directory for database at '{0}'", _path); } // Upgrade documents: // CREATE TABLE docs (doc_id INTEGER PRIMARY KEY, docid TEXT UNIQUE NOT NULL); sqlite3_stmt docQuery = null; PrepareSQL(ref docQuery, "SELECT doc_id, docid FROM docs"); _db.RunInTransaction(() => { int transactionErr; int count = 0; while(raw.SQLITE_ROW == (transactionErr = raw.sqlite3_step(docQuery))) { long docNumericID = raw.sqlite3_column_int64(docQuery, 0); string docID = raw.sqlite3_column_text(docQuery, 1); try { ImportDoc(docID, docNumericID); } catch(CouchbaseLiteException) { Log.To.Upgrade.E(TAG, "Failed to import document #{0} ({1}), rethrowing", docNumericID, new SecureLogString(docID, LogMessageSensitivity.PotentiallyInsecure)); throw; } catch(Exception e) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, e, TAG, "Error importing documents"); } if((++count % 1000) == 0) { Log.To.Upgrade.I(TAG, "Migrated {0} documents", count); } } return transactionErr == raw.SQLITE_DONE; }); raw.sqlite3_finalize(docQuery); try { ImportLocalDocs(); } catch(CouchbaseLiteException) { Log.To.Upgrade.E(TAG, "Failed to import local docs for database '{0}', rethrowing...", _path); throw; } catch(Exception e) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, e, TAG, "Error importing local docs for database '{0}'", _path); } try { ImportInfo(); } catch(CouchbaseLiteException) { Log.To.Upgrade.E(TAG, "Failed to import info for database '{0}', rethrowing...", _path); throw; } catch(Exception e) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, e, TAG, "Error importing info for database '{0}'", _path); } raw.sqlite3_close(_sqlite); _sqlite = null; File.Delete(destPath); File.Delete(destPath + "-wal"); File.Delete(destPath + "-shm"); }
public static void bind(this sqlite3_stmt stmt, int ndx, int v) { stmt.bind_int(ndx, v); }
public static string sqlite3_column_text( sqlite3_stmt pStmt, int i ) { string val = sqlite3_value_text( columnMem( pStmt, i ) ); columnMallocFailure( pStmt ); return val; }
private void ImportDoc(string docID, long docNumericID) { // CREATE TABLE revs ( // sequence INTEGER PRIMARY KEY AUTOINCREMENT, // doc_id INTEGER NOT NULL REFERENCES docs(doc_id) ON DELETE CASCADE, // revid TEXT NOT NULL COLLATE REVID, // parent INTEGER REFERENCES revs(sequence) ON DELETE SET NULL, // current BOOLEAN, // deleted BOOLEAN DEFAULT 0, // json BLOB, // no_attachments BOOLEAN, // UNIQUE (doc_id, revid) ); sqlite3_stmt revQuery = null; _inner.PrepareSQL(ref revQuery, "SELECT sequence, revid, parent, current, deleted, json, no_attachments" + " FROM revs WHERE doc_id=? ORDER BY sequence"); raw.sqlite3_bind_int64(revQuery, 1, docNumericID); var tree = new Dictionary<long, IList<object>>(); int err; while (raw.SQLITE_ROW == (err = raw.sqlite3_step(revQuery))) { long sequence = raw.sqlite3_column_int64(revQuery, 0); var revID = raw.sqlite3_column_text(revQuery, 1).AsRevID(); long parentSeq = raw.sqlite3_column_int64(revQuery, 2); bool current = raw.sqlite3_column_int(revQuery, 3) != 0; bool noAtts = raw.sqlite3_column_int(revQuery, 6) != 0; if (current) { // Add a leaf revision: bool deleted = raw.sqlite3_column_int(revQuery, 4) != 0; IEnumerable<byte> json = raw.sqlite3_column_blob(revQuery, 5); if (json == null) { json = Encoding.UTF8.GetBytes("{}"); } var nuJson = json.ToList(); if (!noAtts) { try { UpdateAttachmentFollows(nuJson); } catch(CouchbaseLiteException) { Log.To.Upgrade.E(TAG, "Failed to process attachments, rethrowing..."); throw; } catch(Exception e) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, e, TAG, "Error processing attachments"); } } json = nuJson; RevisionInternal rev = new RevisionInternal(docID, revID, deleted); rev.SetJson(json); var history = new List<RevisionID>(); history.Add(revID); while (parentSeq > 0) { var ancestor = tree.Get(parentSeq); Debug.Assert(ancestor != null, String.Format("Couldn't find parent sequence of {0} (doc {1})", parentSeq, docID)); history.Add((RevisionID)ancestor[0]); parentSeq = (long)ancestor[1]; } Log.To.Upgrade.V(TAG, "Upgrading doc {0} history {1}", rev, Manager.GetObjectMapper().WriteValueAsString(history)); try { _db.ForceInsert(rev, history, null); } catch (CouchbaseLiteException) { Log.To.Upgrade.E(TAG, "Failed to insert revision {0} into target database, rethrowing...", rev); raw.sqlite3_finalize(revQuery); throw; } catch(Exception e) { raw.sqlite3_finalize(revQuery); throw Misc.CreateExceptionAndLog(Log.To.Upgrade, e, TAG, "Error inserting revision {0} into target database", rev); } NumRevs++; } else { tree[sequence] = new List<object> { revID, parentSeq }; } } raw.sqlite3_finalize(revQuery); ++NumDocs; if (err != raw.SQLITE_OK) { var s = SqliteErrToStatus(err); if (s.IsError) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, s.Code, TAG, "SQLite error during upgrade ({0})", err); } } }
//const void *sqlite3_column_text16(sqlite3_stmt pStmt, int i){ // const void *val = sqlite3_value_text16( columnMem(pStmt,i) ); // columnMallocFailure(pStmt); // return val; //} #endif // * SQLITE_OMIT_UTF16 */ public static int sqlite3_column_type( sqlite3_stmt pStmt, int i ) { int iType = sqlite3_value_type( columnMem( pStmt, i ) ); columnMallocFailure( pStmt ); return iType; }
public void Import() { // Open source (SQLite) database: var err = raw.sqlite3_open_v2(_path, out _sqlite, raw.SQLITE_OPEN_READONLY, null); _inner = new v1_upgrader(_db, _sqlite); if (err > 0) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, SqliteErrToStatus(err).Code, TAG, "SQLite error opening source database ({0})", err); } raw.sqlite3_create_collation(_sqlite, "JSON", raw.SQLITE_UTF8, CollateRevIDs); raw.sqlite3_create_collation(_sqlite, "REVID", raw.SQLITE_UTF8, CollateRevIDs); // Open destination database: try { _db.Open(); } catch(CouchbaseLiteException) { Log.To.Upgrade.E(TAG, "Upgrade failed: Couldn't open new db, rethrowing"); throw; } catch(Exception e) { throw Misc.CreateExceptionAndLog(Log.To.Database, e, TAG, "Error during upgrade; couldn't open new db"); } // Upgrade documents: // CREATE TABLE docs (doc_id INTEGER PRIMARY KEY, docid TEXT UNIQUE NOT NULL); sqlite3_stmt docQuery = null; _inner.PrepareSQL(ref docQuery, "SELECT doc_id, docid FROM docs"); _db.RunInTransaction(() => { int transactionErr; int count = 0; while(raw.SQLITE_ROW == (transactionErr = raw.sqlite3_step(docQuery))) { long docNumericID = raw.sqlite3_column_int64(docQuery, 0); string docID = raw.sqlite3_column_text(docQuery, 1); try { ImportDoc(docID, docNumericID); } catch(CouchbaseLiteException) { Log.To.Database.E(TAG, "Failed to import document #{0} ({1}), rethrowing", docNumericID, new SecureLogString(docID, LogMessageSensitivity.PotentiallyInsecure)); throw; } catch(Exception e) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, e, TAG, "Error importing document #{0} ({1})", docNumericID, new SecureLogString(docID, LogMessageSensitivity.PotentiallyInsecure)); } if((++count % 1000) == 0) { Log.To.Upgrade.I(TAG, "Migrated {0} documents", count); } } return transactionErr == raw.SQLITE_DONE; }); raw.sqlite3_finalize(docQuery); try { _inner.ImportLocalDocs(); } catch(CouchbaseLiteException) { Log.To.Upgrade.E(TAG, "Failed to import local docs for database '{0}', rethrowing...", _path); throw; } catch(Exception e) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, e, TAG, "Error importing local docs for database '{0}'", _path); } try { _inner.ImportInfo(); } catch(CouchbaseLiteException) { Log.To.Upgrade.E(TAG, "Failed to import info for database '{0}', rethrowing...", _path); throw; } catch(Exception e) { throw Misc.CreateExceptionAndLog(Log.To.Upgrade, e, TAG, "Error importing info for database '{0}'", _path); } raw.sqlite3_close(_sqlite); _sqlite = null; foreach (var ext in new List<string> { "", "-wal", "-shm" }) { File.Delete(_path + ext); } }
public static string sqlite3_column_name16(sqlite3_stmt pStmt, int N){ return columnName( pStmt, N, sqlite3_value_text16, COLNAME_NAME); }
/* ** Load the content of the sqlite_stat1 and sqlite_stat2 tables. The ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] ** arrays. The contents of sqlite_stat2 are used to populate the ** Index.aSample[] arrays. ** ** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR ** is returned. In this case, even if SQLITE_ENABLE_STAT2 was defined ** during compilation and the sqlite_stat2 table is present, no data is ** read from it. ** ** If SQLITE_ENABLE_STAT2 was defined during compilation and the ** sqlite_stat2 table is not present in the database, SQLITE_ERROR is ** returned. However, in this case, data is read from the sqlite_stat1 ** table (if it is present) before returning. ** ** If an OOM error occurs, this function always sets db.mallocFailed. ** This means if the caller does not care about other errors, the return ** code may be ignored. */ static int sqlite3AnalysisLoad(sqlite3 db, int iDb) { analysisInfo sInfo; HashElem i; string zSql; int rc; Debug.Assert(iDb >= 0 && iDb < db.nDb); Debug.Assert(db.aDb[iDb].pBt != null); Debug.Assert(sqlite3BtreeHoldsMutex(db.aDb[iDb].pBt)); /* Clear any prior statistics */ //for(i=sqliteHashFirst(&db.aDb[iDb].pSchema.idxHash);i;i=sqliteHashNext(i)){ for (i = db.aDb[iDb].pSchema.idxHash.first; i != null; i = i.next) { Index pIdx = (Index)i.data;// sqliteHashData( i ); sqlite3DefaultRowEst(pIdx); sqlite3DeleteIndexSamples(db, pIdx); pIdx.aSample = null; } /* Check to make sure the sqlite_stat1 table exists */ sInfo.db = db; sInfo.zDatabase = db.aDb[iDb].zName; if (sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase) == null) { return(SQLITE_ERROR); } /* Load new statistics out of the sqlite_stat1 table */ zSql = sqlite3MPrintf(db, "SELECT tbl, idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase); if (zSql == null) { rc = SQLITE_NOMEM; } else { rc = sqlite3_exec(db, zSql, (dxCallback)analysisLoader, sInfo, 0); sqlite3DbFree(db, ref zSql); } /* Load the statistics from the sqlite_stat2 table. */ #if SQLITE_ENABLE_STAT2 if (rc == SQLITE_OK && null == sqlite3FindTable(db, "sqlite_stat2", sInfo.zDatabase)) { rc = SQLITE_ERROR; } if (rc == SQLITE_OK) { sqlite3_stmt pStmt = null; zSql = sqlite3MPrintf(db, "SELECT idx,sampleno,sample FROM %Q.sqlite_stat2", sInfo.zDatabase); //if( !zSql ){ //rc = SQLITE_NOMEM; //}else{ string sDummy = ""; rc = sqlite3_prepare(db, zSql, -1, ref pStmt, ref sDummy); sqlite3DbFree(db, ref zSql); //} if (rc == SQLITE_OK) { while (sqlite3_step(pStmt) == SQLITE_ROW) { string zIndex; /* Index name */ Index pIdx; /* Pointer to the index object */ zIndex = sqlite3_column_text(pStmt, 0); pIdx = !String.IsNullOrEmpty(zIndex) ? sqlite3FindIndex(db, zIndex, sInfo.zDatabase) : null; if (pIdx != null) { int iSample = sqlite3_column_int(pStmt, 1); if (iSample < SQLITE_INDEX_SAMPLES && iSample >= 0) { int eType = sqlite3_column_type(pStmt, 2); if (pIdx.aSample == null) { //static const int sz = sizeof(IndexSample)*SQLITE_INDEX_SAMPLES; //pIdx->aSample = (IndexSample *)sqlite3DbMallocRaw(0, sz); //if( pIdx.aSample==0 ){ //db.mallocFailed = 1; //break; //} pIdx.aSample = new IndexSample[SQLITE_INDEX_SAMPLES];//memset(pIdx->aSample, 0, sz); } //Debug.Assert( pIdx.aSample != null ); if (pIdx.aSample[iSample] == null) { pIdx.aSample[iSample] = new IndexSample(); } IndexSample pSample = pIdx.aSample[iSample]; { pSample.eType = (u8)eType; if (eType == SQLITE_INTEGER || eType == SQLITE_FLOAT) { pSample.u.r = sqlite3_column_double(pStmt, 2); } else if (eType == SQLITE_TEXT || eType == SQLITE_BLOB) { string z = null; byte[] zBLOB = null; //string z = (const char *)( //(eType==SQLITE_BLOB) ? //sqlite3_column_blob(pStmt, 2): //sqlite3_column_text(pStmt, 2) //); if (eType == SQLITE_BLOB) { zBLOB = sqlite3_column_blob(pStmt, 2); } else { z = sqlite3_column_text(pStmt, 2); } int n = sqlite3_column_bytes(pStmt, 2); if (n > 24) { n = 24; } pSample.nByte = (u8)n; if (n < 1) { pSample.u.z = null; pSample.u.zBLOB = null; } else { pSample.u.z = z; pSample.u.zBLOB = zBLOB; //pSample->u.z = sqlite3DbMallocRaw(dbMem, n); //if( pSample->u.z ){ // memcpy(pSample->u.z, z, n); //}else{ // db->mallocFailed = 1; // break; //} } } } } } } rc = sqlite3_finalize(pStmt); } } #endif //if( rc==SQLITE_NOMEM ){ // db.mallocFailed = 1; //} return(rc); }
//const void *sqlite3_column_decltype16(sqlite3_stmt pStmt, int N){ // return columnName( // pStmt, N, (const void*()(Mem))sqlite3_value_text16, COLNAME_DECLTYPE); //} #endif // * SQLITE_OMIT_UTF16 */ #endif // * SQLITE_OMIT_DECLTYPE */ #if SQLITE_ENABLE_COLUMN_METADATA /* ** Return the name of the database from which a result column derives. ** NULL is returned if the result column is an expression or constant or ** anything else which is not an unabiguous reference to a database column. */ public static string sqlite3_column_database_name( sqlite3_stmt pStmt, int N ) { return columnName( pStmt, N, sqlite3_value_text, COLNAME_DATABASE ); }
/* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare( sqlite3 db, /* Database handle. */ string zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ Vdbe pReprepare, /* VM being reprepared */ ref sqlite3_stmt ppStmt, /* OUT: A pointer to the prepared statement */ ref string pzTail /* OUT: End of parsed string */ ) { Parse pParse; /* Parsing context */ string zErrMsg = ""; /* Error message */ int rc = SQLITE_OK; /* Result code */ int i; /* Loop counter */ ppStmt = null; pzTail = null; /* Allocate the parsing context */ pParse = new Parse();//sqlite3StackAllocZero(db, sizeof(*pParse)); //if ( pParse == null ) //{ // rc = SQLITE_NOMEM; // goto end_prepare; //} pParse.pReprepare = pReprepare; pParse.sLastToken.z = ""; // assert( ppStmt && *ppStmt==0 ); //Debug.Assert( 0 == db.mallocFailed ); Debug.Assert(sqlite3_mutex_held(db.mutex)); /* Check to verify that it is possible to get a read lock on all ** database schemas. The inability to get a read lock indicates that ** some other database connection is holding a write-lock, which in ** turn means that the other connection has made uncommitted changes ** to the schema. ** ** Were we to proceed and prepare the statement against the uncommitted ** schema changes and if those schema changes are subsequently rolled ** back and different changes are made in their place, then when this ** prepared statement goes to run the schema cookie would fail to detect ** the schema change. Disaster would follow. ** ** This thread is currently holding mutexes on all Btrees (because ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it ** is not possible for another thread to start a new schema change ** while this routine is running. Hence, we do not need to hold ** locks on the schema, we just need to make sure nobody else is ** holding them. ** ** Note that setting READ_UNCOMMITTED overrides most lock detection, ** but it does *not* override schema lock detection, so this all still ** works even if READ_UNCOMMITTED is set. */ for (i = 0; i < db.nDb; i++) { Btree pBt = db.aDb[i].pBt; if (pBt != null) { Debug.Assert(sqlite3BtreeHoldsMutex(pBt)); rc = sqlite3BtreeSchemaLocked(pBt); if (rc != 0) { string zDb = db.aDb[i].zName; sqlite3Error(db, rc, "database schema is locked: %s", zDb); testcase(db.flags & SQLITE_ReadUncommitted); goto end_prepare; } } } sqlite3VtabUnlockList(db); pParse.db = db; pParse.nQueryLoop = (double)1; if (nBytes >= 0 && (nBytes == 0 || zSql[nBytes - 1] != 0)) { string zSqlCopy; int mxLen = db.aLimit[SQLITE_LIMIT_SQL_LENGTH]; testcase(nBytes == mxLen); testcase(nBytes == mxLen + 1); if (nBytes > mxLen) { sqlite3Error(db, SQLITE_TOOBIG, "statement too long"); rc = sqlite3ApiExit(db, SQLITE_TOOBIG); goto end_prepare; } zSqlCopy = zSql.Substring(0, nBytes);// sqlite3DbStrNDup(db, zSql, nBytes); if (zSqlCopy != null) { sqlite3RunParser(pParse, zSqlCopy, ref zErrMsg); sqlite3DbFree(db, ref zSqlCopy); //pParse->zTail = &zSql[pParse->zTail-zSqlCopy]; } else { //pParse->zTail = &zSql[nBytes]; } } else { sqlite3RunParser(pParse, zSql, ref zErrMsg); } Debug.Assert(1 == (int)pParse.nQueryLoop); //if ( db.mallocFailed != 0 ) //{ // pParse.rc = SQLITE_NOMEM; //} if (pParse.rc == SQLITE_DONE) { pParse.rc = SQLITE_OK; } if (pParse.checkSchema != 0) { schemaIsValid(pParse); } //if ( db.mallocFailed != 0 ) //{ // pParse.rc = SQLITE_NOMEM; //} //if (pzTail != null) { pzTail = pParse.zTail == null ? "" : pParse.zTail.ToString(); } rc = pParse.rc; #if !SQLITE_OMIT_EXPLAIN if (rc == SQLITE_OK && pParse.pVdbe != null && pParse.explain != 0) { string[] azColName = new string[] { "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", "selectid", "order", "from", "detail" }; int iFirst, mx; if (pParse.explain == 2) { sqlite3VdbeSetNumCols(pParse.pVdbe, 4); iFirst = 8; mx = 12; } else { sqlite3VdbeSetNumCols(pParse.pVdbe, 8); iFirst = 0; mx = 8; } for (i = iFirst; i < mx; i++) { sqlite3VdbeSetColName(pParse.pVdbe, i - iFirst, COLNAME_NAME, azColName[i], SQLITE_STATIC); } } #endif Debug.Assert(db.init.busy == 0 || saveSqlFlag == 0); if (db.init.busy == 0) { Vdbe pVdbe = pParse.pVdbe; sqlite3VdbeSetSql(pVdbe, zSql, (int)(zSql.Length - (pParse.zTail == null ? 0 : pParse.zTail.Length)), saveSqlFlag); } if (pParse.pVdbe != null && (rc != SQLITE_OK /*|| db.mallocFailed != 0 */)) { sqlite3VdbeFinalize(ref pParse.pVdbe); //Debug.Assert( ppStmt == null ); } else { ppStmt = pParse.pVdbe; } if (zErrMsg != "") { sqlite3Error(db, rc, "%s", zErrMsg); sqlite3DbFree(db, ref zErrMsg); } else { sqlite3Error(db, rc, 0); } /* Delete any TriggerPrg structures allocated while parsing this statement. */ while (pParse.pTriggerPrg != null) { TriggerPrg pT = pParse.pTriggerPrg; pParse.pTriggerPrg = pT.pNext; sqlite3DbFree(db, ref pT); } end_prepare: //sqlite3StackFree( db, pParse ); rc = sqlite3ApiExit(db, rc); Debug.Assert((rc & db.errMask) == rc); return(rc); }
/* ** Set all the parameters in the compiled SQL statement to NULL. */ public static int sqlite3_clear_bindings( sqlite3_stmt pStmt ) { int i; int rc = SQLITE_OK; Vdbe p = (Vdbe)pStmt; #if SQLITE_THREADSAFE sqlite3_mutex mutex = ( (Vdbe)pStmt ).db.mutex; #endif sqlite3_mutex_enter( mutex ); for ( i = 0; i < p.nVar; i++ ) { sqlite3VdbeMemRelease( p.aVar[i] ); p.aVar[i].flags = MEM_Null; } if ( p.isPrepareV2 && p.expmask != 0 ) { p.expired = true; } sqlite3_mutex_leave( mutex ); return rc; }
/* ** This is the callback routine for the code that initializes the ** database. See sqlite3Init() below for additional information. ** This routine is also called from the OP_ParseSchema opcode of the VDBE. ** ** Each callback contains the following information: ** ** argv[0] = name of thing being created ** argv[1] = root page number for table or index. 0 for trigger or view. ** argv[2] = SQL text for the CREATE statement. ** */ static int sqlite3InitCallback(object pInit, sqlite3_int64 argc, object p2, object NotUsed) { string[] argv = (string[])p2; InitData pData = (InitData)pInit; sqlite3 db = pData.db; int iDb = pData.iDb; Debug.Assert(argc == 3); UNUSED_PARAMETER2(NotUsed, argc); Debug.Assert(sqlite3_mutex_held(db.mutex)); DbClearProperty(db, iDb, DB_Empty); //if ( db.mallocFailed != 0 ) //{ // corruptSchema( pData, argv[0], "" ); // return 1; //} Debug.Assert(iDb >= 0 && iDb < db.nDb); if (argv == null) { return(0); /* Might happen if EMPTY_RESULT_CALLBACKS are on */ } if (argv[1] == null) { corruptSchema(pData, argv[0], ""); } else if (!String.IsNullOrEmpty(argv[2])) { /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db.init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. */ int rc; sqlite3_stmt pStmt = null; #if !NDEBUG || SQLITE_COVERAGE_TEST //TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ int rcp; #endif Debug.Assert(db.init.busy != 0); db.init.iDb = iDb; db.init.newTnum = sqlite3Atoi(argv[1]); db.init.orphanTrigger = 0; //TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0); #if !NDEBUG || SQLITE_COVERAGE_TEST rcp = sqlite3_prepare(db, argv[2], -1, ref pStmt, 0); #else sqlite3_prepare(db, argv[2], -1, ref pStmt, 0); #endif rc = db.errCode; #if !NDEBUG || SQLITE_COVERAGE_TEST Debug.Assert((rc & 0xFF) == (rcp & 0xFF)); #endif db.init.iDb = 0; if (SQLITE_OK != rc) { if (db.init.orphanTrigger != 0) { Debug.Assert(iDb == 1); } else { pData.rc = rc; //if ( rc == SQLITE_NOMEM ) //{ // // db.mallocFailed = 1; //} //else if (rc != SQLITE_INTERRUPT && (rc & 0xFF) != SQLITE_LOCKED) { corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } } } sqlite3_finalize(pStmt); } else if (argv[0] == null || argv[0] == "") { corruptSchema(pData, null, null); } else { /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE ** constraint for a CREATE TABLE. The index should have already ** been created when we processed the CREATE TABLE. All we have ** to do here is record the root page number for that index. */ Index pIndex; pIndex = sqlite3FindIndex(db, argv[0], db.aDb[iDb].zName); if (pIndex == null) { /* This can occur if there exists an index on a TEMP table which ** has the same name as another index on a permanent index. Since ** the permanent table is hidden by the TEMP table, we can also ** safely ignore the index on the permanent table. */ /* Do Nothing */ ; } else if (sqlite3GetInt32(argv[1], ref pIndex.tnum) == false) { corruptSchema(pData, argv[0], "invalid rootpage"); } } return(0); }
/* ** This is the top-level implementation of sqlite3_step(). Call ** sqlite3Step() to do most of the work. If a schema error occurs, ** call sqlite3Reprepare() and try again. */ public static int sqlite3_step( sqlite3_stmt pStmt ) { int rc = SQLITE_OK; /* Result from sqlite3Step() */ int rc2 = SQLITE_OK; /* Result from sqlite3Reprepare() */ Vdbe v = (Vdbe)pStmt; /* the prepared statement */ int cnt = 0; /* Counter to prevent infinite loop of reprepares */ sqlite3 db; /* The database connection */ if ( vdbeSafetyNotNull( v ) ) { return SQLITE_MISUSE_BKPT(); } db = v.db; sqlite3_mutex_enter( db.mutex ); while ( ( rc = sqlite3Step( v ) ) == SQLITE_SCHEMA && cnt++ < SQLITE_MAX_SCHEMA_RETRY && ( rc2 = rc = sqlite3Reprepare( v ) ) == SQLITE_OK ) { sqlite3_reset( pStmt ); v.expired = false; } if ( rc2 != SQLITE_OK && ALWAYS( v.isPrepareV2 ) && ALWAYS( db.pErr != null ) ) { /* This case occurs after failing to recompile an sql statement. ** The error message from the SQL compiler has already been loaded ** into the database handle. This block copies the error message ** from the database handle into the statement and sets the statement ** program counter to 0 to ensure that when the statement is ** finalized or reset the parser error message is available via ** sqlite3_errmsg() and sqlite3_errcode(). */ string zErr = sqlite3_value_text( db.pErr ); sqlite3DbFree( db, ref v.zErrMsg ); //if ( 0 == db.mallocFailed ) { v.zErrMsg = zErr;// sqlite3DbStrDup(db, zErr); v.rc = rc2; } //else //{ // v.zErrMsg = string.Empty; // v->rc = rc = SQLITE_NOMEM; //} } rc = sqlite3ApiExit( db, rc ); sqlite3_mutex_leave( db.mutex ); return rc; }
internal static void CheckOk(sqlite3_stmt stmt, int rc) => CheckOk(raw.sqlite3_db_handle(stmt), rc);
/* ** Return the number of values available from the current row of the ** currently executing statement pStmt. */ public static int sqlite3_data_count( sqlite3_stmt pStmt ) { Vdbe pVm = pStmt; if ( pVm == null || pVm.pResultSet == null ) return 0; return pVm.nResColumn; }
static public int sqlite3_exec( sqlite3 db, /* The database on which the SQL executes */ string zSql, /* The SQL to be executed */ sqlite3_callback xCallback, /* Invoke this callback routine */ object pArg, /* First argument to xCallback() */ ref string pzErrMsg /* Write error messages here */ ) { int rc = SQLITE_OK; /* Return code */ string zLeftover = ""; /* Tail of unprocessed SQL */ sqlite3_stmt pStmt = null; /* The current SQL statement */ string[] azCols = null; /* Names of result columns */ int nRetry = 0; /* Number of retry attempts */ int callbackIsInit; /* True if callback data is initialized */ if (!sqlite3SafetyCheckOk(db)) { return(SQLITE_MISUSE_BKPT()); } if (zSql == null) { zSql = ""; } sqlite3_mutex_enter(db.mutex); sqlite3Error(db, SQLITE_OK, 0); while ((rc == SQLITE_OK || (rc == SQLITE_SCHEMA && (++nRetry) < 2)) && zSql != "") { int nCol; string[] azVals = null; pStmt = null; rc = sqlite3_prepare(db, zSql, -1, ref pStmt, ref zLeftover); Debug.Assert(rc == SQLITE_OK || pStmt == null); if (rc != SQLITE_OK) { continue; } if (pStmt == null) { /* this happens for a comment or white-space */ zSql = zLeftover; continue; } callbackIsInit = 0; nCol = sqlite3_column_count(pStmt); while (true) { int i; rc = sqlite3_step(pStmt); /* Invoke the callback function if required */ if (xCallback != null && (SQLITE_ROW == rc || (SQLITE_DONE == rc && callbackIsInit == 0 && (db.flags & SQLITE_NullCallback) != 0))) { if (0 == callbackIsInit) { azCols = new string[nCol];//sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1); //if ( azCols == null ) //{ // goto exec_out; //} for (i = 0; i < nCol; i++) { azCols[i] = sqlite3_column_name(pStmt, i); /* sqlite3VdbeSetColName() installs column names as UTF8 ** strings so there is no way for sqlite3_column_name() to fail. */ Debug.Assert(azCols[i] != null); } callbackIsInit = 1; } if (rc == SQLITE_ROW) { azVals = new string[nCol];// azCols[nCol]; for (i = 0; i < nCol; i++) { azVals[i] = sqlite3_column_text(pStmt, i); if (azVals[i] == null && sqlite3_column_type(pStmt, i) != SQLITE_NULL) { //db.mallocFailed = 1; //goto exec_out; } } } if (xCallback(pArg, nCol, azVals, azCols) != 0) { rc = SQLITE_ABORT; sqlite3VdbeFinalize(ref pStmt); pStmt = null; sqlite3Error(db, SQLITE_ABORT, 0); goto exec_out; } } if (rc != SQLITE_ROW) { rc = sqlite3VdbeFinalize(ref pStmt); pStmt = null; if (rc != SQLITE_SCHEMA) { nRetry = 0; if ((zSql = zLeftover) != "") { int zindex = 0; while (zindex < zSql.Length && sqlite3Isspace(zSql[zindex])) { zindex++; } if (zindex != 0) { zSql = zindex < zSql.Length ? zSql.Substring(zindex) : ""; } } } break; } } sqlite3DbFree(db, ref azCols); azCols = null; } exec_out: if (pStmt != null) { sqlite3VdbeFinalize(ref pStmt); } sqlite3DbFree(db, ref azCols); rc = sqlite3ApiExit(db, rc); if (rc != SQLITE_OK && ALWAYS(rc == sqlite3_errcode(db)) && pzErrMsg != null) { //int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db)); //pzErrMsg = sqlite3Malloc(nErrMsg); //if (pzErrMsg) //{ // memcpy(pzErrMsg, sqlite3_errmsg(db), nErrMsg); //}else{ //rc = SQLITE_NOMEM; //sqlite3Error(db, SQLITE_NOMEM, 0); //} pzErrMsg = sqlite3_errmsg(db); } else if (pzErrMsg != "") { pzErrMsg = ""; } Debug.Assert((rc & db.errMask) == rc); sqlite3_mutex_leave(db.mutex); return(rc); }
/* ** This function is called after invoking an sqlite3_value_XXX function on a ** column value (i.e. a value returned by evaluating an SQL expression in the ** select list of a SELECT statement) that may cause a malloc() failure. If ** malloc() has failed, the threads mallocFailed flag is cleared and the result ** code of statement pStmt set to SQLITE_NOMEM. ** ** Specifically, this is called from within: ** ** sqlite3_column_int() ** sqlite3_column_int64() ** sqlite3_column_text() ** sqlite3_column_text16() ** sqlite3_column_real() ** sqlite3_column_bytes() ** sqlite3_column_bytes16() ** sqlite3_column_blob() */ static void columnMallocFailure( sqlite3_stmt pStmt ) { /* If malloc() failed during an encoding conversion within an ** sqlite3_column_XXX API, then set the return code of the statement to ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR ** and _finalize() will return NOMEM. */ Vdbe p = pStmt; if ( p != null ) { p.rc = sqlite3ApiExit( p.db, p.rc ); sqlite3_mutex_leave( p.db.mutex ); } }
/// <summary> /// Avoids the additional database trip that using SqliteCommandBuilder requires. /// </summary> /// <returns>The insert command.</returns> /// <param name="table">Table.</param> /// <param name="values">Values.</param> /// <param name="conflictResolutionStrategy">Conflict resolution strategy.</param> sqlite3_stmt GetInsertCommand(String table, ContentValues values, ConflictResolutionStrategy conflictResolutionStrategy) { if (!IsOpen) { throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.BadRequest, TAG, "GetInsertCommand called on closed database"); } var builder = new StringBuilder("INSERT"); if (conflictResolutionStrategy != ConflictResolutionStrategy.None) { builder.Append(" OR "); builder.Append(conflictResolutionStrategy); } builder.Append(" INTO "); builder.Append(table); builder.Append(" ("); // Append our content column names and create our SQL parameters. var valueSet = values.ValueSet(); var valueBuilder = new StringBuilder(); var index = 0; var args = new object[valueSet.Count]; foreach (var column in valueSet) { if (index > 0) { builder.Append(","); valueBuilder.Append(","); } builder.AppendFormat("{0}", column.Key); valueBuilder.Append("?"); args[index] = column.Value; index++; } builder.Append(") VALUES ("); builder.Append(valueBuilder); builder.Append(")"); var sql = builder.ToString(); sqlite3_stmt command = null; if (args != null) { Log.To.Database.V(TAG, "Preparing statement: '{0}' with values: {1}", sql, new SecureLogJsonString(args, LogMessageSensitivity.PotentiallyInsecure)); } else { Log.To.Database.V(TAG, "Preparing statement: '{0}'", sql); } command = BuildCommand(_writeConnection, sql, args); return(command); }
/* ** The following routine destroys a virtual machine that is created by ** the sqlite3_compile() routine. The integer returned is an SQLITE_ ** success/failure code that describes the result of executing the virtual ** machine. ** ** This routine sets the error code and string returned by ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ public static int sqlite3_finalize( sqlite3_stmt pStmt ) { int rc; if ( pStmt == null ) { /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL ** pointer is a harmless no-op. */ rc = SQLITE_OK; } else { Vdbe v = pStmt; sqlite3 db = v.db; #if SQLITE_THREADSAFE sqlite3_mutex mutex; #endif if ( vdbeSafety( v ) ) return SQLITE_MISUSE_BKPT(); #if SQLITE_THREADSAFE mutex = v.db.mutex; #endif sqlite3_mutex_enter( mutex ); rc = sqlite3VdbeFinalize( ref v ); rc = sqlite3ApiExit( db, rc ); sqlite3_mutex_leave( mutex ); } return rc; }
public static sqlite3_stmt next_stmt(this sqlite3 db, sqlite3_stmt s) { return(raw.sqlite3_next_stmt(db, s)); }
public static double sqlite3_column_double( sqlite3_stmt pStmt, int i ) { double val = sqlite3_value_double( columnMem( pStmt, i ) ); columnMallocFailure( pStmt ); return val; }
public static int stmt_busy(this sqlite3_stmt stmt) { return(raw.sqlite3_stmt_busy(stmt)); }
/* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare( sqlite3 db, /* Database handle. */ string zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */ Vdbe pReprepare, /* VM being reprepared */ ref sqlite3_stmt ppStmt, /* OUT: A pointer to the prepared statement */ ref string pzTail /* OUT: End of parsed string */ ) { Parse pParse; /* Parsing context */ string zErrMsg = ""; /* Error message */ int rc = SQLITE_OK; /* Result code */ int i; /* Loop counter */ /* Allocate the parsing context */ pParse = new Parse();//sqlite3StackAllocZero(db, sizeof(*pParse)); if ( pParse == null ) { rc = SQLITE_NOMEM; goto end_prepare; } pParse.pReprepare = pReprepare; pParse.sLastToken.z = ""; Debug.Assert( ppStmt == null );// assert( ppStmt && *ppStmt==0 ); //Debug.Assert( 0 == db.mallocFailed ); Debug.Assert( sqlite3_mutex_held( db.mutex ) ); /* Check to verify that it is possible to get a read lock on all ** database schemas. The inability to get a read lock indicates that ** some other database connection is holding a write-lock, which in ** turn means that the other connection has made uncommitted changes ** to the schema. ** ** Were we to proceed and prepare the statement against the uncommitted ** schema changes and if those schema changes are subsequently rolled ** back and different changes are made in their place, then when this ** prepared statement goes to run the schema cookie would fail to detect ** the schema change. Disaster would follow. ** ** This thread is currently holding mutexes on all Btrees (because ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it ** is not possible for another thread to start a new schema change ** while this routine is running. Hence, we do not need to hold ** locks on the schema, we just need to make sure nobody else is ** holding them. ** ** Note that setting READ_UNCOMMITTED overrides most lock detection, ** but it does *not* override schema lock detection, so this all still ** works even if READ_UNCOMMITTED is set. */ for ( i = 0; i < db.nDb; i++ ) { Btree pBt = db.aDb[i].pBt; if ( pBt != null ) { Debug.Assert( sqlite3BtreeHoldsMutex( pBt ) ); rc = sqlite3BtreeSchemaLocked( pBt ); if ( rc != 0 ) { string zDb = db.aDb[i].zName; sqlite3Error( db, rc, "database schema is locked: %s", zDb ); testcase( db.flags & SQLITE_ReadUncommitted ); goto end_prepare; } } } sqlite3VtabUnlockList( db ); pParse.db = db; pParse.nQueryLoop = (double)1; if ( nBytes >= 0 && ( nBytes == 0 || zSql[nBytes - 1] != 0 ) ) { string zSqlCopy; int mxLen = db.aLimit[SQLITE_LIMIT_SQL_LENGTH]; testcase( nBytes == mxLen ); testcase( nBytes == mxLen + 1 ); if ( nBytes > mxLen ) { sqlite3Error( db, SQLITE_TOOBIG, "statement too long" ); rc = sqlite3ApiExit( db, SQLITE_TOOBIG ); goto end_prepare; } zSqlCopy = zSql.Substring( 0, nBytes );// sqlite3DbStrNDup(db, zSql, nBytes); if ( zSqlCopy != null ) { sqlite3RunParser( pParse, zSqlCopy, ref zErrMsg ); sqlite3DbFree( db, ref zSqlCopy ); //pParse->zTail = &zSql[pParse->zTail-zSqlCopy]; } else { //pParse->zTail = &zSql[nBytes]; } } else { sqlite3RunParser( pParse, zSql, ref zErrMsg ); } Debug.Assert( 1 == (int)pParse.nQueryLoop ); //if ( db.mallocFailed != 0 ) //{ // pParse.rc = SQLITE_NOMEM; //} if ( pParse.rc == SQLITE_DONE ) pParse.rc = SQLITE_OK; if ( pParse.checkSchema != 0 ) { schemaIsValid( pParse ); } if ( pParse.rc == SQLITE_SCHEMA ) { sqlite3ResetInternalSchema( db, 0 ); } //if ( db.mallocFailed != 0 ) //{ // pParse.rc = SQLITE_NOMEM; //} //if (pzTail != null) { pzTail = pParse.zTail == null ? "" : pParse.zTail.ToString(); } rc = pParse.rc; #if !SQLITE_OMIT_EXPLAIN if ( rc == SQLITE_OK && pParse.pVdbe != null && pParse.explain != 0 ) { string[] azColName = new string[] { "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", "selectid", "order", "from", "detail" }; int iFirst, mx; if ( pParse.explain == 2 ) { sqlite3VdbeSetNumCols( pParse.pVdbe, 4 ); iFirst = 8; mx = 12; } else { sqlite3VdbeSetNumCols( pParse.pVdbe, 8 ); iFirst = 0; mx = 8; } for ( i = iFirst; i < mx; i++ ) { sqlite3VdbeSetColName( pParse.pVdbe, i - iFirst, COLNAME_NAME, azColName[i], SQLITE_STATIC ); } } #endif Debug.Assert( db.init.busy == 0 || saveSqlFlag == 0 ); if ( db.init.busy == 0 ) { Vdbe pVdbe = pParse.pVdbe; sqlite3VdbeSetSql( pVdbe, zSql, (int)( zSql.Length - ( pParse.zTail == null ? 0 : pParse.zTail.Length ) ), saveSqlFlag ); } if ( pParse.pVdbe != null && ( rc != SQLITE_OK /*|| db.mallocFailed != 0 */ ) ) { sqlite3VdbeFinalize( pParse.pVdbe ); Debug.Assert( ppStmt == null ); } else { ppStmt = pParse.pVdbe; } if ( zErrMsg != "" ) { sqlite3Error( db, rc, "%s", zErrMsg ); sqlite3DbFree( db, ref zErrMsg ); } else { sqlite3Error( db, rc, 0 ); } /* Delete any TriggerPrg structures allocated while parsing this statement. */ while ( pParse.pTriggerPrg != null ) { TriggerPrg pT = pParse.pTriggerPrg; pParse.pTriggerPrg = pT.pNext; sqlite3DbFree( db, ref pT ); } end_prepare: //sqlite3StackFree( db, pParse ); rc = sqlite3ApiExit( db, rc ); Debug.Assert( ( rc & db.errMask ) == rc ); return rc; }
public static int stmt_readonly(this sqlite3_stmt stmt) { return(raw.sqlite3_stmt_readonly(stmt)); }
/* ** Rerun the compilation of a statement after a schema change. ** ** If the statement is successfully recompiled, return SQLITE_OK. Otherwise, ** if the statement cannot be recompiled because another connection has ** locked the sqlite3_master table, return SQLITE_LOCKED. If any other error ** occurs, return SQLITE_SCHEMA. */ static int sqlite3Reprepare( Vdbe p ) { int rc; sqlite3_stmt pNew = new sqlite3_stmt(); string zSql; sqlite3 db; Debug.Assert( sqlite3_mutex_held( sqlite3VdbeDb( p ).mutex ) ); zSql = sqlite3_sql( (sqlite3_stmt)p ); Debug.Assert( zSql != null ); /* Reprepare only called for prepare_v2() statements */ db = sqlite3VdbeDb( p ); Debug.Assert( sqlite3_mutex_held( db.mutex ) ); string dummy = ""; rc = sqlite3LockAndPrepare( db, zSql, -1, 0, p, ref pNew, ref dummy ); if ( rc != 0 ) { if ( rc == SQLITE_NOMEM ) { // db.mallocFailed = 1; } Debug.Assert( pNew == null ); return rc; } else { Debug.Assert( pNew != null ); } sqlite3VdbeSwap( (Vdbe)pNew, p ); sqlite3TransferBindings( pNew, (sqlite3_stmt)p ); sqlite3VdbeResetStepResult( (Vdbe)pNew ); sqlite3VdbeFinalize( (Vdbe)pNew ); return SQLITE_OK; }
public static string column_database_name(this sqlite3_stmt stmt, int index) { return(raw.sqlite3_column_database_name(stmt, index)); }
/* ** Compile the UTF-16 encoded SQL statement zSql into a statement handle. */ static int sqlite3Prepare16( sqlite3 db, /* Database handle. */ string zSql, /* UTF-15 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ bool saveSqlFlag, /* True to save SQL text into the sqlite3_stmt */ ref sqlite3_stmt ppStmt, /* OUT: A pointer to the prepared statement */ ref string pzTail /* OUT: End of parsed string */ ){ /* This function currently works by first transforming the UTF-16 ** encoded string to UTF-8, then invoking sqlite3_prepare(). The ** tricky bit is figuring out the pointer to return in pzTail. */ string zSql8; string zTail8 = ""; int rc = SQLITE_OK; assert( ppStmt ); *ppStmt = 0; if( !sqlite3SafetyCheckOk(db) ){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(db.mutex); zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); if( zSql8 !=""){ rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, null, ref ppStmt, ref zTail8); } if( zTail8 !="" && pzTail !=""){ /* If sqlite3_prepare returns a tail pointer, we calculate the ** equivalent pointer into the UTF-16 string by counting the unicode ** characters between zSql8 and zTail8, and then returning a pointer ** the same number of characters into the UTF-16 string. */ Debugger.Break (); // TODO -- // int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); // pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); } sqlite3DbFree(db,ref zSql8); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db.mutex); return rc; }
public static void bind(this sqlite3_stmt stmt, params object[] a) { if (a == null) { return; } int count = Math.Min(stmt.bind_parameter_count(), a.Length); // TODO instead of Math.Min(), consider comparing the two // counts and throwing if they're not equal. for (int i = 0; i < count; i++) { int ndx = i + 1; if (a[i] == null) { //Console.WriteLine("bind: {0} null", i); stmt.bind_null(ndx); } else { Type t = a[i].GetType(); //Console.WriteLine("bind: {0} {1} -- {2}", i, t, a[i]); if (typeof(String) == t) { stmt.bind_text(ndx, (string)a[i]); } else if ( (typeof(Int32) == t) || (typeof(Boolean) == t) || (typeof(Byte) == t) || (typeof(UInt16) == t) || (typeof(Int16) == t) || (typeof(sbyte) == t) || (typeof(Int64) == t) || (typeof(UInt32) == t) ) { stmt.bind_int64(ndx, (long)(Convert.ChangeType(a[i], typeof(long), null))); } else if ( (typeof(double) == t) || (typeof(float) == t) || (typeof(decimal) == t) ) { stmt.bind_double(ndx, (double)(Convert.ChangeType(a[i], typeof(double), null))); } else if (typeof(DateTime) == t) { DateTime d = (DateTime)a[i]; DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0); TimeSpan diff = d.ToUniversalTime() - origin; stmt.bind_int64(ndx, (long)diff.TotalSeconds); } else if (typeof(byte[]) == t) { stmt.bind_blob(ndx, (byte[])a[i]); } else { throw new NotSupportedException("Invalid type conversion" + t); } } } }