/// <summary> /// Returns a cold observable that compiles a SQL statement /// that publishes the rows in the result set for each subscription. /// </summary> /// <param name="This">The asynchronous database connection.</param> /// <param name="sql">The SQL statement to compile and Query.</param> /// <returns>A cold observable of rows in the result set.</returns> public static IObservable <IReadOnlyList <ResultSetValue> > Query( this IAsyncDatabaseConnection This, string sql) { Contract.Requires(sql != null); return(This.Use(conn => conn.Query(sql))); }
// http://msdn.microsoft.com/en-us/library/system.idisposable(v=vs.110).aspx protected override void Dispose(bool disposing) { if (disposed) { return; } if (disposing) { queue.Use(db => blobStream.Dispose()); } // Free any unmanaged objects here. disposed = true; base.Dispose(disposing); }
/// <summary> /// Compiles and executes multiple SQL statements. /// </summary> /// <param name="This">An asynchronous database connection.</param> /// <param name="sql">One or more semicolon delimited SQL statements.</param> /// <param name="cancellationToken">Cancellation token that can be used to cancel the task.</param> /// <returns>A task that completes when all statements have been executed.</returns> public static Task ExecuteAllAsync( this IAsyncDatabaseConnection This, string sql, CancellationToken cancellationToken) { Contract.Requires(sql != null); return(This.Use((conn, ct) => conn.ExecuteAll(sql), cancellationToken)); }
/// <summary> /// Schedules the <see cref="Func<T,TResult>"/> <paramref name="f"/> on the database operations queue. /// </summary> /// <typeparam name="T">The result type.</typeparam> /// <param name="This">The asynchronous database connection.</param> /// <param name="f">A function from <see cref="IDatabaseConnection"/> to <typeparamref name="T"/>.</param> /// <param name="cancellationToken">Cancellation token that can be used to cancel the task.</param> /// <returns>A task that completes with the result of <paramref name="f"/>.</returns> public static Task <T> Use <T>( this IAsyncDatabaseConnection This, Func <IDatabaseConnection, CancellationToken, T> f, CancellationToken cancellationToken) { Contract.Requires(This != null); Contract.Requires(f != null); return(This.Use((conn, ct) => new[] { f(conn, ct) }).ToTask(cancellationToken)); }
/// <summary> /// Returns a cold observable that compiles a SQL statement with /// provided bind parameter values, that publishes the rows in the result /// set for each subscription. /// </summary> /// <param name="This">The asynchronous database connection.</param> /// <param name="sql">The SQL statement to compile and Query.</param> /// <param name="values">The bind parameter values.</param> /// <returns>A cold observable of rows in the result set.</returns> public static IObservable <IReadOnlyList <ResultSetValue> > Query( this IAsyncDatabaseConnection This, string sql, params object[] values) { Contract.Requires(This != null); Contract.Requires(sql != null); Contract.Requires(values != null); return(This.Use((conn, ct) => conn.Query(sql, values))); }
/// <summary> /// Deletes all object instances specified by their primary keys. /// </summary> /// <returns>A task that completes with a dictionary mapping the primary key to its value if found in the database.</returns> /// <param name="This">The database connection.</param> /// <param name="primaryKeys">An IEnumerable of primary keys to delete.</param> /// <param name="resultSelector">A transform function to apply to each row.</param> /// <param name="ct">A cancellation token that can be used to cancel the operation.</param> /// <typeparam name="T">The mapped type.</typeparam> public static Task <IReadOnlyDictionary <long, T> > DeleteAllAsync <T>( this IAsyncDatabaseConnection This, IEnumerable <long> primaryKeys, Func <IReadOnlyList <ResultSetValue>, T> resultSelector, CancellationToken ct) { Contract.Requires(primaryKeys != null); Contract.Requires(resultSelector != null); return(This.Use((db, _) => db.DeleteAll <T>(primaryKeys, resultSelector), ct)); }
/// <summary> /// Compiles and executes a SQL statement with the provided bind parameter values. /// </summary> /// <param name="This">The asynchronous database connection.</param> /// <param name="sql">The SQL statement to compile and execute.</param> /// <param name="cancellationToken">Cancellation token that can be used to cancel the task.</param> /// <param name="values">The bind parameter values.</param> /// <returns>A task that completes when the statement has been executed.</returns> public static Task ExecuteAsync( this IAsyncDatabaseConnection This, string sql, CancellationToken cancellationToken, params object[] values) { Contract.Requires(sql != null); Contract.Requires(values != null); return(This.Use((conn, ct) => conn.Execute(sql, values), cancellationToken)); }
/// <summary> /// Inserts the objects into the database, replacing existing entries if the given primary keys already exist. /// </summary> /// <returns>A Task that completes with a dictionary mapping the provided objects to the objects that were inserted into the database.</returns> /// <param name="This">The database connection.</param> /// <param name="objects">The objects to be inserted into the database.</param> /// <param name="resultSelector">A transform function to apply to each row.</param> /// <param name="ct">A cancellation token that can be used to cancel the operation</param> /// <typeparam name="T">The mapped type.</typeparam> public static Task <IReadOnlyDictionary <T, T> > InsertOrReplaceAllAsync <T>( this IAsyncDatabaseConnection This, IEnumerable <T> objects, Func <IReadOnlyList <ResultSetValue>, T> resultSelector, CancellationToken ct) { Contract.Requires(objects != null); Contract.Requires(resultSelector != null); return(This.Use((db, _) => db.InsertOrReplaceAll(objects, resultSelector), ct)); }
/// <summary> /// Compiles a SQL statement. /// </summary> /// <param name="This">The asynchronous database connection.</param> /// <param name="sql">The SQL statement to compile.</param> /// <param name="cancellationToken">Cancellation token that can be used to cancel the task.</param> /// <returns>Task that completes with a <see cref="IAsyncStatement"/> that /// can be used to query the result set asynchronously.</returns> public static Task <IAsyncStatement> PrepareStatementAsync( this IAsyncDatabaseConnection This, string sql, CancellationToken cancellationToken) { Contract.Requires(sql != null); return(This.Use <IAsyncStatement>((conn, ct) => { var stmt = conn.PrepareStatement(sql); return new AsyncStatementImpl(stmt, This); }, cancellationToken)); }
/// <summary> /// Schedules the <see cref="Action"/> <paramref name="f"/> on the database operations queue. /// </summary> /// <param name="This">The asynchronous database connection.</param> /// <param name="f">The action.</param> /// <param name="cancellationToken">Cancellation token that can be used to cancel the task.</param> /// <returns>A task that completes when <paramref name="f"/> returns.</returns> public static Task Use( this IAsyncDatabaseConnection This, Action <IDatabaseConnection, CancellationToken> f, CancellationToken cancellationToken) { Contract.Requires(f != null); return(This.Use((conn, ct) => { f(conn, ct); return Enumerable.Empty <Unit>(); }, cancellationToken)); }
/// <summary> /// Opens the blob located by the a database, table, column, and rowid for incremental asynchronous I/O as a <see cref="System.IO.Stream"/>. /// </summary> /// <param name="This">The asynchronous database connection.</param> /// <param name="database">The database containing the blob.</param> /// <param name="tableName">The table containing the blob.</param> /// <param name="columnName">The column containing the blob.</param> /// <param name="rowId">The row containing the blob.</param> /// <param name="canWrite"> /// <see langwords="true"/> if the Stream should be open for both read and write operations. /// <see langwords="false"/> if the Stream should be open oly for read operations. /// </param> /// <param name="cancellationToken">Cancellation token that can be used to cancel the task.</param> /// <returns>A <see cref="Task"/> that completes with a <see cref="System.IO.Stream"/> that can be used to asynchronously write and read to and from blob.</returns> public static Task <Stream> OpenBlobAsync( this IAsyncDatabaseConnection This, string database, string tableName, string columnName, long rowId, bool canWrite, CancellationToken cancellationToken) { Contract.Requires(database != null); Contract.Requires(tableName != null); Contract.Requires(columnName != null); return(This.Use <Stream>((db, ct) => { var blob = db.OpenBlob(database, tableName, columnName, rowId, canWrite); return new AsyncBlobStream(blob, This); }, cancellationToken)); }
/// <summary> /// Compiles one or more SQL statements. /// </summary> /// <param name="This">The asynchronous database connection.</param> /// <param name="sql">One or more semicolon delimited SQL statements.</param> /// <param name="cancellationToken">Cancellation token that can be used to cancel the task.</param> /// <returns>A <see cref="Task"/> that completes with a <see cref="IReadOnlyList<T>"/> /// of the compiled <see cref="IAsyncStatement"/>instances.</returns> public static Task <IReadOnlyList <IAsyncStatement> > PrepareAllAsync( this IAsyncDatabaseConnection This, string sql, CancellationToken cancellationToken) { Contract.Requires(sql != null); return(This.Use <IReadOnlyList <IAsyncStatement> >((conn, ct) => { // Eagerly prepare all the statements. The synchronous version of PrepareAll() // is lazy, preparing each statement when MoveNext() is called on the Enumerator. // Hence an implementation like: // // return conn.PrepareAll(sql).Select(stmt => new AsyncStatementImpl(stmt, This)); // // would result in unintentional database access not on the operations queue. // Added bonus of being eager: Callers can retrieve individual statements via // the index in the list. return conn.PrepareAll(sql).Select(stmt => new AsyncStatementImpl(stmt, This)).ToList(); }, cancellationToken)); }
/// <summary> /// Deletes all rows in a given table, asynchronously. /// </summary> /// <returns>A task that completes when all rows are deleted succesfully.</returns> /// <param name="This">The database connection.</param> /// <param name="ct">A cancellation token that can be used to cancel the operation.</param> /// <typeparam name="T">The mapped type.</typeparam> public static Task DeleteAllRowsAsync <T>(this IAsyncDatabaseConnection This, CancellationToken ct) => This.Use((db, _) => db.DeleteAllRows <T>(), ct);
/// <summary> /// Drops the table if exists async. /// </summary> /// <returns>The table if exists async.</returns> /// <param name="This">The database connection.</param> /// <param name="ct">The cancellation token.</param> public static Task DropTableIfExistsAsync <T>(this IAsyncDatabaseConnection This, CancellationToken ct) => This.Use((db, _) => db.DropTableIfExists <T>(), ct);
/// <summary> /// Creates or migrate a table in the database for the given table mapping, creating indexes if needed. /// </summary> /// <returns>A task that completes once the table is succesfully created and is ready for use.</returns> /// <param name="This">The database connection</param> /// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param> /// <typeparam name="T">The mapped type.</typeparam> public static Task InitTableAsync <T>(this IAsyncDatabaseConnection This, CancellationToken cancellationToken) { Contract.Requires(This != null); return(This.Use((db, ct) => db.InitTable <T>(), cancellationToken)); }
/// <summary> /// Returns a cold IObservable which schedules the function f on the database operation queue each /// time it is is subscribed to. The published values are generated by enumerating the IEnumerable returned by f. /// </summary> /// <typeparam name="T">The result type.</typeparam> /// <param name="This">The asynchronous database connection.</param> /// <param name="f"> /// A function that may synchronously use the provided IDatabaseConnection and returns /// an IEnumerable of produced values that are published to the subscribed IObserver. /// The returned IEnumerable may block. This allows the IEnumerable to provide the results of /// enumerating a SQLite prepared statement for instance. /// </param> /// <returns>A cold observable of the values produced by the function f.</returns> public static IObservable <T> Use <T>(this IAsyncDatabaseConnection This, Func <IDatabaseConnection, IEnumerable <T> > f) { Contract.Requires(f != null); return(This.Use((conn, ct) => f(conn))); }
/// <summary> /// Schedules the <see cref="Func<T,TResult>"/> <paramref name="f"/> on the database operations queue. /// </summary> /// <typeparam name="T">The result type.</typeparam> /// <param name="This">The asynchronous database connection.</param> /// <param name="f">A function from <see cref="IDatabaseConnection"/> to <typeparamref name="T"/>.</param> /// <returns>A task that completes with the result of <paramref name="f"/>.</returns> public static Task <T> Use <T>(this IAsyncDatabaseConnection This, Func <IDatabaseConnection, T> f) { Contract.Requires(f != null); return(This.Use((db, ct) => f(db), CancellationToken.None)); }