Coder Social home page Coder Social logo

dnetindexeddb's Introduction

master - .Net5 version

master_net31 - 3.x version

DnetIndexedDb

This is a Blazor library to work with IndexedDB DOM API. It allows query multiple IndexedDb databases simultaneously

The actual API expose the following methods:

  • Open and upgrade an instance of IndexedDB
  • Close an instance of IndexedDB
  • Delete an instance of IndexedDB
  • Add an item to a given store
  • Update an item in a given store
  • Delete an item from a store by key
  • Delete all items from a store
  • Retrieve all items from a given store
  • Retrieve an items by index
  • Retrieve a range of items by key
  • Retrieve a range of items by index

Compatibility *Server-side Blazor and client-side Blazor

Using the library

  1. Install the Nuget package DnetIndexedDb
  2. Add the following script reference to your Index.html after the blazor.webassembly.js reference: <script src="_content/DnetIndexedDb/rxjs.min.js"></script> <script src="_content/DnetIndexedDb/dnet-indexeddb.js"></script>
  3. create a new instance of IndexedDbDatabaseModel
  4. Create a derive class from IndexedDbInterop
  public class GridColumnDataIndexedDb : IndexedDbInterop
  {
    public GridColumnDataIndexedDb(IJSRuntime jsRuntime, IndexedDbOptions<GridColumnDataIndexedDb> options) 
    :base(jsRuntime, options)
    {
    }
  }
  1. Register your derive class in ConfiguredServices on Startup.cs. When register use options to add the IndexedDbDatabaseModel instance.
  services.AddIndexedDbDatabase<GridColumnDataIndexedDb>(options =>
  {
    options.UseDatabase(GetGridColumnDatabaseModel());
  });
  1. Inject the created instance of your derived class into the component or page.

Detailed configuration and use

Step 1 - Create the database model

To create the database model use the following classes. You can find more info about the IndexedDB database here: https://www.w3.org/TR/IndexedDB-2/#database-construct

IndexedDbDatabase IndexedDbDatabaseModel IndexedDbIndex IndexedDbStore IndexedDbStoreParameter

See the examples below:

    public class IndexedDbDatabaseModel
    {
      
        public string Name { get; set; }
     
        public int Version { get; set; }
      
        public List<IndexedDbStore> Stores { get; set; } = new List<IndexedDbStore>();

        public int DbModelId { get; set; }
    }
 var indexedDbDatabaseModel = new IndexedDbDatabaseModel
            {
                Name = "GridColumnData",
                Version = 1,
                Stores = new List<IndexedDbStore>
                {
                new IndexedDbStore
                {
                    Name = "tableField",
                    Key = new IndexedDbStoreParameter
                    {
                        KeyPath = "tableFieldId",
                        AutoIncrement = true
                    },
                    Indexes = new List<IndexedDbIndex>
                    {
                        new IndexedDbIndex
                        {
                            Name = "tableFieldId",
                            Definition = new IndexedDbIndexParameter
                            {
                                Unique = true
                            }
                        },
                        new IndexedDbIndex
                        {
                            Name = "attachedProperty",
                            Definition = new IndexedDbIndexParameter
                            {
                                Unique = false
                            }
                        },
                        new IndexedDbIndex
                        {
                            Name = "fieldVisualName",
                            Definition = new IndexedDbIndexParameter
                            {
                                Unique = false
                            }
                        }, new IndexedDbIndex
                        {
                            Name = "hide",
                            Definition = new IndexedDbIndexParameter
                            {
                                Unique = false
                            }
                        },
                        new IndexedDbIndex
                        {
                            Name = "isLink",
                            Definition = new IndexedDbIndexParameter
                            {
                                Unique = false
                            }
                        },
                        new IndexedDbIndex
                        {
                            Name = "memberOf",
                            Definition = new IndexedDbIndexParameter
                            {
                                Unique = false
                            }
                        },
                        new IndexedDbIndex
                        {
                            Name = "tableName",
                            Definition = new IndexedDbIndexParameter
                            {
                                Unique = false
                            }
                        },
                        new IndexedDbIndex
                        {
                            Name = "textAlignClass",
                            Definition = new IndexedDbIndexParameter
                            {
                                Unique = false
                            }
                        },
                        new IndexedDbIndex
                        {
                            Name = "type",
                            Definition = new IndexedDbIndexParameter
                            {
                                Unique = false
                            }
                        },
                        new IndexedDbIndex
                        {
                            Name = "width",
                            Definition = new IndexedDbIndexParameter
                            {
                                Unique = false
                            }
                        }
                    }
                }
            },
                DbModelId = 0
            };
Create database model by @Kylar182
    public class TableFieldDatabase : IndexedDbDatabaseModel
    {
        public TableFieldDatabase()
        {
            Name = "GridColumnData";
            Version = 1;
            Stores = _stores;
        }

        /// <summary>
        /// List of Object Stores
        /// </summary>
        private List<IndexedDbStore> _stores => new List<IndexedDbStore>
        {
            _tableFieldStore,
        };

        private IndexedDbStore _tableFieldStore => new TStore<TableFieldDto>();
    }
    
    public class TStore<T> : IndexedDbStore where T : class
    {
        private IndexedDbStoreParameter _key;

        private readonly List<IndexedDbIndex> _indexes = new List<IndexedDbIndex>();

        public TStore()
        {
            BuildStore();
            Name = typeof(T).Name.ToPlural();
            Key = _key;
            Indexes = _indexes;
        }

        private void BuildStore()
        {
            foreach (PropertyInfo info in typeof(T).GetProperties())
            {
                var classId = info.Name.Substring(info.Name.Length - 2);

                var classAttrs = info.GetCustomAttributes(true);

                var keyAttr = classAttrs.Select(p => p as KeyAttribute).FirstOrDefault();

                if (classId == "Id" || keyAttr != null)
                {
                    _key = new IndexedDbStoreParameter
                    {
                        KeyPath = info.Name.ToCamelCase(),
                        AutoIncrement = true
                    };
                }

                _indexes.Add(new IndexedDbIndex
                {
                    Name = info.Name.ToCamelCase(),
                    Definition = new IndexedDbIndexParameter { Unique = false }
                });
            }
        }
    }
Fluent DbModel Definition
using DnetIndexedDb.Fluent;
...
    services.AddIndexedDbDatabase<SecuritySuiteDataIndexedDb>(options =>
    {
        var model = new IndexedDbDatabaseModel()
            .WithName("Security")
            .WithVersion(1)
            .WithModelId(0);

        model.AddStore("tableFieldDtos")
            .WithAutoIncrementingKey("tableFieldId")
            .AddUniqueIndex("tableFieldId")
            .AddIndex("attachedProperty")
            .AddIndex("fieldVisualName")
            .AddIndex("hide")
            .AddIndex("isLink")
            .AddIndex("memberOf")
            .AddIndex("tableName")
            .AddIndex("textAlignClass")
            .AddIndex("type")
            .AddIndex("width");

        options.UseDatabase(model);
    });

Step 2 - Creating a service

You can create a service for any indexedDB's database that you want to use in your application. Use the base class IndexedDbInterop to create your derived class. See code below.

  public class GridColumnDataIndexedDb : IndexedDbInterop
  {
    public GridColumnDataIndexedDb(IJSRuntime jsRuntime, IndexedDbOptions<GridColumnDataIndexedDb> options) 
    :base(jsRuntime, options)
    {
    }
  }

This follows a similar pattern to what you do when you create a new DbContext in EF core.

Step 3 - Registering a service

You can use the AddIndexedDbDatabase extension method to register your service in ConfiguredServices on Startup.cs. Use the options builder to add the service Database. See code below.

  services.AddIndexedDbDatabase<GridColumnDataIndexedDb>(options =>
  {
    options.UseDatabase(GetGridColumnDatabaseModel());
  });

GetGridColumnDatabaseModel() return an instance of IndexedDbDatabaseModel

You can also use multiple database, declaring as many service as you want.

   services.AddIndexedDbDatabase<SecuritySuiteDataIndexedDb>(options =>
   {
     options.UseDatabase(GetSecurityDatabaseModel());
   });

Using the service in your application

To use IndexedDB service in a component or page first inject the IndexedDB servicer instance.

@inject GridColumnDataIndexedDb GridColumnDataIndexedDb

IndexedDB store are the equivalent of table in SQL Database. For the API demostrations will use the following class as our store model.

    public class TableFieldDto
    {
        public int TableFieldId { get; set; }

        public string TableName { get; set; }

        public string FieldVisualName { get; set; }

        public string AttachedProperty { get; set; }

        public bool IsLink { get; set; }

        public int MemberOf { get; set; }

        public int Width { get; set; }

        public string TextAlignClass { get; set; }

        public bool Hide { get; set; }

        public string Type { get; set; }
    }

API examples

Open and upgrade an instance of IndexedDB

ValueTask<int> OpenIndexedDb()

 var result = await GridColumnDataIndexedDb.OpenIndexedDb();

Add an items to a given store

ValueTask<TEntity> AddItems<TEntity>(string objectStoreName, List<TEntity> items)

 var result = await GridColumnDataIndexedDb.AddItems<TableFieldDto>("tableField", items);

Retrieve an item by key

ValueTask<TEntity> GetByKey<TKey, TEntity>(string objectStoreName, TKey key)

 var result = await GridColumnDataIndexedDb.GetByKey<int, TableFieldDto>("tableField", 11);

Delete an item from a store by key

ValueTask<string> DeleteByKey<TKey>(string objectStoreName, TKey key)

 var result = await GridColumnDataIndexedDb.DeleteByKey<int>("tableField", 11);

Retrieve all items from a given store

ValueTask<List<TEntity>> GetAll<TEntity>(string objectStoreName)

  var result = await GridColumnDataIndexedDb.GetAll<TableFieldDto>("tableField");

Retrieve a range of items by key

ValueTask<List<TEntity>> GetRange<TKey, TEntity>(string objectStoreName, TKey lowerBound, TKey upperBound)

   var result = await GridColumnDataIndexedDb.GetRange<int, TableFieldDto>("tableField", 15, 20);

Retrieve a range of items by index

ValueTask<List<TEntity>> GetByIndex<TKey, TEntity>(string objectStoreName, TKey lowerBound, TKey upperBound, string dbIndex, bool isRange)

    var result = await GridColumnDataIndexedDb.GetByIndex<string, TableFieldDto>("tableField", "Name", null, "fieldVisualName", false);

Update items in a given store

ValueTask<string> UpdateItems<TEntity>(string objectStoreName, List<TEntity> items)

    foreach (var item in items)
    {
        item.FieldVisualName = item.FieldVisualName + "Updated";
    }
   var result = await GridColumnDataIndexedDb.UpdateItems<TableFieldDto>("tableField", items);

Delete all items from a store

ValueTask<string> DeleteAll(string objectStoreName)

  var result = await GridColumnDataIndexedDb.DeleteAll("tableField");

Delete an instance of IndexedDB

ValueTask<string> DeleteIndexedDb()

  var result = await GridColumnDataIndexedDb.DeleteIndexedDb();

dnetindexeddb's People

Contributors

amuste avatar mcbride-clint avatar rebelweb avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.