/// <summary> /// Finds column by name in results. /// Returns 0-based index, or -1 if not found. /// </summary> /// <param name="name">Column name in results, as returned by sqlite3_column_name. Case-sensitive.</param> public int ColumnIndex(string name) { int n = ColumnCount; if (n > 0 && !name.NE()) { if (AStringUtil.IsAscii(name)) { for (int i = 0; i < n; i++) { byte *b = SLApi.sqlite3_column_name(_st, i); if (BytePtr_.AsciiEq(b, name)) { return(i); } } } else { var bname = AConvert.ToUtf8(name); for (int i = 0; i < n; i++) { byte *b = SLApi.sqlite3_column_name(_st, i); if (BytePtr_.Eq(b, bname)) { return(i); } } } } return(-1); }
int _B(SLIndexOrName p) { if (p.name == null) { return(p.index); } int r = SLApi.sqlite3_bind_parameter_index(_st, AConvert.ToUtf8(p.name)); if (r == 0) { throw new SLException($"Parameter '{p.name}' does not exist in the SQL statement."); } return(r); }
/// <summary> /// Opens or creates a database file. /// </summary> /// <param name="file"> /// Database file. Can be: /// - Full path. Supports environment variables etc, see <see cref="APath.ExpandEnvVar"/> /// - ":memory:" - create a private, temporary in-memory database. /// - "" - create a private, temporary on-disk database. /// - Starts with "file:" - see sqlite3_open_v2 documentation in SQLite website. /// </param> /// <param name="flags">sqlite3_open_v2 flags, documanted in SQLite website. Default: read-write, create file if does not exist (and parent directory).</param> /// <param name="sql"> /// SQL to execute. For example, one or more ;-separated PRAGMA statements to configure the database connection. Or even "CREATE TABLE IF NOT EXISTS ...". /// This function also always executes "PRAGMA foreign_keys=ON;PRAGMA secure_delete=ON;". /// </param> /// <exception cref="ArgumentException">Not full path.</exception> /// <exception cref="SLException">Failed to open database or execute sql.</exception> /// <remarks> /// Calls sqlite3_open_v2. /// <note>If a variable of this class is used by multiple threads, use <c>lock(variable) { }</c> where need.</note> /// </remarks> public ASqlite(string file, SLFlags flags = SLFlags.ReadWriteCreate, string sql = null) { bool isSpec = file != null && (file.Length == 0 || file == ":memory:" || file.Starts("file:")); if (!isSpec) { file = APath.Normalize(file); if (flags.Has(SLFlags.SQLITE_OPEN_CREATE) && !AFile.ExistsAsFile(file, true)) { AFile.CreateDirectoryFor(file); } } var r = SLApi.sqlite3_open_v2(AConvert.ToUtf8(file), ref _db, flags, null); if (r != 0) { Dispose(); throw new SLException(r, "sqlite3_open " + file); } Execute("PRAGMA foreign_keys=ON;PRAGMA secure_delete=ON;" + sql); }
/// <summary> /// Returns <c>sqlite3_column_text(column)</c> as string. /// </summary> public string GetText(SLIndexOrName column) { int icol = _C(column); if (_db.IsUtf16) //both these codes would work, but with long strings can be significantly slower if SQLite has to convert text encoding { char *t = SLApi.sqlite3_column_text16(_st, icol); if (t != null) { return(new string(t, 0, SLApi.sqlite3_column_bytes16(_st, icol))); } } else { byte *t = SLApi.sqlite3_column_text(_st, icol); if (t != null) { return(AConvert.FromUtf8(t, SLApi.sqlite3_column_bytes(_st, icol))); } } _WarnGet(); return(null); }
/// <summary> /// sqlite3_column_name. /// </summary> public string ColumnName(int index) => AConvert.FromUtf8(SLApi.sqlite3_column_name(_st, index));
/// <summary> /// Calls sqlite3_exec to execute one or more SQL statements that don't return data. /// </summary> /// <param name="sql">SQL statement, or several ;-separated statements.</param> /// <exception cref="SLException">Failed to execute sql.</exception> public void Execute(string sql) { var b = AConvert.ToUtf8(sql); byte *es = null; //gets better error text than sqlite3_errstr; sqlite3_errmsg gets nothing after sqlite3_exec. var r = SLApi.sqlite3_exec(_db, b, default, default, &es);
/// <summary> /// Loads image and returns its data in .bmp file format. /// Returns null if fails, for example file not found or invalid Base64 string. /// </summary> /// <param name="s">Depends on t. File path or resource name without prefix or Base64 image data without prefix.</param> /// <param name="t">Image type and string format.</param> /// <param name="searchPath">Use <see cref="AFile.SearchPath"/></param> /// <remarks>Supports environment variables etc. If not full path, searches in <see cref="AFolders.ThisAppImages"/>.</remarks> public static byte[] BmpFileDataFromString(string s, ImageType t, bool searchPath = false) { //AOutput.Write(t, s); try { switch (t) { case ImageType.Bmp: case ImageType.PngGifJpg: case ImageType.Cur: if (searchPath) { s = AFile.SearchPath(s, AFolders.ThisAppImages); if (s == null) { return(null); } } else { if (!APath.IsFullPathExpandEnvVar(ref s)) { return(null); } s = APath.Normalize(s, AFolders.ThisAppImages); if (!AFile.ExistsAsFile(s)) { return(null); } } break; } switch (t) { case ImageType.Base64CompressedBmp: return(AConvert.Decompress(Convert.FromBase64String(s))); case ImageType.Base64PngGifJpg: using (var stream = new MemoryStream(Convert.FromBase64String(s), false)) { return(_ImageToBytes(Image.FromStream(stream))); } case ImageType.Resource: return(_ImageToBytes(AResources.GetAppResource(s) as Image)); case ImageType.Bmp: return(File.ReadAllBytes(s)); case ImageType.PngGifJpg: return(_ImageToBytes(Image.FromFile(s))); case ImageType.Ico: case ImageType.IconLib: case ImageType.ShellIcon: case ImageType.Cur: return(_IconToBytes(s, t == ImageType.Cur, searchPath)); } } catch (Exception ex) { ADebug.Print(ex.Message + " " + s); } return(null); }
/// <summary> /// Gets image type from string. /// </summary> /// <param name="anyFile">When the string is valid but not of any image type, return ShellIcon instead of None.</param> /// <param name="s">File path etc. See <see cref="ImageType"/>.</param> public static ImageType ImageTypeFromString(bool anyFile, string s) { var b = AConvert.ToUtf8(s); fixed(byte *p = b) return(ImageTypeFromString(true, p, b.Length - 1)); }