From 49a42b192d445222d71567f9b9ac9e9e9e10d786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D1=96=D0=B9=20=D0=A7=D0=B5=D0=B1?= =?UTF-8?q?=D1=83=D0=BA=D1=96=D0=BD?= Date: Mon, 14 Aug 2017 10:14:21 +0300 Subject: [PATCH] Added Uri, UriBuilder and StringBuilder support --- src/SQLite.cs | 84 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 31 deletions(-) diff --git a/src/SQLite.cs b/src/SQLite.cs index 2ec5129d..c2340cbe 100644 --- a/src/SQLite.cs +++ b/src/SQLite.cs @@ -1,16 +1,16 @@ // // Copyright (c) 2009-2017 Krueger Systems, Inc. -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -33,6 +33,7 @@ using System.Reflection; using System.Linq; using System.Linq.Expressions; +using System.Text; using System.Threading; #if USE_CSHARP_SQLITE @@ -384,12 +385,12 @@ static byte[] GetNullTerminatedUtf8 (string s) /// /// /// The type whose mapping to the database is returned. - /// + /// /// /// Optional flags allowing implicit PK and indexes based on naming conventions - /// + /// /// - /// The mapping represents the schema of the columns of the database and contains + /// The mapping represents the schema of the columns of the database and contains /// methods to set and get properties of objects. /// public TableMapping GetMapping (Type type, CreateFlags createFlags = CreateFlags.None) @@ -416,9 +417,9 @@ public TableMapping GetMapping (Type type, CreateFlags createFlags = CreateFlags /// /// /// Optional flags allowing implicit PK and indexes based on naming conventions - /// + /// /// - /// The mapping represents the schema of the columns of the database and contains + /// The mapping represents the schema of the columns of the database and contains /// methods to set and get properties of objects. /// public TableMapping GetMapping (CreateFlags createFlags = CreateFlags.None) @@ -481,7 +482,7 @@ public CreateTableResult CreateTable (CreateFlags createFlags = CreateFlags.N /// later access this schema by calling GetMapping. /// /// Type to reflect to a database table. - /// Optional flags allowing implicit PK and indexes based on naming conventions. + /// Optional flags allowing implicit PK and indexes based on naming conventions. /// /// Whether the table was created or migrated. /// @@ -1047,7 +1048,7 @@ public object Get (object pk, TableMapping map) /// /// Attempts to retrieve the first object that matches the predicate from the table - /// associated with the specified type. + /// associated with the specified type. /// /// /// A predicate for which object to find. @@ -1101,7 +1102,7 @@ public object Find (object pk, TableMapping map) /// /// Attempts to retrieve the first object that matches the predicate from the table - /// associated with the specified type. + /// associated with the specified type. /// /// /// A predicate for which object to find. @@ -1117,7 +1118,7 @@ public T Find (Expression> predicate) where T : new() /// /// Attempts to retrieve the first object that matches the query from the table - /// associated with the specified type. + /// associated with the specified type. /// /// /// The fully escaped SQL. @@ -1136,7 +1137,7 @@ public T FindWithQuery (string query, params object[] args) where T : new() /// /// Attempts to retrieve the first object that matches the query from the table - /// associated with the specified type. + /// associated with the specified type. /// /// /// The TableMapping used to identify the table. @@ -1169,9 +1170,9 @@ public object FindWithQuery (TableMapping map, string query, params object[] arg /// Throws if a transaction has already begun. public void BeginTransaction () { - // The BEGIN command only works if the transaction stack is empty, - // or in other words if there are no pending transactions. - // If the transaction stack is not empty when the BEGIN command is invoked, + // The BEGIN command only works if the transaction stack is empty, + // or in other words if there are no pending transactions. + // If the transaction stack is not empty when the BEGIN command is invoked, // then the command fails with an error. // Rather than crash with an error, we will just ignore calls to BeginTransaction // that would result in an error. @@ -1182,7 +1183,7 @@ public void BeginTransaction () catch (Exception ex) { var sqlExp = ex as SQLiteException; if (sqlExp != null) { - // It is recommended that applications respond to the errors listed below + // It is recommended that applications respond to the errors listed below // by explicitly issuing a ROLLBACK command. // TODO: This rollback failsafe should be localized to all throw sites. switch (sqlExp.Result) { @@ -1196,7 +1197,7 @@ public void BeginTransaction () } } else { - // Call decrement and not VolatileWrite in case we've already + // Call decrement and not VolatileWrite in case we've already // created a transaction point in SaveTransactionPoint since the catch. Interlocked.Decrement (ref _transactionDepth); } @@ -1213,7 +1214,7 @@ public void BeginTransaction () /// /// Creates a savepoint in the database at the current point in the transaction timeline. /// Begins a new transaction if one is not in progress. - /// + /// /// Call to undo transactions since the returned savepoint. /// Call to commit transactions after the savepoint returned here. /// Call to end the transaction, committing all changes. @@ -1230,7 +1231,7 @@ public string SaveTransactionPoint () catch (Exception ex) { var sqlExp = ex as SQLiteException; if (sqlExp != null) { - // It is recommended that applications respond to the errors listed below + // It is recommended that applications respond to the errors listed below // by explicitly issuing a ROLLBACK command. // TODO: This rollback failsafe should be localized to all throw sites. switch (sqlExp.Result) { @@ -1277,8 +1278,8 @@ public void RollbackTo (string savepoint) /// true to avoid throwing exceptions, false otherwise void RollbackTo (string savepoint, bool noThrow) { - // Rolling back without a TO clause rolls backs all transactions - // and leaves the transaction stack empty. + // Rolling back without a TO clause rolls backs all transactions + // and leaves the transaction stack empty. try { if (String.IsNullOrEmpty (savepoint)) { if (Interlocked.Exchange (ref _transactionDepth, 0) > 0) { @@ -1298,10 +1299,10 @@ void RollbackTo (string savepoint, bool noThrow) } /// - /// Releases a savepoint returned from . Releasing a savepoint + /// Releases a savepoint returned from . Releasing a savepoint /// makes changes since that savepoint permanent if the savepoint began the transaction, /// or otherwise the changes are permanent pending a call to . - /// + /// /// The RELEASE command is like a COMMIT for a SAVEPOINT. /// /// The name of the savepoint to release. The string should be the result of a call to @@ -2029,7 +2030,7 @@ public class TableAttribute : Attribute /// /// Flag whether to create the table without rowid (see https://sqlite.org/withoutrowid.html) - /// + /// /// The default is false so that sqlite adds an implicit rowid to every table created. /// public bool WithoutRowId { get; set; } @@ -2429,7 +2430,7 @@ public static string SqlType (TableMapping.Column p, bool storeDateTimeAsTicks) else if (clrType == typeof (Single) || clrType == typeof (Double) || clrType == typeof (Decimal)) { return "float"; } - else if (clrType == typeof (String)) { + else if (clrType == typeof (String) || clrType == typeof (StringBuilder) || clrType == typeof (Uri) || clrType == typeof (UriBuilder)) { int? len = p.MaxStringLength; if (len.HasValue) @@ -2778,6 +2779,15 @@ internal static void BindParameter (Sqlite3Statement stmt, int index, object val 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 (); @@ -2882,6 +2892,18 @@ object ReadCol (Sqlite3Statement stmt, int index, SQLite3.ColType type, Type clr 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); } @@ -3749,7 +3771,7 @@ public enum ConfigOption : int [DllImport(LibraryPath, EntryPoint = "sqlite3_open_v2", CallingConvention=CallingConvention.Cdecl)] public static extern Result Open ([MarshalAs(UnmanagedType.LPStr)] string filename, out IntPtr db, int flags, IntPtr zvfs); - + [DllImport(LibraryPath, EntryPoint = "sqlite3_open_v2", CallingConvention = CallingConvention.Cdecl)] public static extern Result Open(byte[] filename, out IntPtr db, int flags, IntPtr zvfs); @@ -3761,16 +3783,16 @@ public enum ConfigOption : int [DllImport(LibraryPath, EntryPoint = "sqlite3_close", CallingConvention=CallingConvention.Cdecl)] public static extern Result Close (IntPtr db); - + [DllImport(LibraryPath, EntryPoint = "sqlite3_close_v2", CallingConvention = CallingConvention.Cdecl)] public static extern Result Close2(IntPtr db); - + [DllImport(LibraryPath, EntryPoint = "sqlite3_initialize", CallingConvention=CallingConvention.Cdecl)] public static extern Result Initialize(); - + [DllImport(LibraryPath, EntryPoint = "sqlite3_shutdown", CallingConvention=CallingConvention.Cdecl)] public static extern Result Shutdown(); - + [DllImport(LibraryPath, EntryPoint = "sqlite3_config", CallingConvention=CallingConvention.Cdecl)] public static extern Result Config (ConfigOption option);