/// <summary> /// Returns <c>sqlite3_column_int64(column)</c>. /// </summary> /// <remarks> /// Use this function to get integer values of size 8 bytes: long, ulong, 64-bit enum, maybe DateTime. /// </remarks> public long GetLong(SLIndexOrName column) { long r = SLApi.sqlite3_column_int64(_st, _C(column)); if (r == 0) { _WarnGet(); } return(r); }
/// <summary> /// Returns <c>sqlite3_column_int(column)</c>. /// </summary> /// <remarks> /// Use this function to get integer values of size 4, 2 or 1 bytes: int, uint, short, ushort, byte, sbyte, enum. /// </remarks> public int GetInt(SLIndexOrName column) { int r = SLApi.sqlite3_column_int(_st, _C(column)); if (r == 0) { _WarnGet(); } return(r); }
///// <summary> ///// Returns <c>DateTime.FromBinary(sqlite3_column_int64(column))</c>. ///// </summary> ///// <param name="column"></param> ///// <param name="convertToLocal">If the value in database is stored as UTC, convert to local.</param> ///// <exception cref="ArgumentException">The value in database is not in the valid DateTime range.</exception> ///// <seealso cref="Bind(int, DateTime, bool)"/> //public DateTime GetDateTime(SLIndexOrName column, bool convertToLocal = false) //{ // var r = DateTime.FromBinary(GetLong(column)); //info: it's OK if 0/null // if(convertToLocal && r.Kind == DateTimeKind.Utc) r = r.ToLocalTime(); // return r; //} /// <summary> /// Returns <c>sqlite3_column_double(column)</c>. /// </summary> public double GetDouble(SLIndexOrName column) { double r = SLApi.sqlite3_column_double(_st, _C(column)); if (r == 0) { _WarnGet(); } return(r); }
/// <summary> /// Returns <c>sqlite3_column_blob(column)</c> as a variable of any value type that does not have fields of reference types. /// </summary> public T GetStruct <T>(SLIndexOrName column) where T : unmanaged { var t = (T *)GetBlob(column, out int nb); T r = default; if (t != null && nb == sizeof(T)) { Buffer.MemoryCopy(t, &r, nb, nb); } return(r); }
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); }
///// DateTime - calls sqlite3_bind_int64(value.ToBinary()). #endregion #region get int _C(SLIndexOrName p) { if (p.name == null) { return(p.index); } int r = ColumnIndex(p.name); if (r < 0) { throw new SLException($"Column '{p.name}' does not exist in query results."); } return(r); }
/// <summary> /// Returns <c>sqlite3_column_blob(column)</c> and gets blob size. /// </summary> /// <param name="column"></param> /// <param name="nBytes">Blob size.</param> public void *GetBlob(SLIndexOrName column, out int nBytes) { int icol = _C(column); void *r = SLApi.sqlite3_column_blob(_st, icol); if (r == null) { nBytes = 0; _WarnGet(); } else { nBytes = SLApi.sqlite3_column_bytes(_st, icol); } return(r); }
/// <summary> /// Returns <c>sqlite3_column_blob(column)</c> as List. /// </summary> public List <T> GetList <T>(SLIndexOrName column) where T : unmanaged { var t = (T *)GetBlob(column, out int nb); if (t == null) { return(null); } int ne = nb / sizeof(T); var r = new List <T>(ne); for (int i = 0; i < ne; i++) { r.Add(t[i]); } return(r); }
/// <summary> /// Returns <c>sqlite3_column_blob(column)</c> as array. /// </summary> public T[] GetArray <T>(SLIndexOrName column) where T : unmanaged { var t = GetBlob(column, out int nb); if (t == null) { return(null); } if (nb == 0) { return(Array.Empty <T>()); } int size = sizeof(T); int ne = nb / size; nb = ne * size; var r = new T[ne]; fixed(T *p = r) Buffer.MemoryCopy(t, p, nb, nb); return(r); }
/// <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>Calls sqlite3_bind_int64. Returns self.</summary> /// <exception cref="SLException">Failed.</exception> public ASqliteStatement Bind(SLIndexOrName sqlParam, long value) => _Err(SLApi.sqlite3_bind_int64(_st, _B(sqlParam), value), "sqlite3_bind_int64");
/// <summary> /// Returns <c>sqlite3_column_int64(column) != 0</c>. /// </summary> public bool GetBool(SLIndexOrName column) => GetLong(column) != 0;
/// <summary>Calls sqlite3_bind_int64. Returns self.</summary> /// <exception cref="SLException">Failed.</exception> public ASqliteStatement Bind(SLIndexOrName sqlParam, ulong value) => Bind(sqlParam, (long)value);
/// <summary>Calls sqlite3_bind_double. Returns self.</summary> /// <exception cref="SLException">Failed.</exception> public ASqliteStatement Bind(SLIndexOrName sqlParam, double value) => _Err(SLApi.sqlite3_bind_double(_st, _B(sqlParam), value), "sqlite3_bind_double");
/// <summary>Calls sqlite3_bind_null. Returns self.</summary> /// <exception cref="SLException">Failed.</exception> /// <remarks>Usually don't need to call this function. Unset parameter values are null. The Bind(string/void*/Array/List) functions set null too if the value is null.</remarks> public ASqliteStatement BindNull(SLIndexOrName sqlParam) => _Err(SLApi.sqlite3_bind_null(_st, _B(sqlParam)), "sqlite3_bind_null");
/// <summary>Calls sqlite3_bind_int. Returns self.</summary> /// <exception cref="SLException">Failed.</exception> public ASqliteStatement Bind(SLIndexOrName sqlParam, uint value) => Bind(sqlParam, (int)value);
/// <summary>Calls sqlite3_bind_blob64. Returns self.</summary> /// <exception cref="SLException">Failed.</exception> public ASqliteStatement Bind <T>(SLIndexOrName sqlParam, List <T> list) where T : unmanaged => Bind(sqlParam, list?.ToArray());
/// <summary>Calls sqlite3_bind_blob64. Returns self.</summary> /// <exception cref="SLException">Failed.</exception> public ASqliteStatement Bind <T>(SLIndexOrName sqlParam, T[] array) where T : unmanaged { fixed(T *p = array) return(Bind(sqlParam, p, (array?.LongLength ?? 0) * sizeof(T))); }
/// <summary>Calls sqlite3_bind_blob64. Returns self.</summary> /// <exception cref="SLException">Failed.</exception> public ASqliteStatement Bind(SLIndexOrName sqlParam, void *blob, long nBytes) => _Err(SLApi.sqlite3_bind_blob64(_st, _B(sqlParam), blob, nBytes), "sqlite3_bind_blob64");
/// <summary>Calls sqlite3_bind_text16. Returns self.</summary> /// <exception cref="SLException">Failed.</exception> public ASqliteStatement Bind(SLIndexOrName sqlParam, string value) => _Err(SLApi.sqlite3_bind_text16(_st, _B(sqlParam), value, (value?.Length ?? 0) * 2), "sqlite3_bind_text16");
/// <summary>Calls sqlite3_bind_int(value ? 1 : 0). Returns self.</summary> /// <exception cref="SLException">Failed.</exception> public ASqliteStatement Bind(SLIndexOrName sqlParam, bool value) => Bind(sqlParam, value ? 1 : 0);
/// <summary>Binds a value as blob. Calls sqlite3_bind_blob64. Returns self.</summary> /// <exception cref="SLException">Failed.</exception> /// <remarks>Can be any value type that does not contain fields of reference types. Examples: Guid, Point, int, decimal.</remarks> public ASqliteStatement BindStruct <T>(SLIndexOrName sqlParam, T value) where T : unmanaged => Bind(sqlParam, &value, sizeof(T));
[MethodImpl(MethodImplOptions.NoInlining)] //ensure that value is copied to the parameter, because must not be smaller than int public ASqliteStatement Bind <T>(SLIndexOrName sqlParam, T value) where T : unmanaged, Enum => Bind(sqlParam, sizeof(T) == 8 ? *(long *)&value : *(int *)&value);