Skip to content

feat: allow custom indexeddb database and store names #78

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

Merged
merged 1 commit into from
Feb 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { map, mergeMap, first, tap, filter } from 'rxjs/operators';

import { LocalDatabase } from './local-database';
import { LocalStorageDatabase } from './localstorage-database';
import { LOCAL_STORAGE_PREFIX } from '../tokens';
import { PREFIX, INDEXEDDB_NAME, DEFAULT_INDEXEDDB_NAME, INDEXEDDB_STORE_NAME, DEFAULT_INDEXEDDB_STORE_NAME } from '../tokens';

@Injectable({
providedIn: 'root'
Expand All @@ -14,15 +14,11 @@ export class IndexedDBDatabase implements LocalDatabase {
/**
* IndexedDB database name for local storage
*/
protected dbName = 'ngStorage';
protected dbName: string;
/**
* IndexedDB object store name for local storage
*/
protected readonly objectStoreName = 'localStorage';
/**
* IndexedDB key path name for local storage (where an item's key will be stored)
*/
protected readonly keyPath = 'key';
protected objectStoreName: string;
/**
* IndexedDB data path name for local storage (where items' value will be stored)
*/
Expand Down Expand Up @@ -67,13 +63,15 @@ export class IndexedDBDatabase implements LocalDatabase {
/**
* Connects to IndexedDB
*/
constructor(@Optional() @Inject(LOCAL_STORAGE_PREFIX) protected prefix: string | null = null) {
constructor(
@Optional() @Inject(PREFIX) prefix: string | null = null,
@Optional() @Inject(INDEXEDDB_NAME) dbName = DEFAULT_INDEXEDDB_NAME,
@Optional() @Inject(INDEXEDDB_STORE_NAME) storeName = DEFAULT_INDEXEDDB_STORE_NAME,
) {

if (prefix) {
this.dbName = prefix ? `${prefix}_${dbName}` : dbName;

this.dbName = `${prefix}_${this.dbName}`;

}
this.objectStoreName = storeName;

/* Creating the RxJS ReplaySubject */
this.database = new ReplaySubject<IDBDatabase>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Observable } from 'rxjs';
import { IndexedDBDatabase } from './indexeddb-database';
import { LocalStorageDatabase } from './localstorage-database';
import { MockLocalDatabase } from './mock-local-database';
import { LOCAL_STORAGE_PREFIX } from '../tokens';
import { PREFIX } from '../tokens';

export function localDatabaseFactory(platformId: Object, prefix: string | null) {

Expand Down Expand Up @@ -33,7 +33,7 @@ export function localDatabaseFactory(platformId: Object, prefix: string | null)
useFactory: localDatabaseFactory,
deps: [
PLATFORM_ID,
[new Optional(), LOCAL_STORAGE_PREFIX]
[new Optional(), PREFIX]
]
})
export abstract class LocalDatabase {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable, Optional, Inject } from '@angular/core';
import { Observable, of, throwError } from 'rxjs';

import { LocalDatabase } from './local-database';
import { LOCAL_STORAGE_PREFIX } from '../tokens';
import { PREFIX } from '../tokens';

@Injectable({
providedIn: 'root'
Expand All @@ -16,7 +16,7 @@ export class LocalStorageDatabase implements LocalDatabase {
return of(localStorage.length);
}

constructor(@Optional() @Inject(LOCAL_STORAGE_PREFIX) protected userPrefix: string | null = null) {
constructor(@Optional() @Inject(PREFIX) userPrefix: string | null = null) {

if (userPrefix) {
this.prefix = `${userPrefix}_`;
Expand Down
31 changes: 31 additions & 0 deletions projects/ngx-pwa/local-storage/src/lib/lib.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,23 @@ describe('LocalStorage with IndexedDB and a prefix', () => {

});

it('should have the wanted prefix with custom database and object store names', () => {

const prefix = 'myapp';
const dbName = 'customDb';

class IndexedDBDatabasePrefix extends IndexedDBDatabase {
getDbBame() {
return this.dbName;
}
}

const indexedDBService = new IndexedDBDatabasePrefix(prefix, dbName);

expect(indexedDBService.getDbBame()).toBe(`${prefix}_${dbName}`);

});

const localStorageService = new LocalStorage(new IndexedDBDatabase('myapp'), new JSONValidator());

beforeEach((done: DoneFn) => {
Expand All @@ -1047,6 +1064,20 @@ describe('LocalStorage with IndexedDB and a prefix', () => {

});

describe('LocalStorage with IndexedDB and a custom database and object store names', () => {

const localStorageService = new LocalStorage(new IndexedDBDatabase(null, 'dBcustom', 'storeCustom'), new JSONValidator());

beforeEach((done: DoneFn) => {
localStorageService.clear().subscribe(() => {
done();
});
});

tests(localStorageService);

});

describe('LocalStorage with automatic storage injection', () => {

it('should store and get the same value', (done: DoneFn) => {
Expand Down
73 changes: 70 additions & 3 deletions projects/ngx-pwa/local-storage/src/lib/tokens.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,82 @@
import { InjectionToken, Provider } from '@angular/core';

export const LOCAL_STORAGE_PREFIX = new InjectionToken<string>('localStoragePrefix', { providedIn: 'root', factory: () => '' });
/**
* Internal. Use the `localStorageProviders()` helper function to provide options.
*/
export const PREFIX = new InjectionToken<string>('localStoragePrefix', {
providedIn: 'root',
factory: () => ''
});

/**
* @deprecated Use the `localStorageProviders()` helper function to provide options.
*/
export const LOCAL_STORAGE_PREFIX = PREFIX;

/**
* Default name used for `indexedDb` database.
* *Use only for interoperability with other APIs.*
*/
export const DEFAULT_INDEXEDDB_NAME = 'ngStorage';

/**
* Internal. Use the `localStorageProviders()` helper function to provide options.
*/
export const INDEXEDDB_NAME = new InjectionToken<string>('localStorageIndexedDbName', {
providedIn: 'root',
factory: () => DEFAULT_INDEXEDDB_NAME
});

/**
* Default name used for `indexedDb` object store.
* *Use only for interoperability with other APIs.*
*/
export const DEFAULT_INDEXEDDB_STORE_NAME = 'localStorage';

/**
* Internal. Use the `localStorageProviders()` helper function to provide options.
*/
export const INDEXEDDB_STORE_NAME = new InjectionToken<string>('localStorageIndexedDbStoreName', {
providedIn: 'root',
factory: () => DEFAULT_INDEXEDDB_STORE_NAME
});

export interface LocalStorageProvidersConfig {

/** Optional prefix to avoid collision in multiple apps on same subdomain */
/**
* Optional prefix to avoid collision when there are *multiple apps on the same subdomain*
* (makes no sense in other scenarios). **Avoid special characters.**
* **WARNING: do not change this option in an app already deployed in production, as previously stored data would be lost.**
*/
prefix?: string;

/**
* Allows to change the name used for `indexedDb` database. **Avoid special characters.**
* *Use only for interoperability with other APIs or to avoid collision with other libs.*
* **WARNING: do not change this option in an app already deployed in production, as previously stored data would be lost.**
*/
indexedDbName?: string;

/**
* Allows to change the name used for `indexedDb` object store. **Avoid special characters.**
* *Use only for interoperability with other APIs or to avoid collision with other libs.*
* **WARNING: do not change this option in an app already deployed in production, as previously stored data would be lost.**
*/
indexedDbStoreName?: string;

}

/**
* Helper function to provide options. **Must be used at initialization, ie. in `AppModule`.**
* @param config Options.
* @returns A list of providers for the lib options.
*/
export function localStorageProviders(config: LocalStorageProvidersConfig): Provider[] {

return [
config.prefix ? { provide: LOCAL_STORAGE_PREFIX, useValue: config.prefix } : []
config.prefix ? { provide: PREFIX, useValue: config.prefix } : [],
config.indexedDbName ? { provide: INDEXEDDB_NAME, useValue: config.indexedDbName } : [],
config.indexedDbStoreName ? { provide: INDEXEDDB_STORE_NAME, useValue: config.indexedDbStoreName } : [],
];

}
5 changes: 4 additions & 1 deletion projects/ngx-pwa/local-storage/src/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ export { LocalStorageDatabase } from './lib/databases/localstorage-database';
export { MockLocalDatabase } from './lib/databases/mock-local-database';
export { JSONValidator } from './lib/validation/json-validator';
export { LSGetItemOptions, LocalStorage } from './lib/lib.service';
export { localStorageProviders, LocalStorageProvidersConfig, LOCAL_STORAGE_PREFIX } from './lib/tokens';
export {
localStorageProviders, LocalStorageProvidersConfig, LOCAL_STORAGE_PREFIX, PREFIX,
DEFAULT_INDEXEDDB_NAME, INDEXEDDB_NAME, DEFAULT_INDEXEDDB_STORE_NAME, INDEXEDDB_STORE_NAME
} from './lib/tokens';