diff --git a/Sqlite/Cirrious.MvvmCross.Community.Plugins.Sqlite/BaseClasses.cs b/Sqlite/Cirrious.MvvmCross.Community.Plugins.Sqlite/BaseClasses.cs index 94bcbb6..13dab5e 100644 --- a/Sqlite/Cirrious.MvvmCross.Community.Plugins.Sqlite/BaseClasses.cs +++ b/Sqlite/Cirrious.MvvmCross.Community.Plugins.Sqlite/BaseClasses.cs @@ -1,1006 +1,190 @@ -// BaseClasses.cs -// (c) Copyright Cirrious Ltd. http://www.cirrious.com -// MvvmCross is licensed using Microsoft Public License (Ms-PL) -// Contributions and inspirations noted in readme.md and license.txt -// -// Project Lead - Stuart Lodge, @slodge, me@slodge.com - using System; using System.Collections.Generic; -using System.Linq.Expressions; -using SQLiteOpenFlags = System.Int16; +using System.Linq; +using System.Text; +using SQLite; -namespace Cirrious.MvvmCross.Community.Plugins.Sqlite +namespace SQLite.Net.Interop { - /// - /// This class is used to provide advanced options for creation of - /// a SQLiteConnection. - /// + public enum DatabaseType + { + File, + InMemory, + Temporary + } + public class SQLiteConnectionOptions { - /// - /// Constructs a SQLiteConnectionOptions with default settings. - /// - public SQLiteConnectionOptions() - { - // we want the default to be Ticks - see https://github.com/slodge/MvvmCross/issues/213#issuecomment-24610834 - StoreDateTimeAsTicks = true; - } - /// - /// The name of the database file. - /// - public string Address { get; set; } - /// - /// The base path1 to use in conjunction with the Address to create - /// the full location to store the database file. - /// - /// - /// This is used for determining the name of File databases, and the key - /// used for distinct in-memory databases. This is not used for temporary - /// databases. - /// - /// Please note that if this value is null it will be set based on best - /// know location based on platform. Only provide this value if you - /// know what you are doing. If this value is left empty it will not - /// be replaced and only the Address will be used. - /// - /// - public string BasePath { get; set; } - /// - /// If true will store DateTime properties as ticks; otherwise it - /// will not. (Default: true) - /// - /// - /// It is recommended to always set this to true, which the default. - /// This is due to performance advantages as well as an MvvmCross - /// documented issue: - /// https://github.com/slodge/MvvmCross/issues/213#issuecomment-24610834 - /// - public bool StoreDateTimeAsTicks { get; set; } - /// - /// States which type of database should be created. (Default: File) - /// - public DatabaseType Type { get; set; } - - /// - /// Types of databases that can be created. - /// - public enum DatabaseType + public SQLiteConnectionOptions(string databasePath, DatabaseType databaseType = DatabaseType.File, bool storeDateTimeAsTicks = true) { - /// - /// Specifies a file based database. (Default) - /// - File, - /// - /// Specifies a pure in-memory database. - /// - InMemory, - /// - /// Specifies a temporary file based database. - /// - Temporary, + DatabasePath = databasePath; + DatabaseType = databaseType; + StoreDateTimeAsTicks = storeDateTimeAsTicks; } - } - public interface ISQLiteConnectionFactoryEx - { - /// - /// Creates a SQLite database using the provided options. - /// - /// The options to use to create a SQLite connection. - /// A ISQLiteConnection. - ISQLiteConnection CreateEx(SQLiteConnectionOptions options); - /// - /// Creates a SQLite database using the provided path2 and options. - /// - /// Address for the database. - /// The provide path2 will override any provided in the options. - /// The options to use to create a SQLite connection. - /// A ISQLiteConnection. - ISQLiteConnection CreateEx(string address, SQLiteConnectionOptions options = null); + public string DatabasePath { get; set; } + public DatabaseType DatabaseType { get; set; } + public bool StoreDateTimeAsTicks { get; set; } } public interface ISQLiteConnectionFactory { - /// - /// Creates a SQLite database using the provided path2. - /// - /// Address for the database. - /// A ISQLiteConnection. - ISQLiteConnection Create(string address); - /// - /// Creates a in-memory SQLite database. - /// - /// - /// This method will create NO FILES on disk and it will be a new - /// database that exists only in memory. Once the connection is closed - /// the database will no longer exist. You can open multiple in memory - /// databases and they will each be created as an isolated in-memory - /// databases. - /// - /// An ISQLiteConnection to a isolated in-memory database. + ISQLiteConnection Create(string databasePath); ISQLiteConnection CreateInMemory(); - /// - /// Creates a new temporary SQLite database. - /// - /// - /// Each call will create a new temporary file based database. Each connection - /// will therefore be to is own temporary database. Once the connection that - /// created it is closed the temporary database will be deleted. - /// - /// Please note that while a file is created for each temporary database - /// that typically it will reside in the in-memory pager cache. This is - /// still different from a pure in-memory database created by the Created*InMemory - /// methods in that the temporary database may be flushed to the file if - /// it becomes to large or if the underlying SQLite engine is placed under - /// memory pressure. This never occurs with the pure in-memory database options. - /// - /// - /// A ISQLiteConnection to a temporary database. - ISQLiteConnection CreateTemp(); + ISQLiteConnection CreateTemporary(); } - [Flags] - public enum CreateFlags + public interface ISQLiteConnectionFactoryEx { - None = 0, - ImplicitPK = 1, // create a primary key for field called 'Id' (Orm.ImplicitPkName) - ImplicitIndex = 2, // create an index for fields ending in 'Id' (Orm.ImplicitIndexSuffix) - AllImplicit = 3, // do both above - - AutoIncPK = 4 // force PK field to be auto inc + ISQLiteConnection Create(SQLiteConnectionOptions options); } - public class ColumnInfo - { - [Column("name")] - public string Name { get; set; } - - public override string ToString() - { - return Name; - } - } - - public class CreateTablesResult + [Flags] + public enum CreateFlags { - public Dictionary Results { get; private set; } - - public CreateTablesResult() - { - this.Results = new Dictionary(); - } + None = 0x000, + ImplicitPK = 0x001, + AutoIncPK = 0x002, + ImplicitIndex = 0x004, + AllImplicit = ImplicitPK | AutoIncPK | ImplicitIndex, + FullTextSearch3 = 0x100, + FullTextSearch4 = 0x200, + Nullable = 0x800 } - [AttributeUsage(AttributeTargets.Class)] + [AttributeUsage(AttributeTargets.Class, Inherited = false)] public class TableAttribute : Attribute { - public string Name { get; set; } - public TableAttribute(string name) { Name = name; } + + public string Name { get; } } [AttributeUsage(AttributeTargets.Property)] public class ColumnAttribute : Attribute { - public string Name { get; set; } - public ColumnAttribute(string name) { Name = name; } + + public string Name { get; } } [AttributeUsage(AttributeTargets.Property)] - public class PrimaryKeyAttribute : Attribute - { - } + public class PrimaryKeyAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property)] - public class AutoIncrementAttribute : Attribute - { - } + public class AutoIncrementAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property)] public class IndexedAttribute : Attribute { - public string Name { get; set; } - public int Order { get; set; } - public virtual bool Unique { get; set; } - - public IndexedAttribute() - { - } - - public IndexedAttribute(string name, int order) + public IndexedAttribute(string name = null, int order = -1, bool unique = false) { Name = name; Order = order; + Unique = unique; } - } - [AttributeUsage(AttributeTargets.Property)] - public class IgnoreAttribute : Attribute - { + public string Name { get; } + public int Order { get; } + public bool Unique { get; } } [AttributeUsage(AttributeTargets.Property)] - public class UniqueAttribute : IndexedAttribute - { - public override bool Unique - { - get { return true; } - set { /* throw? */ } - } - } + public class IgnoreAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property)] - public class MaxLengthAttribute : Attribute - { - public int Value { get; private set; } + public class UniqueAttribute : Attribute { } - public MaxLengthAttribute(int length) - { - Value = length; - } - } + [AttributeUsage(AttributeTargets.Property)] + public class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property)] public class CollationAttribute : Attribute { - public string Value { get; private set; } - public CollationAttribute(string collation) { Value = collation; } - } - - [AttributeUsage(AttributeTargets.Property)] - public class NotNullAttribute : Attribute - { - } - public interface ITableMapping - { - string TableName { get; } + public string Value { get; } } - public interface ITableQuery : IEnumerable where T : new() - { - ISQLiteConnection Connection { get; } - - ITableQuery Where(Expression> predExpr); - - ITableQuery Take(int n); - - ITableQuery Skip(int n); - - T ElementAt(int index); - - ITableQuery Deferred(); - - ITableQuery OrderBy(Expression> orderExpr); - - ITableQuery OrderByDescending(Expression> orderExpr); - - ITableQuery Join( - ITableQuery inner, - Expression> outerKeySelector, - Expression> innerKeySelector, - Expression> resultSelector) - where TResult : new() - where TInner : new(); - - ITableQuery Select(Expression> selector) where TResult : new(); - - int Count(); - - int Count(Expression> predExpr); - - IEnumerator GetEnumerator(); - - T First(); - - T FirstOrDefault(); - } - - public interface ISQLiteCommand + [AttributeUsage(AttributeTargets.Property)] + public class MaxLengthAttribute : Attribute { - string CommandText { get; set; } - - int ExecuteNonQuery(); - - IEnumerable ExecuteDeferredQuery(); - - List ExecuteQuery(); - - List ExecuteQuery(ITableMapping map); - - IEnumerable ExecuteDeferredQuery(ITableMapping map); - - T ExecuteScalar(); - - void Bind(string name, object val); + public MaxLengthAttribute(int length) + { + Value = length; + } - void Bind(object val); + public int Value { get; } } - /// - /// Represents an open connection to a SQLite database. - /// public interface ISQLiteConnection : IDisposable { - string DatabasePath { get; } - - bool TimeExecution { get; set; } - - bool Trace { get; set; } - - bool StoreDateTimeAsTicks { get; } - - /// - /// Sets a busy handler to sleep the specified amount of time when a table is locked. - /// The handler will sleep multiple times until a total time of has accumulated. - /// - TimeSpan BusyTimeout { get; set; } - - /// - /// Retrieves the mapping that is automatically generated for the given type. - /// - /// - /// 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 - /// methods to set and get properties of objects. - /// - ITableMapping GetMapping(Type type, CreateFlags createFlags = CreateFlags.None); - - /// - /// Retrieves the mapping that is automatically generated for the given type. - /// - /// - /// The mapping represents the schema of the columns of the database and contains - /// methods to set and get properties of objects. - /// - ITableMapping GetMapping(); - - /// - /// Executes a "drop table" on the database. This is non-recoverable. - /// - int DropTable(); - - /// - /// Executes a "create table if not exists" on the database. It also - /// creates any specified indexes on the columns of the table. It uses - /// a schema automatically generated from the specified type. You can - /// later access this schema by calling GetMapping. - /// - /// - /// The number of entries added to the database schema. - /// - int CreateTable(CreateFlags createFlags = CreateFlags.None); - - /// - /// Executes a "create table if not exists" on the database. It also - /// creates any specified indexes on the columns of the table. It uses - /// a schema automatically generated from the specified type. You can - /// 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. - /// - /// The number of entries added to the database schema. - /// - int CreateTable(Type ty, CreateFlags createFlags = CreateFlags.None); - - /// - /// Creates an index for the specified table and column. - /// - /// Name of the index to create - /// Name of the database table - /// Name of the column to index - /// Whether the index should be unique - int CreateIndex(string indexName, string tableName, string columnName, bool unique = false); - - /// - /// Creates an index for the specified table and column. - /// - /// Name of the database table - /// Name of the column to index - /// Whether the index should be unique - int CreateIndex(string tableName, string columnName, bool unique = false); - - /// - /// Creates an index for the specified object property. - /// e.g. CreateIndex(c => c.Name); - /// - /// Type to reflect to a database table. - /// Property to index - /// Whether the index should be unique - void CreateIndex(Expression> property, bool unique = false); - - List GetTableInfo(string tableName); - - /// - /// Creates a new SQLiteCommand given the command text with arguments. Place a '?' - /// in the command text for each of the arguments. - /// - /// - /// The fully escaped SQL. - /// - /// - /// Arguments to substitute for the occurences of '?' in the command text. - /// - /// - /// A - /// - ISQLiteCommand CreateCommand(string cmdText, params object[] ps); - - /// - /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?' - /// in the command text for each of the arguments and then executes that command. - /// Use this method instead of Query when you don't expect rows back. Such cases include - /// INSERTs, UPDATEs, and DELETEs. - /// You can set the Trace or TimeExecution properties of the connection - /// to profile execution. - /// - /// - /// The fully escaped SQL. - /// - /// - /// Arguments to substitute for the occurences of '?' in the query. - /// - /// - /// The number of rows modified in the database as a result of this execution. - /// - int Execute(string query, params object[] args); - - T ExecuteScalar(string query, params object[] args); - - /// - /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?' - /// in the command text for each of the arguments and then executes that command. - /// It returns each row of the result using the mapping automatically generated for - /// the given type. - /// - /// - /// The fully escaped SQL. - /// - /// - /// Arguments to substitute for the occurences of '?' in the query. - /// - /// - /// An enumerable with one result for each row returned by the query. - /// - List Query(string query, params object[] args) where T : new(); - - /// - /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?' - /// in the command text for each of the arguments and then executes that command. - /// It returns each row of the result using the mapping automatically generated for - /// the given type. - /// - /// - /// The fully escaped SQL. - /// - /// - /// Arguments to substitute for the occurences of '?' in the query. - /// - /// - /// An enumerable with one result for each row returned by the query. - /// The enumerator will call sqlite3_step on each call to MoveNext, so the database - /// connection must remain open for the lifetime of the enumerator. - /// - IEnumerable DeferredQuery(string query, params object[] args) where T : new(); - - /// - /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?' - /// in the command text for each of the arguments and then executes that command. - /// It returns each row of the result using the specified mapping. This function is - /// only used by libraries in order to query the database via introspection. It is - /// normally not used. - /// - /// - /// A to use to convert the resulting rows - /// into objects. - /// - /// - /// The fully escaped SQL. - /// - /// - /// Arguments to substitute for the occurences of '?' in the query. - /// - /// - /// An enumerable with one result for each row returned by the query. - /// - List Query(ITableMapping map, string query, params object[] args); - - /// - /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?' - /// in the command text for each of the arguments and then executes that command. - /// It returns each row of the result using the specified mapping. This function is - /// only used by libraries in order to query the database via introspection. It is - /// normally not used. - /// - /// - /// A to use to convert the resulting rows - /// into objects. - /// - /// - /// The fully escaped SQL. - /// - /// - /// Arguments to substitute for the occurences of '?' in the query. - /// - /// - /// An enumerable with one result for each row returned by the query. - /// The enumerator will call sqlite3_step on each call to MoveNext, so the database - /// connection must remain open for the lifetime of the enumerator. - /// - IEnumerable DeferredQuery(ITableMapping map, string query, params object[] args); - - /// - /// Returns a queryable interface to the table represented by the given type. - /// - /// - /// A queryable object that is able to translate Where, OrderBy, and Take - /// queries into native SQL. - /// - ITableQuery Table() where T : new(); - - /// - /// Attempts to retrieve an object with the given primary key from the table - /// associated with the specified type. Use of this method requires that - /// the given type have a designated PrimaryKey (using the PrimaryKeyAttribute). - /// - /// - /// The primary key. - /// - /// - /// The object with the given primary key. Throws a not found exception - /// if the object is not found. - /// - T Get(object pk) where T : new(); - - /// - /// Attempts to retrieve the first object that matches the predicate from the table - /// associated with the specified type. - /// - /// - /// A predicate for which object to find. - /// - /// - /// The object that matches the given predicate. Throws a not found exception - /// if the object is not found. - /// - T Get(Expression> predicate) where T : new(); + void Trace(bool enabled); - /// - /// Attempts to retrieve an object with the given primary key from the table - /// associated with the specified type. Use of this method requires that - /// the given type have a designated PrimaryKey (using the PrimaryKeyAttribute). - /// - /// - /// The primary key. - /// - /// - /// The object with the given primary key or null - /// if the object is not found. - /// - T Find(object pk) where T : new(); - - /// - /// Attempts to retrieve an object with the given primary key from the table - /// associated with the specified type. Use of this method requires that - /// the given type have a designated PrimaryKey (using the PrimaryKeyAttribute). - /// - /// - /// The primary key. - /// - /// - /// The TableMapping used to identify the object type. - /// - /// - /// The object with the given primary key or null - /// if the object is not found. - /// - object Find(object pk, ITableMapping map); - - /// - /// Attempts to retrieve the first object that matches the predicate from the table - /// associated with the specified type. - /// - /// - /// A predicate for which object to find. - /// - /// - /// The object that matches the given predicate or null - /// if the object is not found. - /// - T Find(Expression> predicate) where T : new(); - - /// - /// Whether has been called and the database is waiting for a . - /// - bool IsInTransaction { get; } - - /// - /// Begins a new transaction. Call to end the transaction. - /// - /// Throws if a transaction has already begun. - void BeginTransaction(); + int Execute(string sql, params object[] args); + List Query(string sql, params object[] args) where T : new(); + T Find(object primaryKey) where T : new(); + T Get(object primaryKey) where T : new(); + T Get(Expression> predicate) where T : new(); - /// - /// 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. - /// - /// A string naming the savepoint. - string SaveTransactionPoint(); - - /// - /// Rolls back the transaction that was begun by or . - /// - void Rollback(); + int Insert(object item); + int InsertAll(IEnumerable items); + int Update(object item); + int Delete(object item); - /// - /// Rolls back the savepoint created by or SaveTransactionPoint. - /// - /// The name of the savepoint to roll back to, as returned by . If savepoint is null or empty, this method is equivalent to a call to - void RollbackTo(string 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 - void Release(string savepoint); - - /// - /// Commits the transaction that was begun by . - /// + void CreateTable(CreateFlags createFlags = CreateFlags.None); + void DropTable(); + TableMapping GetMapping(Type type); + void BeginTransaction(); void Commit(); + void Rollback(); - /// - /// Executes within a (possibly nested) transaction by wrapping it in a SAVEPOINT. If an - /// exception occurs the whole transaction is rolled back, not just the current savepoint. The exception - /// is rethrown. - /// - /// - /// The to perform within a transaction. can contain any number - /// of operations on the connection but should never call or - /// . - /// - void RunInTransaction(Action action); - - /// - /// Inserts all specified objects. - /// - /// - /// An of the objects to insert. - /// - /// - /// The number of rows added to the table. - /// - int InsertAll(System.Collections.IEnumerable objects); - - /// - /// Inserts all specified objects. - /// - /// - /// An of the objects to insert. - /// - /// - /// Literal SQL code that gets placed into the command. INSERT {extra} INTO ... - /// - /// - /// The number of rows added to the table. - /// - int InsertAll(System.Collections.IEnumerable objects, string extra); - - /// - /// Inserts all specified objects. - /// - /// - /// An of the objects to insert. - /// - /// - /// The type of object to insert. - /// - /// - /// The number of rows added to the table. - /// - int InsertAll(System.Collections.IEnumerable objects, Type objType); - - /// - /// Inserts the given object and retrieves its - /// auto incremented primary key if it has one. - /// - /// - /// The object to insert. - /// - /// - /// The number of rows added to the table. - /// - int Insert(object obj); - - /// - /// Inserts the given object and retrieves its - /// auto incremented primary key if it has one. - /// If a UNIQUE constraint violation occurs with - /// some pre-existing object, this function deletes - /// the old object. - /// - /// - /// The object to insert. - /// - /// - /// The number of rows modified. - /// - int InsertOrReplace(object obj); - - /// - /// Inserts the given object and retrieves its - /// auto incremented primary key if it has one. - /// - /// - /// The object to insert. - /// - /// - /// The type of object to insert. - /// - /// - /// The number of rows added to the table. - /// - int Insert(object obj, Type objType); - - /// - /// Inserts the given object and retrieves its - /// auto incremented primary key if it has one. - /// If a UNIQUE constraint violation occurs with - /// some pre-existing object, this function deletes - /// the old object. - /// - /// - /// The object to insert. - /// - /// - /// The type of object to insert. - /// - /// - /// The number of rows modified. - /// - int InsertOrReplace(object obj, Type objType); - - /// - /// Inserts the given object and retrieves its - /// auto incremented primary key if it has one. - /// - /// - /// The object to insert. - /// - /// - /// Literal SQL code that gets placed into the command. INSERT {extra} INTO ... - /// - /// - /// The number of rows added to the table. - /// - int Insert(object obj, string extra); - - /// - /// Inserts the given object and retrieves its - /// auto incremented primary key if it has one. - /// - /// - /// The object to insert. - /// - /// - /// Literal SQL code that gets placed into the command. INSERT {extra} INTO ... - /// - /// - /// The type of object to insert. - /// - /// - /// The number of rows added to the table. - /// - int Insert(object obj, string extra, Type objType); - - /// - /// Updates all of the columns of a table using the specified object - /// except for its primary key. - /// The object is required to have a primary key. - /// - /// - /// The object to update. It must have a primary key designated using the PrimaryKeyAttribute. - /// - /// - /// The number of rows updated. - /// - int Update(object obj); - - /// - /// Updates all of the columns of a table using the specified object - /// except for its primary key. - /// The object is required to have a primary key. - /// - /// - /// The object to update. It must have a primary key designated using the PrimaryKeyAttribute. - /// - /// - /// The type of object to insert. - /// - /// - /// The number of rows updated. - /// - int Update(object obj, Type objType); - - /// - /// Updates all specified objects. - /// - /// - /// An of the objects to insert. - /// - /// - /// The number of rows modified. - /// - int UpdateAll(System.Collections.IEnumerable objects); - - /// - /// Deletes the given object from the database using its primary key. - /// - /// - /// The object to delete. It must have a primary key designated using the PrimaryKeyAttribute. - /// - /// - /// The number of rows deleted. - /// - int Delete(object objectToDelete); - - /// - /// Deletes the object with the specified primary key. - /// - /// - /// The primary key of the object to delete. - /// - /// - /// The number of objects deleted. - /// - /// - /// The type of object. - /// - int Delete(object primaryKey); - - /// - /// Deletes all the objects from the specified table. - /// WARNING WARNING: Let me repeat. It deletes ALL the objects from the - /// specified table. Do you really want to do that? - /// - /// - /// The number of objects deleted. - /// - /// - /// The type of objects to delete. - /// - int DeleteAll(); - - void Close(); + TableQuery Table() where T : new(); } - /// - /// Base class that each platform specific SQLiteConnectionFactory - /// should extend. - /// - public abstract class MvxBaseSQLiteConnectionFactory - : ISQLiteConnectionFactory - , ISQLiteConnectionFactoryEx + public abstract class MvxBaseSQLiteConnectionFactory : ISQLiteConnectionFactory, ISQLiteConnectionFactoryEx { - private const string InMemoryDatabase = ":memory:"; - - public virtual ISQLiteConnection Create(string address) + public ISQLiteConnection Create(string databasePath) { - return CreateEx(address); + return Create(new SQLiteConnectionOptions(databasePath)); } - public virtual ISQLiteConnection CreateInMemory() + public ISQLiteConnection CreateInMemory() { - var options = new SQLiteConnectionOptions { Type = SQLiteConnectionOptions.DatabaseType.InMemory, }; - return CreateEx(options); + return Create(new SQLiteConnectionOptions(null, DatabaseType.InMemory)); } - public virtual ISQLiteConnection CreateTemp() + public ISQLiteConnection CreateTemporary() { - var options = new SQLiteConnectionOptions { Type = SQLiteConnectionOptions.DatabaseType.Temporary, }; - return CreateEx(options); + return Create(new SQLiteConnectionOptions(null, DatabaseType.Temporary)); } - public virtual ISQLiteConnection CreateEx(SQLiteConnectionOptions options) + public ISQLiteConnection Create(SQLiteConnectionOptions options) { - if (options == null) - throw new ArgumentNullException("options"); - switch (options.Type) + if (options == null) throw new ArgumentNullException(nameof(options)); + + switch (options.DatabaseType) { - case SQLiteConnectionOptions.DatabaseType.InMemory: - return CreateInMemoryDb(options); - case SQLiteConnectionOptions.DatabaseType.Temporary: - return CreateTempDb(options); - default: - return CreateFileDb(options); + case DatabaseType.File: + return CreateSQLiteConnection(options.DatabasePath, options.StoreDateTimeAsTicks); + case DatabaseType.InMemory: + return CreateSQLiteConnection(":memory:", options.StoreDateTimeAsTicks); + case DatabaseType.Temporary: + return CreateSQLiteConnection("", options.StoreDateTimeAsTicks); + default: + throw new NotSupportedException($"Unsupported database type: {options.DatabaseType}"); } } - public virtual ISQLiteConnection CreateEx(string address, SQLiteConnectionOptions options = null) - { - options = options ?? new SQLiteConnectionOptions(); - options.Address = address; - return CreateEx(options); - } - - private ISQLiteConnection CreateFileDb(SQLiteConnectionOptions options) - { - if (string.IsNullOrWhiteSpace(options.Address)) - throw new ArgumentException(Properties.Resources.CreateFileDbInvalidAddress); - var path = options.BasePath ?? GetDefaultBasePath(); - string filePath = LocalPathCombine(path, options.Address); - return CreateSQLiteConnection(filePath, options.StoreDateTimeAsTicks); - } - - private ISQLiteConnection CreateInMemoryDb(SQLiteConnectionOptions options) - { - return CreateSQLiteConnection(InMemoryDatabase, options.StoreDateTimeAsTicks); - } - - private ISQLiteConnection CreateTempDb(SQLiteConnectionOptions options) - { - return CreateSQLiteConnection(string.Empty, options.StoreDateTimeAsTicks); - } - - /// - /// Returns the platform specific default base path1. - /// - /// - /// Returns default base path. - /// - protected abstract string GetDefaultBasePath(); - /// - /// Combines two strings into a platform specific path1. - /// - /// - /// If one of the specified paths is a zero-length string, - /// this method returns the other path. If - /// contains an absolute path, this method returns - /// . - /// - /// The first path1 to combine - /// The second path1 to combine. - /// - /// The combined paths. - /// - protected abstract string LocalPathCombine(string path1, string path2); - /// - /// Creates the platform specific SQLiteConnection. - /// - /// - /// The name of a file that does or will contain the database. - /// - /// - /// If true will store DateTime properties as ticks; otherwise it - /// will not. - /// - /// Returns the interface to a SQLiteConnection. protected abstract ISQLiteConnection CreateSQLiteConnection(string databasePath, bool storeDateTimeAsTicks); } -} \ No newline at end of file +}