SQLite3.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. //
  2. // Copyright (c) 2009-2024 Krueger Systems, Inc.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #if WINDOWS_PHONE && !USE_WP8_NATIVE_SQLITE
  23. #define USE_CSHARP_SQLITE
  24. #endif
  25. #if !USE_SQLITEPCL_RAW
  26. using System.Runtime.InteropServices;
  27. #endif
  28. #if USE_CSHARP_SQLITE
  29. using Sqlite3 = Community.CsharpSqlite.Sqlite3;
  30. using Sqlite3DatabaseHandle = Community.CsharpSqlite.Sqlite3.sqlite3;
  31. using Sqlite3Statement = Community.CsharpSqlite.Sqlite3.Vdbe;
  32. #elif USE_WP8_NATIVE_SQLITE
  33. using Sqlite3 = Sqlite.Sqlite3;
  34. using Sqlite3DatabaseHandle = Sqlite.Database;
  35. using Sqlite3Statement = Sqlite.Statement;
  36. #elif USE_SQLITEPCL_RAW
  37. using Sqlite3DatabaseHandle = SQLitePCL.sqlite3;
  38. using Sqlite3BackupHandle = SQLitePCL.sqlite3_backup;
  39. using Sqlite3Statement = SQLitePCL.sqlite3_stmt;
  40. using Sqlite3 = SQLitePCL.raw;
  41. #else
  42. using Sqlite3DatabaseHandle = System.IntPtr;
  43. using Sqlite3BackupHandle = System.IntPtr;
  44. #endif
  45. #pragma warning disable 1591 // XML Doc Comments
  46. namespace SQLite
  47. {
  48. public static class SQLite3
  49. {
  50. static SQLite3()
  51. {
  52. if(RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
  53. {
  54. nativeLoader = new NativeLibraryLoader.NativeLoader("libsqlite3.so.0");
  55. nativeLoader.SearchDirectories.Add("/usr/lib/");
  56. }
  57. else
  58. {
  59. nativeLoader = new NativeLibraryLoader.NativeLoader("e_sqlite3.dll");
  60. nativeLoader.SearchDirectories.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"runtimes"));
  61. }
  62. nativeLoader.Init();
  63. }
  64. private static NativeLibraryLoader.NativeLoader nativeLoader;
  65. public enum Result : int
  66. {
  67. OK = 0,
  68. Error = 1,
  69. Internal = 2,
  70. Perm = 3,
  71. Abort = 4,
  72. Busy = 5,
  73. Locked = 6,
  74. NoMem = 7,
  75. ReadOnly = 8,
  76. Interrupt = 9,
  77. IOError = 10,
  78. Corrupt = 11,
  79. NotFound = 12,
  80. Full = 13,
  81. CannotOpen = 14,
  82. LockErr = 15,
  83. Empty = 16,
  84. SchemaChngd = 17,
  85. TooBig = 18,
  86. Constraint = 19,
  87. Mismatch = 20,
  88. Misuse = 21,
  89. NotImplementedLFS = 22,
  90. AccessDenied = 23,
  91. Format = 24,
  92. Range = 25,
  93. NonDBFile = 26,
  94. Notice = 27,
  95. Warning = 28,
  96. Row = 100,
  97. Done = 101
  98. }
  99. public enum ExtendedResult : int
  100. {
  101. IOErrorRead = (Result.IOError | (1 << 8)),
  102. IOErrorShortRead = (Result.IOError | (2 << 8)),
  103. IOErrorWrite = (Result.IOError | (3 << 8)),
  104. IOErrorFsync = (Result.IOError | (4 << 8)),
  105. IOErrorDirFSync = (Result.IOError | (5 << 8)),
  106. IOErrorTruncate = (Result.IOError | (6 << 8)),
  107. IOErrorFStat = (Result.IOError | (7 << 8)),
  108. IOErrorUnlock = (Result.IOError | (8 << 8)),
  109. IOErrorRdlock = (Result.IOError | (9 << 8)),
  110. IOErrorDelete = (Result.IOError | (10 << 8)),
  111. IOErrorBlocked = (Result.IOError | (11 << 8)),
  112. IOErrorNoMem = (Result.IOError | (12 << 8)),
  113. IOErrorAccess = (Result.IOError | (13 << 8)),
  114. IOErrorCheckReservedLock = (Result.IOError | (14 << 8)),
  115. IOErrorLock = (Result.IOError | (15 << 8)),
  116. IOErrorClose = (Result.IOError | (16 << 8)),
  117. IOErrorDirClose = (Result.IOError | (17 << 8)),
  118. IOErrorSHMOpen = (Result.IOError | (18 << 8)),
  119. IOErrorSHMSize = (Result.IOError | (19 << 8)),
  120. IOErrorSHMLock = (Result.IOError | (20 << 8)),
  121. IOErrorSHMMap = (Result.IOError | (21 << 8)),
  122. IOErrorSeek = (Result.IOError | (22 << 8)),
  123. IOErrorDeleteNoEnt = (Result.IOError | (23 << 8)),
  124. IOErrorMMap = (Result.IOError | (24 << 8)),
  125. LockedSharedcache = (Result.Locked | (1 << 8)),
  126. BusyRecovery = (Result.Busy | (1 << 8)),
  127. CannottOpenNoTempDir = (Result.CannotOpen | (1 << 8)),
  128. CannotOpenIsDir = (Result.CannotOpen | (2 << 8)),
  129. CannotOpenFullPath = (Result.CannotOpen | (3 << 8)),
  130. CorruptVTab = (Result.Corrupt | (1 << 8)),
  131. ReadonlyRecovery = (Result.ReadOnly | (1 << 8)),
  132. ReadonlyCannotLock = (Result.ReadOnly | (2 << 8)),
  133. ReadonlyRollback = (Result.ReadOnly | (3 << 8)),
  134. AbortRollback = (Result.Abort | (2 << 8)),
  135. ConstraintCheck = (Result.Constraint | (1 << 8)),
  136. ConstraintCommitHook = (Result.Constraint | (2 << 8)),
  137. ConstraintForeignKey = (Result.Constraint | (3 << 8)),
  138. ConstraintFunction = (Result.Constraint | (4 << 8)),
  139. ConstraintNotNull = (Result.Constraint | (5 << 8)),
  140. ConstraintPrimaryKey = (Result.Constraint | (6 << 8)),
  141. ConstraintTrigger = (Result.Constraint | (7 << 8)),
  142. ConstraintUnique = (Result.Constraint | (8 << 8)),
  143. ConstraintVTab = (Result.Constraint | (9 << 8)),
  144. NoticeRecoverWAL = (Result.Notice | (1 << 8)),
  145. NoticeRecoverRollback = (Result.Notice | (2 << 8))
  146. }
  147. public enum ConfigOption : int
  148. {
  149. SingleThread = 1,
  150. MultiThread = 2,
  151. Serialized = 3
  152. }
  153. //const string LibraryPath = "libsqlite3.so.0";
  154. const string LibraryPath = "e_sqlite3.dll";
  155. #if !USE_CSHARP_SQLITE && !USE_WP8_NATIVE_SQLITE && !USE_SQLITEPCL_RAW
  156. public static int Threadsafe() => nativeLoader.LoadFunction<ThreadsafeDelegate>("sqlite3_threadsafe").Invoke();
  157. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  158. delegate int ThreadsafeDelegate();
  159. public static Result Open(string filename, out IntPtr db) => nativeLoader.LoadFunction<OpenDelegate>("sqlite3_open").Invoke(filename, out db);
  160. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  161. delegate Result OpenDelegate([MarshalAs(UnmanagedType.LPStr)] string filename, out IntPtr db);
  162. public static Result Open(string filename, out IntPtr db, int flags, string zvfs) => nativeLoader.LoadFunction<OpenV2Delegate>("sqlite3_open_v2").Invoke(filename, out db, flags, zvfs);
  163. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  164. delegate Result OpenV2Delegate([MarshalAs(UnmanagedType.LPStr)] string filename, out IntPtr db, int flags, [MarshalAs(UnmanagedType.LPStr)] string zvfs);
  165. public static Result Open(byte[] filename, out IntPtr db, int flags, string zvfs) => nativeLoader.LoadFunction<OpenV2BytesDelegate>("sqlite3_open_v2").Invoke(filename, out db, flags, zvfs);
  166. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  167. delegate Result OpenV2BytesDelegate(byte[] filename, out IntPtr db, int flags, [MarshalAs(UnmanagedType.LPStr)] string zvfs);
  168. public static Result Open16(string filename, out IntPtr db) => nativeLoader.LoadFunction<Open16Delegate>("sqlite3_open16").Invoke(filename, out db);
  169. [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
  170. delegate Result Open16Delegate([MarshalAs(UnmanagedType.LPWStr)] string filename, out IntPtr db);
  171. public static Result EnableLoadExtension(IntPtr db, int onoff) => nativeLoader.LoadFunction<EnableLoadExtensionDelegate>("sqlite3_enable_load_extension").Invoke(db, onoff);
  172. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  173. delegate Result EnableLoadExtensionDelegate(IntPtr db, int onoff);
  174. public static Result Close(IntPtr db) => nativeLoader.LoadFunction<CloseDelegate>("sqlite3_close").Invoke(db);
  175. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  176. delegate Result CloseDelegate(IntPtr db);
  177. public static Result Close2(IntPtr db) => nativeLoader.LoadFunction<Close2Delegate>("sqlite3_close_v2").Invoke(db);
  178. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  179. delegate Result Close2Delegate(IntPtr db);
  180. public static Result Initialize() => nativeLoader.LoadFunction<InitializeDelegate>("sqlite3_initialize").Invoke();
  181. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  182. delegate Result InitializeDelegate();
  183. public static Result Shutdown() => nativeLoader.LoadFunction<ShutdownDelegate>("sqlite3_shutdown").Invoke();
  184. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  185. delegate Result ShutdownDelegate();
  186. public static Result Config(ConfigOption option) => nativeLoader.LoadFunction<ConfigDelegate>("sqlite3_config").Invoke(option);
  187. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  188. delegate Result ConfigDelegate(ConfigOption option);
  189. public static int SetDirectory(uint directoryType, string directoryPath) => nativeLoader.LoadFunction<SetDirectoryDelegate>("sqlite3_win32_set_directory").Invoke(directoryType, directoryPath);
  190. [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
  191. delegate int SetDirectoryDelegate(uint directoryType, string directoryPath);
  192. public static Result BusyTimeout(IntPtr db, int milliseconds) => nativeLoader.LoadFunction<BusyTimeoutDelegate>("sqlite3_busy_timeout").Invoke(db, milliseconds);
  193. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  194. delegate Result BusyTimeoutDelegate(IntPtr db, int milliseconds);
  195. public static int Changes(IntPtr db) => nativeLoader.LoadFunction<ChangesDelegate>("sqlite3_changes").Invoke(db);
  196. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  197. delegate int ChangesDelegate(IntPtr db);
  198. public static Result Prepare2(IntPtr db, string sql, int numBytes, out IntPtr stmt, IntPtr pzTail) => nativeLoader.LoadFunction<Prepare2Delegate>("sqlite3_prepare_v2").Invoke(db, sql, numBytes, out stmt, pzTail);
  199. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  200. delegate Result Prepare2Delegate(IntPtr db, [MarshalAs(UnmanagedType.LPStr)] string sql, int numBytes, out IntPtr stmt, IntPtr pzTail);
  201. #if NETFX_CORE
  202. public static Result Prepare2(IntPtr db, byte[] queryBytes, int numBytes, out IntPtr stmt, IntPtr pzTail) => nativeLoader.LoadFunction<Prepare2BytesDelegate>("sqlite3_prepare_v2").Invoke(db, queryBytes, numBytes, out stmt, pzTail);
  203. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  204. delegate Result Prepare2BytesDelegate(IntPtr db, byte[] queryBytes, int numBytes, out IntPtr stmt, IntPtr pzTail);
  205. #endif
  206. public static IntPtr Prepare2(IntPtr db, string query)
  207. {
  208. IntPtr stmt;
  209. #if NETFX_CORE
  210. byte[] queryBytes = System.Text.UTF8Encoding.UTF8.GetBytes(query);
  211. var r = Prepare2(db, queryBytes, queryBytes.Length, out stmt, IntPtr.Zero);
  212. #else
  213. var r = Prepare2(db, query, System.Text.UTF8Encoding.UTF8.GetByteCount(query), out stmt, IntPtr.Zero);
  214. #endif
  215. if (r != Result.OK)
  216. {
  217. throw SQLiteException.New(r, GetErrmsg(db));
  218. }
  219. return stmt;
  220. }
  221. public static Result Step(IntPtr stmt) => nativeLoader.LoadFunction<StepDelegate>("sqlite3_step").Invoke(stmt);
  222. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  223. delegate Result StepDelegate(IntPtr stmt);
  224. public static Result Reset(IntPtr stmt) => nativeLoader.LoadFunction<ResetDelegate>("sqlite3_reset").Invoke(stmt);
  225. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  226. delegate Result ResetDelegate(IntPtr stmt);
  227. public static Result Finalize(IntPtr stmt) => nativeLoader.LoadFunction<FinalizeDelegate>("sqlite3_finalize").Invoke(stmt);
  228. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  229. delegate Result FinalizeDelegate(IntPtr stmt);
  230. public static long LastInsertRowid(IntPtr db) => nativeLoader.LoadFunction<LastInsertRowidDelegate>("sqlite3_last_insert_rowid").Invoke(db);
  231. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  232. delegate long LastInsertRowidDelegate(IntPtr db);
  233. public static IntPtr Errmsg(IntPtr db) => nativeLoader.LoadFunction<ErrmsgDelegate>("sqlite3_errmsg16").Invoke(db);
  234. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  235. delegate IntPtr ErrmsgDelegate(IntPtr db);
  236. public static string GetErrmsg(IntPtr db)
  237. {
  238. return Marshal.PtrToStringUni(Errmsg(db));
  239. }
  240. public static int BindParameterIndex(IntPtr stmt, string name) => nativeLoader.LoadFunction<BindParameterIndexDelegate>("sqlite3_bind_parameter_index").Invoke(stmt, name);
  241. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  242. delegate int BindParameterIndexDelegate(IntPtr stmt, [MarshalAs(UnmanagedType.LPStr)] string name);
  243. public static int BindNull(IntPtr stmt, int index) => nativeLoader.LoadFunction<BindNullDelegate>("sqlite3_bind_null").Invoke(stmt, index);
  244. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  245. delegate int BindNullDelegate(IntPtr stmt, int index);
  246. public static int BindInt(IntPtr stmt, int index, int val) => nativeLoader.LoadFunction<BindIntDelegate>("sqlite3_bind_int").Invoke(stmt, index, val);
  247. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  248. delegate int BindIntDelegate(IntPtr stmt, int index, int val);
  249. public static int BindInt64(IntPtr stmt, int index, long val) => nativeLoader.LoadFunction<BindInt64Delegate>("sqlite3_bind_int64").Invoke(stmt, index, val);
  250. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  251. delegate int BindInt64Delegate(IntPtr stmt, int index, long val);
  252. public static int BindDouble(IntPtr stmt, int index, double val) => nativeLoader.LoadFunction<BindDoubleDelegate>("sqlite3_bind_double").Invoke(stmt, index, val);
  253. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  254. delegate int BindDoubleDelegate(IntPtr stmt, int index, double val);
  255. public static int BindText(IntPtr stmt, int index, string val, int n, IntPtr free) => nativeLoader.LoadFunction<BindTextDelegate>("sqlite3_bind_text16").Invoke(stmt, index, val, n, free);
  256. [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
  257. delegate int BindTextDelegate(IntPtr stmt, int index, [MarshalAs(UnmanagedType.LPWStr)] string val, int n, IntPtr free);
  258. public static int BindBlob(IntPtr stmt, int index, byte[] val, int n, IntPtr free) => nativeLoader.LoadFunction<BindBlobDelegate>("sqlite3_bind_blob").Invoke(stmt, index, val, n, free);
  259. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  260. delegate int BindBlobDelegate(IntPtr stmt, int index, byte[] val, int n, IntPtr free);
  261. public static int ColumnCount(IntPtr stmt) => nativeLoader.LoadFunction<ColumnCountDelegate>("sqlite3_column_count").Invoke(stmt);
  262. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  263. delegate int ColumnCountDelegate(IntPtr stmt);
  264. public static IntPtr ColumnName(IntPtr stmt, int index) => nativeLoader.LoadFunction<ColumnNameDelegate>("sqlite3_column_name").Invoke(stmt, index);
  265. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  266. delegate IntPtr ColumnNameDelegate(IntPtr stmt, int index);
  267. static IntPtr ColumnName16Internal(IntPtr stmt, int index) => nativeLoader.LoadFunction<ColumnName16Delegate>("sqlite3_column_name16").Invoke(stmt, index);
  268. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  269. delegate IntPtr ColumnName16Delegate(IntPtr stmt, int index);
  270. public static string ColumnName16(IntPtr stmt, int index)
  271. {
  272. return Marshal.PtrToStringUni(ColumnName16Internal(stmt, index));
  273. }
  274. public static ColType ColumnType(IntPtr stmt, int index) => nativeLoader.LoadFunction<ColumnTypeDelegate>("sqlite3_column_type").Invoke(stmt, index);
  275. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  276. delegate ColType ColumnTypeDelegate(IntPtr stmt, int index);
  277. public static int ColumnInt(IntPtr stmt, int index) => nativeLoader.LoadFunction<ColumnIntDelegate>("sqlite3_column_int").Invoke(stmt, index);
  278. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  279. delegate int ColumnIntDelegate(IntPtr stmt, int index);
  280. public static long ColumnInt64(IntPtr stmt, int index) => nativeLoader.LoadFunction<ColumnInt64Delegate>("sqlite3_column_int64").Invoke(stmt, index);
  281. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  282. delegate long ColumnInt64Delegate(IntPtr stmt, int index);
  283. public static double ColumnDouble(IntPtr stmt, int index) => nativeLoader.LoadFunction<ColumnDoubleDelegate>("sqlite3_column_double").Invoke(stmt, index);
  284. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  285. delegate double ColumnDoubleDelegate(IntPtr stmt, int index);
  286. public static IntPtr ColumnText(IntPtr stmt, int index) => nativeLoader.LoadFunction<ColumnTextDelegate>("sqlite3_column_text").Invoke(stmt, index);
  287. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  288. delegate IntPtr ColumnTextDelegate(IntPtr stmt, int index);
  289. public static IntPtr ColumnText16(IntPtr stmt, int index) => nativeLoader.LoadFunction<ColumnText16Delegate>("sqlite3_column_text16").Invoke(stmt, index);
  290. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  291. delegate IntPtr ColumnText16Delegate(IntPtr stmt, int index);
  292. public static IntPtr ColumnBlob(IntPtr stmt, int index) => nativeLoader.LoadFunction<ColumnBlobDelegate>("sqlite3_column_blob").Invoke(stmt, index);
  293. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  294. delegate IntPtr ColumnBlobDelegate(IntPtr stmt, int index);
  295. public static int ColumnBytes(IntPtr stmt, int index) => nativeLoader.LoadFunction<ColumnBytesDelegate>("sqlite3_column_bytes").Invoke(stmt, index);
  296. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  297. delegate int ColumnBytesDelegate(IntPtr stmt, int index);
  298. public static string ColumnString(IntPtr stmt, int index)
  299. {
  300. return Marshal.PtrToStringUni(SQLite3.ColumnText16(stmt, index));
  301. }
  302. public static byte[] ColumnByteArray(IntPtr stmt, int index)
  303. {
  304. int length = ColumnBytes(stmt, index);
  305. var result = new byte[length];
  306. if (length > 0)
  307. Marshal.Copy(ColumnBlob(stmt, index), result, 0, length);
  308. return result;
  309. }
  310. public static Result GetResult(Sqlite3DatabaseHandle db) => nativeLoader.LoadFunction<GetResultDelegate>("sqlite3_errcode").Invoke(db);
  311. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  312. delegate Result GetResultDelegate(Sqlite3DatabaseHandle db);
  313. public static ExtendedResult ExtendedErrCode(IntPtr db) => nativeLoader.LoadFunction<ExtendedErrCodeDelegate>("sqlite3_extended_errcode").Invoke(db);
  314. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  315. delegate ExtendedResult ExtendedErrCodeDelegate(IntPtr db);
  316. public static int LibVersionNumber() => nativeLoader.LoadFunction<LibVersionNumberDelegate>("sqlite3_libversion_number").Invoke();
  317. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  318. delegate int LibVersionNumberDelegate();
  319. public static Sqlite3BackupHandle BackupInit(Sqlite3DatabaseHandle destDb, string destName, Sqlite3DatabaseHandle sourceDb, string sourceName) => nativeLoader.LoadFunction<BackupInitDelegate>("sqlite3_backup_init").Invoke(destDb, destName, sourceDb, sourceName);
  320. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  321. delegate Sqlite3BackupHandle BackupInitDelegate(Sqlite3DatabaseHandle destDb, [MarshalAs(UnmanagedType.LPStr)] string destName, Sqlite3DatabaseHandle sourceDb, [MarshalAs(UnmanagedType.LPStr)] string sourceName);
  322. public static Result BackupStep(Sqlite3BackupHandle backup, int numPages) => nativeLoader.LoadFunction<BackupStepDelegate>("sqlite3_backup_step").Invoke(backup, numPages);
  323. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  324. delegate Result BackupStepDelegate(Sqlite3BackupHandle backup, int numPages);
  325. public static Result BackupFinish(Sqlite3BackupHandle backup) => nativeLoader.LoadFunction<BackupFinishDelegate>("sqlite3_backup_finish").Invoke(backup);
  326. [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  327. delegate Result BackupFinishDelegate(Sqlite3BackupHandle backup);
  328. #else
  329. public static Result Open (string filename, out Sqlite3DatabaseHandle db)
  330. {
  331. return (Result)Sqlite3.sqlite3_open (filename, out db);
  332. }
  333. public static Result Open (string filename, out Sqlite3DatabaseHandle db, int flags, string vfsName)
  334. {
  335. #if USE_WP8_NATIVE_SQLITE
  336. return (Result)Sqlite3.sqlite3_open_v2(filename, out db, flags, vfsName ?? "");
  337. #else
  338. return (Result)Sqlite3.sqlite3_open_v2 (filename, out db, flags, vfsName);
  339. #endif
  340. }
  341. public static Result Close (Sqlite3DatabaseHandle db)
  342. {
  343. return (Result)Sqlite3.sqlite3_close (db);
  344. }
  345. public static Result Close2 (Sqlite3DatabaseHandle db)
  346. {
  347. return (Result)Sqlite3.sqlite3_close_v2 (db);
  348. }
  349. public static Result BusyTimeout (Sqlite3DatabaseHandle db, int milliseconds)
  350. {
  351. return (Result)Sqlite3.sqlite3_busy_timeout (db, milliseconds);
  352. }
  353. public static int Changes (Sqlite3DatabaseHandle db)
  354. {
  355. return Sqlite3.sqlite3_changes (db);
  356. }
  357. public static Sqlite3Statement Prepare2 (Sqlite3DatabaseHandle db, string query)
  358. {
  359. Sqlite3Statement stmt = default (Sqlite3Statement);
  360. #if USE_WP8_NATIVE_SQLITE || USE_SQLITEPCL_RAW
  361. var r = Sqlite3.sqlite3_prepare_v2 (db, query, out stmt);
  362. #else
  363. stmt = new Sqlite3Statement();
  364. var r = Sqlite3.sqlite3_prepare_v2(db, query, -1, ref stmt, 0);
  365. #endif
  366. if (r != 0) {
  367. throw SQLiteException.New ((Result)r, GetErrmsg (db));
  368. }
  369. return stmt;
  370. }
  371. public static Result Step (Sqlite3Statement stmt)
  372. {
  373. return (Result)Sqlite3.sqlite3_step (stmt);
  374. }
  375. public static Result Reset (Sqlite3Statement stmt)
  376. {
  377. return (Result)Sqlite3.sqlite3_reset (stmt);
  378. }
  379. public static Result Finalize (Sqlite3Statement stmt)
  380. {
  381. return (Result)Sqlite3.sqlite3_finalize (stmt);
  382. }
  383. public static long LastInsertRowid (Sqlite3DatabaseHandle db)
  384. {
  385. return Sqlite3.sqlite3_last_insert_rowid (db);
  386. }
  387. public static string GetErrmsg (Sqlite3DatabaseHandle db)
  388. {
  389. return Sqlite3.sqlite3_errmsg (db).utf8_to_string ();
  390. }
  391. public static int BindParameterIndex (Sqlite3Statement stmt, string name)
  392. {
  393. return Sqlite3.sqlite3_bind_parameter_index (stmt, name);
  394. }
  395. public static int BindNull (Sqlite3Statement stmt, int index)
  396. {
  397. return Sqlite3.sqlite3_bind_null (stmt, index);
  398. }
  399. public static int BindInt (Sqlite3Statement stmt, int index, int val)
  400. {
  401. return Sqlite3.sqlite3_bind_int (stmt, index, val);
  402. }
  403. public static int BindInt64 (Sqlite3Statement stmt, int index, long val)
  404. {
  405. return Sqlite3.sqlite3_bind_int64 (stmt, index, val);
  406. }
  407. public static int BindDouble (Sqlite3Statement stmt, int index, double val)
  408. {
  409. return Sqlite3.sqlite3_bind_double (stmt, index, val);
  410. }
  411. public static int BindText (Sqlite3Statement stmt, int index, string val, int n, IntPtr free)
  412. {
  413. #if USE_WP8_NATIVE_SQLITE
  414. return Sqlite3.sqlite3_bind_text(stmt, index, val, n);
  415. #elif USE_SQLITEPCL_RAW
  416. return Sqlite3.sqlite3_bind_text (stmt, index, val);
  417. #else
  418. return Sqlite3.sqlite3_bind_text(stmt, index, val, n, null);
  419. #endif
  420. }
  421. public static int BindBlob (Sqlite3Statement stmt, int index, byte[] val, int n, IntPtr free)
  422. {
  423. #if USE_WP8_NATIVE_SQLITE
  424. return Sqlite3.sqlite3_bind_blob(stmt, index, val, n);
  425. #elif USE_SQLITEPCL_RAW
  426. return Sqlite3.sqlite3_bind_blob (stmt, index, val);
  427. #else
  428. return Sqlite3.sqlite3_bind_blob(stmt, index, val, n, null);
  429. #endif
  430. }
  431. public static int ColumnCount (Sqlite3Statement stmt)
  432. {
  433. return Sqlite3.sqlite3_column_count (stmt);
  434. }
  435. public static string ColumnName (Sqlite3Statement stmt, int index)
  436. {
  437. return Sqlite3.sqlite3_column_name (stmt, index).utf8_to_string ();
  438. }
  439. public static string ColumnName16 (Sqlite3Statement stmt, int index)
  440. {
  441. return Sqlite3.sqlite3_column_name (stmt, index).utf8_to_string ();
  442. }
  443. public static ColType ColumnType (Sqlite3Statement stmt, int index)
  444. {
  445. return (ColType)Sqlite3.sqlite3_column_type (stmt, index);
  446. }
  447. public static int ColumnInt (Sqlite3Statement stmt, int index)
  448. {
  449. return Sqlite3.sqlite3_column_int (stmt, index);
  450. }
  451. public static long ColumnInt64 (Sqlite3Statement stmt, int index)
  452. {
  453. return Sqlite3.sqlite3_column_int64 (stmt, index);
  454. }
  455. public static double ColumnDouble (Sqlite3Statement stmt, int index)
  456. {
  457. return Sqlite3.sqlite3_column_double (stmt, index);
  458. }
  459. public static string ColumnText (Sqlite3Statement stmt, int index)
  460. {
  461. return Sqlite3.sqlite3_column_text (stmt, index).utf8_to_string ();
  462. }
  463. public static string ColumnText16 (Sqlite3Statement stmt, int index)
  464. {
  465. return Sqlite3.sqlite3_column_text (stmt, index).utf8_to_string ();
  466. }
  467. public static byte[] ColumnBlob (Sqlite3Statement stmt, int index)
  468. {
  469. return Sqlite3.sqlite3_column_blob (stmt, index).ToArray ();
  470. }
  471. public static int ColumnBytes (Sqlite3Statement stmt, int index)
  472. {
  473. return Sqlite3.sqlite3_column_bytes (stmt, index);
  474. }
  475. public static string ColumnString (Sqlite3Statement stmt, int index)
  476. {
  477. return Sqlite3.sqlite3_column_text (stmt, index).utf8_to_string ();
  478. }
  479. public static byte[] ColumnByteArray (Sqlite3Statement stmt, int index)
  480. {
  481. int length = ColumnBytes (stmt, index);
  482. if (length > 0) {
  483. return ColumnBlob (stmt, index);
  484. }
  485. return new byte[0];
  486. }
  487. public static Result EnableLoadExtension (Sqlite3DatabaseHandle db, int onoff)
  488. {
  489. return (Result)Sqlite3.sqlite3_enable_load_extension (db, onoff);
  490. }
  491. public static int LibVersionNumber ()
  492. {
  493. return Sqlite3.sqlite3_libversion_number ();
  494. }
  495. public static Result GetResult (Sqlite3DatabaseHandle db)
  496. {
  497. return (Result)Sqlite3.sqlite3_errcode (db);
  498. }
  499. public static ExtendedResult ExtendedErrCode (Sqlite3DatabaseHandle db)
  500. {
  501. return (ExtendedResult)Sqlite3.sqlite3_extended_errcode (db);
  502. }
  503. public static Sqlite3BackupHandle BackupInit (Sqlite3DatabaseHandle destDb, string destName, Sqlite3DatabaseHandle sourceDb, string sourceName)
  504. {
  505. return Sqlite3.sqlite3_backup_init (destDb, destName, sourceDb, sourceName);
  506. }
  507. public static Result BackupStep (Sqlite3BackupHandle backup, int numPages)
  508. {
  509. return (Result)Sqlite3.sqlite3_backup_step (backup, numPages);
  510. }
  511. public static Result BackupFinish (Sqlite3BackupHandle backup)
  512. {
  513. return (Result)Sqlite3.sqlite3_backup_finish (backup);
  514. }
  515. #endif
  516. public enum ColType : int
  517. {
  518. Integer = 1,
  519. Float = 2,
  520. Text = 3,
  521. Blob = 4,
  522. Null = 5
  523. }
  524. }
  525. }