-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Ref app sq lite mem store #245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
88842de
initial commit; implemented memory store interface
amsacha 6934c6c
database builds and can perform writes, textmemoryskill.recall runnin…
amsacha 082736a
Deserialize string to MemoryRecord; Cleanup;
amsacha 92832fe
reduce surface area; remove imported files; undo changes to githubski…
amsacha 19e7977
fixes after rebase
amsacha 2f6e0b0
open and close sqlite connection around each operation instead of kee…
amsacha 644d2a3
added more insert variations for interacting with the sqlite database
amsacha 6a49a45
resolving PR comments
amsacha 69d8c34
Added doc blocks to a few functions
amsacha 025baaa
Merge branch 'feature-refapp' into RefApp_SqLiteMemStore
adrianwyatt 60aece8
ran dotnet format again
amsacha 01a0a95
Merge branch 'feature-refapp' into RefApp_SqLiteMemStore
amsacha File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
149 changes: 149 additions & 0 deletions
149
dotnet/src/SemanticKernel.Skills/Skills.Memory.Sqlite/SqliteDataStore.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,149 @@ | ||
| // Copyright (c) Microsoft. All rights reserved. | ||
|
|
||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Diagnostics.CodeAnalysis; | ||
| using System.Globalization; | ||
| using System.Runtime.CompilerServices; | ||
| using System.Text.Json; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using Microsoft.Data.Sqlite; | ||
| using Microsoft.SemanticKernel.Memory.Storage; | ||
| using Microsoft.SemanticKernel.Skills.Memory.Sqlite; | ||
|
|
||
| namespace Microsoft.SemanticKernel.Skills.Memory.Sqlite; | ||
|
|
||
| /// <summary> | ||
| /// An implementation of <see cref="IDataStore{TValue}"/> backed by a SQLite database. | ||
| /// </summary> | ||
| /// <remarks>The data is saved to a database file, specified in the constructor. | ||
| /// The data persists between subsequent instances. Only one instance may access the file at a time. | ||
| /// The caller is responsible for deleting the file.</remarks> | ||
| /// <typeparam name="TValue">The type of data to be stored in this data store.</typeparam> | ||
| public class SqliteDataStore<TValue> : IDataStore<TValue>, IDisposable | ||
| { | ||
| /// <summary> | ||
| /// Connect a Sqlite database | ||
| /// </summary> | ||
| /// <param name="filename">Path to the database file. If file does not exist, it will be created.</param> | ||
| /// <param name="cancel">Cancellation token</param> | ||
| [SuppressMessage("Design", "CA1000:Do not declare static members on generic types", | ||
| Justification = "Static factory method used to ensure successful connection.")] | ||
| public static async Task<SqliteDataStore<TValue>> ConnectAsync(string filename, | ||
| CancellationToken cancel = default) | ||
| { | ||
| SqliteConnection dbConnection = await Database.CreateConnectionAsync(filename, cancel); | ||
| return new SqliteDataStore<TValue>(dbConnection); | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public IAsyncEnumerable<string> GetCollectionsAsync(CancellationToken cancel = default) | ||
| { | ||
| return this._dbConnection.GetCollectionsAsync(cancel); | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public async IAsyncEnumerable<DataEntry<TValue>> GetAllAsync(string collection, | ||
| [EnumeratorCancellation] CancellationToken cancel = default) | ||
| { | ||
| await foreach (DatabaseEntry dbEntry in this._dbConnection.ReadAllAsync(collection, cancel)) | ||
| { | ||
| yield return DataEntry.Create<TValue>(dbEntry.Key, dbEntry.Value, ParseTimestamp(dbEntry.Timestamp)); | ||
| } | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public async Task<DataEntry<TValue>?> GetAsync(string collection, string key, CancellationToken cancel = default) | ||
| { | ||
| DatabaseEntry? entry = await this._dbConnection.ReadAsync(collection, key, cancel); | ||
| if (entry.HasValue) | ||
| { | ||
| DatabaseEntry dbEntry = entry.Value; | ||
| return DataEntry.Create<TValue>(dbEntry.Key, dbEntry.Value, ParseTimestamp(dbEntry.Timestamp)); | ||
| } | ||
|
|
||
| return null; | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public async Task<DataEntry<TValue>> PutAsync(string collection, DataEntry<TValue> data, CancellationToken cancel = default) | ||
| { | ||
| await this._dbConnection.InsertAsync(collection, data.Key, data.ValueString, ToTimestampString(data.Timestamp), cancel); | ||
| return data; | ||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public Task RemoveAsync(string collection, string key, CancellationToken cancel = default) | ||
| { | ||
| return this._dbConnection.DeleteAsync(collection, key, cancel); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. | ||
| /// </summary> | ||
| public void Dispose() | ||
| { | ||
| // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method | ||
| this.Dispose(disposing: true); | ||
| GC.SuppressFinalize(this); | ||
| } | ||
|
|
||
| #region protected ================================================================================ | ||
|
|
||
| /// <summary> | ||
| /// Performs dispose specifically on the SqliteConnection | ||
| /// </summary> | ||
| protected virtual void Dispose(bool disposing) | ||
| { | ||
| if (!this._disposedValue) | ||
| { | ||
| if (disposing) | ||
| { | ||
| this._dbConnection.Dispose(); | ||
| } | ||
|
|
||
| this._disposedValue = true; | ||
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Constructor | ||
| /// </summary> | ||
| /// <param name="dbConnection">DB connection</param> | ||
| protected SqliteDataStore(SqliteConnection dbConnection) | ||
| { | ||
| this._dbConnection = dbConnection; | ||
| } | ||
|
|
||
| #endregion | ||
|
|
||
| #region private ================================================================================ | ||
|
|
||
| private readonly SqliteConnection _dbConnection; | ||
| private bool _disposedValue; | ||
|
|
||
| /// <summary> | ||
| /// Convert timestamp to string | ||
| /// </summary> | ||
| private static string? ToTimestampString(DateTimeOffset? timestamp) | ||
| { | ||
| return timestamp?.ToString("u", CultureInfo.InvariantCulture); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Convert string to timestamp | ||
| /// </summary> | ||
| private static DateTimeOffset? ParseTimestamp(string? str) | ||
| { | ||
| if (!string.IsNullOrEmpty(str) | ||
| && DateTimeOffset.TryParse(str, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out DateTimeOffset timestamp)) | ||
| { | ||
| return timestamp; | ||
| } | ||
|
|
||
| return null; | ||
| } | ||
|
|
||
| #endregion | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.