diff --git a/changes.md b/changes.md index 6022175..a576015 100644 --- a/changes.md +++ b/changes.md @@ -16,3 +16,8 @@ #### June 21, 2024 - Implement versioning folders to maintain access to history. + +#### June 22, 2024 + +- Code cleanup - removed unused artifacts and completed documentation. +- Implemented StorageItem class. diff --git a/v1/js/itemStore.js b/v1/js/itemStore.js index caca675..d85c9cc 100644 --- a/v1/js/itemStore.js +++ b/v1/js/itemStore.js @@ -40,6 +40,7 @@ export class ItemStore { let id = Date.now(); return id; } + /******************************************************************** * Finds item by id. *******************************************************************/ diff --git a/v2/index.html b/v2/index.html index dbd0477..6f7ab76 100644 --- a/v2/index.html +++ b/v2/index.html @@ -19,6 +19,10 @@
+ diff --git a/v2/js/app.js b/v2/js/app.js index 5ff7965..85d832f 100644 --- a/v2/js/app.js +++ b/v2/js/app.js @@ -1,60 +1,69 @@ -// App Interface (MVC). - -/* -The model class can be imported for a type driven UI, but this is optional. -The datastore does not use model properties for persistence. -All items are added to an item collection. -The item collection is persisted as a JSON array, regardless of the persistence type selected. -*/ +// Bookshelf App Interface (MVC). + +/************************************************************************************ + * The model class can be imported for a type driven UI, but this is optional. + * The datastore does not use model properties for persistence. + * All items are added to an item collection. + * The item collection is persisted as a JSON array, regardless of the persistence type selected. + ***********************************************************************************/ import { Book } from "./book.js"; -/* -The ItemStore module is required to manage the collection. -The DatabaseSettings module is required to override the default persistence settings. -See the example implementations below. -*/ +/************************************************************************************ + * The ItemStore module is required to manage the collection. + * The DatabaseSettings module is required to override the default persistence settings. + * See the example implementations below. + ************************************************************************************/ import { ItemStore } from "./itemStore.js"; -/* -Persistence types is an enum of the browser supported persistence methods. -This module can be imported for strongly typed declarations but this is optional. -The persistence types can be passed directly as strings. -*/ +/************************************************************************************* + * Persistence types is an enum of the browser supported persistence methods. + * This module can be imported for strongly typed declarations but this is optional. + * The persistence types can be passed directly as strings. + ************************************************************************************/ import { PersistenceTypes } from "./services/dataService.js"; -/*************************************************************************************** -Use this declaration to create a item store to manage the collection using default settings. -The collection will be in memory only and deleted upon page refresh or when the browser window is closed. -****************************************************************************************/ +/************************************************************************************* + * The DatabaseSettings class can be used to override the default persistence settings. + * Properties such as database name, key field, and persistence type can all be + * customized using valid options. + *************************************************************************************/ +import { DatabaseSettings } from "./services/databaseSettings.js"; +/************************************************************************************* + * Use this declaration to create a item store to manage the collection + * using default settings. + * The collection will be in memory only and deleted upon page refresh or + * when the browser window is closed. + ************************************************************************************/ //const bookDepot = new ItemStore(); /************************************************************************************* -Use this declaration to create a item store to manage the collection without persistence. -When the usePersistenceStore parameter is set to false, -the collection will be in memory only and deleted upon page refresh or when the browser window is closed. -*************************************************************************************/ - + * Use this declaration to create a item store to manage the collection without persistence. + * When the usePersistenceStore parameter is set to false, + * the collection will be in memory only and deleted upon page refresh or + * when the browser window is closed. + *************************************************************************************/ //const bookDepot = new ItemStore("MyBookStore", false); -/************************************************************************************* -Use this declaration to create an item store to manage the collection with default persistence settings. -This implementation will use cookie storage by default. -The collection will be stored with the browser's cookie until the cookie expires or is deleted. -**************************************************************************************/ - -const bookDepot = new ItemStore("MyBookStore", true); - /************************************************************************************** -An instace of the DatabaseSettings module is required to override the default settings. -Settings such as the database name, database version, table name, as well as key field can be overridden. -This is also where the persistence type can be changed from cookie storage to another option. -This code is ignored when the ItemStore.usePersistence property is set to false. -***************************************************************************************/ + * Use this declaration to create an item store to manage the collection with + * default persistence settings. + * This implementation will use cookie storage by default. + * The collection will be stored with the browser's cookie until the cookie expires or + * is deleted. + **************************************************************************************/ +const bookDepot = new ItemStore("MyBookStore", true); -//Initialize the persistence store by passing in database settings. +/*************************************************************************************** + * An instace of the DatabaseSettings module is required to override the default settings. + * Settings such as the database name, database version, table name, as well as key field + * can be overridden. + * This is also where the persistence type can be changed from cookie storage to another option. + * This code is ignored when the ItemStore.usePersistence property is set to false. + ***************************************************************************************/ + +//Initialize the data store by passing in a DatabaseSettings object. //The persistence types enum can be used for a strongly typed list of supported types. -import { DatabaseSettings } from "./services/databaseSettings.js"; let databaseSettings = new DatabaseSettings( "MyBookStore", 1, @@ -64,12 +73,14 @@ let databaseSettings = new DatabaseSettings( ); bookDepot.initializeDataStore(databaseSettings); -/**************************************************************************************/ - -// new page title +/************************************************************************************** + * New page title + **************************************************************************************/ const pageTitle = "Javascript - Bookshelf"; -// HTML markup to display the book collection. +/*************************************************************************************** + * HTML markup to display the book collection. + ***************************************************************************************/ const markUp = "
" + "

Bookshelf

" + @@ -102,7 +113,9 @@ const markUp = "" + ""; -// initialize the page. +/********************************************************************************** + * initialize the page. + **********************************************************************************/ (function () { // set page title document.title = pageTitle; @@ -135,9 +148,9 @@ const markUp = resetForm(); })(); -/* - Clear all form values. -*/ +/******************************************************************************** + * Clear all form values. + ********************************************************************************/ function resetForm() { // get all inputs var inputs = document.querySelectorAll( @@ -158,9 +171,10 @@ function resetForm() { // set focus on the first input document.getElementById("new-book-title").focus(); } -/* - Update book list display -*/ + +/*********************************************************************************** + * Update book list display + ***********************************************************************************/ function updateListDisplay() { // access the book container var bookList = document.getElementById("book-list"); @@ -254,9 +268,9 @@ function updateListDisplay() { } } -/* - Save a new book from the form values. This could be pushed back to the book depot, but I kind of like it sitting in this "controller". -*/ +/*************************************************************************************** + * Save a new book using form values. + ***************************************************************************************/ function saveBook() { // get values from the html input elements. let title = document.getElementById("new-book-title").value; @@ -296,9 +310,10 @@ function saveBook() { resetForm(); } -/* - Delete a book from the repository -*/ +/****************************************************************************************** + * Delete a book from the repository + * bookId|int: The id for the item to be deleted. + ******************************************************************************************/ function deleteBook(bookId) { // remove the book by id. var b = bookDepot.removeBookById(bookId); @@ -310,9 +325,10 @@ function deleteBook(bookId) { console.log(JSON.stringify(b)); } -/* - Update a single book -*/ +/****************************************************************************************** + * Update book. + * bookId|int: The id of the book to be updated. + ******************************************************************************************/ function updateBook(bookId) { // find the book to be updated var book = bookDepot.getBookById(bookId); @@ -324,18 +340,17 @@ function updateBook(bookId) { document.getElementById("new-book-id").value = book.id; } -/* - Output all of the contents of the repository object to the console. -*/ +/****************************************************************************************** + * Output the contents of the repository object to the console. + ******************************************************************************************/ function displayCollection() { // display the repository in the console. console.log(bookDepot); } -/* - Seed the repository with previously stored items if any. - Update the display. -*/ +/****************************************************************************************** + * Load any existing items from the repository and update the display. + ******************************************************************************************/ async function seedTheRepository() { bookDepot.books = await bookDepot.retrieve(); updateListDisplay(); diff --git a/v2/js/book.js b/v2/js/book.js index b572b89..a12a143 100644 --- a/v2/js/book.js +++ b/v2/js/book.js @@ -1,3 +1,9 @@ +/*********************************************************************** + * Book class + * Title|string: The book title. + * Author|string: The book's author. + * NumberOfPages|int: The number of pages in the book. + ***********************************************************************/ export class Book { constructor(title, author, numberOfPages) { this.id = 0; @@ -8,18 +14,24 @@ export class Book { this.modifiedOn = this.getDate(); } - // get current date as a locale string + /*********************************************************************** + * Gets current date as a locale string + ***********************************************************************/ getDate() { let today = new Date(); return today.toLocaleDateString(); } - // Returns book details to the. + /*********************************************************************** + * Returns|string: Book details. + ***********************************************************************/ getDetails() { return `${this.title} has ${this.numberOfPages} pages and was written by ${this.author}`; } - // returns the total number of pages in the book. + /*********************************************************************** + * Returns|int: The total number of pages in the book. + ***********************************************************************/ totalPages() { return this.numberOfPages; } diff --git a/v2/js/itemStore.js b/v2/js/itemStore.js index efaf5f9..5a62f5a 100644 --- a/v2/js/itemStore.js +++ b/v2/js/itemStore.js @@ -1,31 +1,39 @@ -/* - This class is a middleware controller for storing and executing changes on a collection (array) of book objects. - Dependencies: - DataContext|dataService.js - provides browser persistence via various browser persistence methods. - Book|book.js - the class definition for book objects that will be stored. - GoogleService|googleService.js - provides search services for Google Books API to allow importing titles to the collection. -*/ - -//import dependency modules. +/*********************************************************************** + * This class is a middleware controller for storing and executing + * changes on a collection (array) of book objects. + * Dependencies: + * DataContext|dataService.js - provides browser persistence via various browser persistence methods. + * Book|book.js - the class definition for book objects that will be stored. + ***********************************************************************/ + +/*********************************************************************** + * Import object type to be stored. + ***********************************************************************/ +import { Book } from "./book.js"; -//import backend dataservices if persistence is needed. +/*********************************************************************** + * Import backend dataservices if persistence is needed. + ***********************************************************************/ import { DataContext, PersistenceTypes } from "./services/dataService.js"; -//import database settings class to capture database settings for persistence. +/*********************************************************************** + * import DatabaseSettings class to capture database settings for persistence. + ***********************************************************************/ import { DatabaseSettings } from "./services/databaseSettings.js"; -//import object type to be stored. -import { Book } from "./book.js"; - -// import exception classes +/*********************************************************************** + * Import custom exception classes + ***********************************************************************/ import { PersistenceServiceNotEnabled, DataServiceUnavailable, } from "./services/exceptions.js"; -// not yet implemented -import { GoogleService } from "./services/googleService.js"; - +/*********************************************************************** + * Class definition + * Name|string: The name of the item store. + * UsePersistenceService|bool: Whether or not persistence should be enabled. + ***********************************************************************/ export class ItemStore { constructor(name, usePersistenceService) { this.name = name || "MyItemStore"; @@ -35,7 +43,7 @@ export class ItemStore { this.dataServiceProperties = null; this.databaseDefaults = { - databaseName: "ItemStore", + databaseName: this.name || "ItemStore", databaseVersion: 1, objectStoreName: "Items", keyPathField: "id", @@ -48,6 +56,10 @@ export class ItemStore { } } + /*********************************************************************** + * Initializes the database using the DatabaseSettings object. + * DatabaseSettings|object: Class containing values for database options. + ***********************************************************************/ initializeDataStore(databaseSettings) { if (this.usePersistenceService) { let settings = {}; @@ -97,25 +109,44 @@ export class ItemStore { } } + /*********************************************************************** + * Sets/Resets the name of the item store. + * Name|string: The name of the item store. + ***********************************************************************/ name(name) { this.name = name; } + /*********************************************************************** + * Returns the collection of items. + ***********************************************************************/ getBooks() { return this.books; } + /*********************************************************************** + * Generates an id based on the timestamp. + ***********************************************************************/ generateId() { let id = Date.now(); return id; } - getBookById(bookId) { - bookId = parseInt(bookId); - let book = this.books.find((b) => b.id == bookId); + /*********************************************************************** + * Finds an item by its Id. + * Returns: An item from the collection. + * Id|Int: The id of the item. + ***********************************************************************/ + getBookById(id) { + id = parseInt(id); + let book = this.books.find((b) => b.id == id); return book; } + /*********************************************************************** + * Adds a new item to the collection. + * Book|object: The item that will be added to the collection. + ***********************************************************************/ addBook(book) { // parse book id book.id = book.id == 0 ? this.generateId() : book.id; @@ -134,6 +165,10 @@ export class ItemStore { return this.log(book, ` ${book.title} has been added.`); } + /*********************************************************************** + * Updates an item in the collection. + * Book|object: The item that will be updated. + ***********************************************************************/ updateBook(book) { // remove the existing intance of the book this.removeBook(book); @@ -152,6 +187,10 @@ export class ItemStore { return this.log(book, ` ${book.title} has been updated.`); } + /*********************************************************************** + * Removes an item from the collection. + * Book|object: The item that will be removed. + ***********************************************************************/ removeBook(book) { // find the existing book book.id = parseInt(book.id); @@ -169,10 +208,14 @@ export class ItemStore { return this.log(book, ` ${book.title} has been removed.`); } - removeBookById(bookId) { + /*********************************************************************** + * Removes an item from the collection. + * Id|int: The id of the item that will be removed. + ***********************************************************************/ + removeBookById(id) { // find the existing book - bookId = parseInt(bookId); - let b = this.books.find((item) => item.id == bookId); + id = parseInt(id); + let b = this.books.find((item) => item.id == id); //filter the book from the array. this.books = this.books.filter((o) => o.id !== b.id); @@ -180,7 +223,7 @@ export class ItemStore { // sort the remaining books by title. this.sort(); - //this method takes an integer (bookId) and not an object. + //this method takes an integer (id) and not an object. //create an instance of the book to get access to methods. let b2 = new Book(b.title, b.author, b.numberOfPages); @@ -191,9 +234,9 @@ export class ItemStore { return this.log(b2, ` ${b2.title} has been removed by ID.`); } - /* - Sort the array by book title. - */ + /*********************************************************************** + * Sorts the collection by title. + ***********************************************************************/ sort() { let sorted = this.books.sort((a, b) => { if (a.title < b.title) { @@ -209,9 +252,11 @@ export class ItemStore { this.books = sorted; } - /* - Logs activity to the console - */ + /*********************************************************************** + * Logs activity to the console. + * Book|object: The item that has been modified. + * Message|string: The message to display. + ***********************************************************************/ log(book, message) { // log details of the book. console.log(book.getDetails()); @@ -223,26 +268,9 @@ export class ItemStore { return { book, message }; } - /* - NOT YET IMPLEMENTED - Search Google Books for a title. - */ - async search(term) { - let result = {}; - try { - let googleService = new GoogleService(); - result = await googleService.search(term); - return result; - } catch (e) { - console.log(e); - result.Error = "Service unavailable"; - return result; - } - } - - /* - Save book collection (array) to a cookie or indexedDB. - */ + /*********************************************************************** + * Saves the collection to storage. + ***********************************************************************/ async persist() { if (this.usePersistenceService) { // if the data service doesn't exist, try to create one. @@ -267,9 +295,9 @@ export class ItemStore { return this.books; } - /* - Retrieve book collection from cookie or indexedDB. - */ + /*********************************************************************** + * Retrieves the collection from storage. + ***********************************************************************/ async retrieve() { if (this.usePersistenceService) { // if the data service does not exist, create it. @@ -287,9 +315,10 @@ export class ItemStore { return this.books; } - /* - Create an instance of the data service to manage persistence. - */ + /*********************************************************************** + * Creates an instance of the data context to manage persistence. + * DatabaseProperties|object: Class containing values for database options. + ***********************************************************************/ getDataStore(databaseProperties) { if (this.usePersistenceService) { // create a new instance of the data service and return it. diff --git a/v2/js/services/cookieService.js b/v2/js/services/cookieService.js index 2a9f39c..e4aecd6 100644 --- a/v2/js/services/cookieService.js +++ b/v2/js/services/cookieService.js @@ -1,8 +1,19 @@ +/******************************************************************** + * Import StorageItem class for a strongly typed storage object. + ********************************************************************/ import { StorageItem } from "./storageItem.js"; +/************************************************************************************ + * Wrapper class used to work with document.cookie. + ************************************************************************************/ export class CookieService { constructor() {} + /************************************************************************************ + * Creates/updates a document cookie. + * CookieName|string: The name of the cookie. + * CookieData|string: The value to be stored. + ************************************************************************************/ save(cookieName, cookieData) { //TODO: validate size of cookie. // if it is too large, fall back to indexedDB and log a message. @@ -14,18 +25,27 @@ export class CookieService { }; cookieStore.set(cookie); } + + /************************************************************************************ + * Gets a document.cookie value. + * CookieName|string: The name of the cookie that will be retrieved. + ************************************************************************************/ retrieve(cookieName) { - let data = null; + let item = null; let cookieData = document.cookie .split("; ") .find((row) => row.startsWith(`${cookieName}=`)) ?.split("=")[1]; if (cookieData != null && cookieData.length > 0) { - data = cookieData; + item = new StorageItem(cookieName, cookieData); } - return data; + return item; } + + /************************************************************************************ + * Deletes a document cookie. + * CookieName|string: The name of the cookie tha will be deleted. + ************************************************************************************/ remove(cookieName) {} - clear(cookieName) {} } diff --git a/v2/js/services/dataService.js b/v2/js/services/dataService.js index 63cb1da..038afa8 100644 --- a/v2/js/services/dataService.js +++ b/v2/js/services/dataService.js @@ -1,29 +1,46 @@ -/* - Service provider to manage storing collections to an indexedDB instance or cookie. -*/ - +/************************************************************************************* + * Service provider to manage storing values to various data stores using custom + * services. + *************************************************************************************/ + +/************************************************************************************* + * Import the SessionStorage service in order to persist to window.sessionStorage. + ************************************************************************************/ import { SessionStorageService } from "./sessionStorageService.js"; + +/************************************************************************************* + * Import the LocalStorage service in order to persist to window.localStorage. + ************************************************************************************/ import { LocalStorageService } from "./localStorageService.js"; -import { CookieService } from "./cookieService.js"; -//var indexedDBServer = new Worker("./indexedDBService.js"); +/************************************************************************************* + * Import the CookieStorage service in order to persist to document.cookie. + ************************************************************************************/ +import { CookieService } from "./cookieService.js"; -// IndexedDB transaction modes. -export const TransactionModes = { - Read: "readonly", - ReadWrite: "readwrite", - Flush: "readwriteflush", -}; +/************************************************************************************* + * Import StorageItem class for a strongly typed storage object. + ************************************************************************************/ +import { StorageItem } from "./storageItem.js"; -// Persistence types. +/************************************************************************************* + * PeristenceTypes provides a strongly typed interface to the types of persistence + * services that are available to the application. + ************************************************************************************/ export const PersistenceTypes = { Cookie: "cookie", - IndexedDB: "indexeddb", SessionStorage: "session", LocalStorage: "localstorage", - BlockChain: "blockchain", }; +/************************************************************************************* + * The DataContext class definition. + * persistenceType: The persistenceType to be used for storage. + * databaseName: The name for the database. + * databaseVersion: The version of the database to be used. + * objectStoreName: The name of the specific object store being used. + * keyPathField: The object's field or property that will be used for key values. + ************************************************************************************/ export class DataContext { constructor( persistenceType, @@ -42,95 +59,33 @@ export class DataContext { this._iterator = 0; } - // Create a new indexedDB database. - async initializeIndexDB() { - let request = await indexedDB.open( - this._databaseName, - this._databaseVersion - ); - request.onupgradeneeded = (e) => { - this._database = e.target.result; - - try { - // Create an objectStore - this._database - .createObjectStore(this._objectStoreName, { - keyPath: this._keyPathField, - }) - .createIndex("by_id", "id", { unique: true }); - } catch (e) { - console.log(e); - } - }; - - request.onsuccess = (e) => { - this._database = e.target.result; - this._database.onversionchange = () => { - this._database.close(); - console.log("version changed."); - }; - }; - - request.onerror = (e) => { - // Handle errors. - console.log(e); - }; - request.onblocked = (e) => { - this._database.close(); - }; - } - - //Retrieve data from persistence layer and return an array. + /************************************************************************************* + * Retrieves data from persistence layer and returns an array. + ************************************************************************************/ async retrieve() { let data = []; + let storageItem = new StorageItem(); switch (this._persistenceType) { //retrieve from cookie service case PersistenceTypes.Cookie: let cookieService = new CookieService(); - let cookieData = cookieService.retrieve(this._databaseName); - if (cookieData !== null && cookieData.length > 0) { - data = JSON.parse(cookieData); - } - break; - - //retrieve from indexedDB service - case PersistenceTypes.indexedDB: - if (typeof this._database === "undefined" || this._database === null) { - this.initializeIndexDB(); - } - - let transaction = await this._database.transaction( - this._objectStoreName, - TransactionModes.Read - ); - - let objectStore = await transaction.objectStore(this._objectStoreName); - objectStore.openCursor().onsuccess = (e) => { - const cursor = e.target.result; - if (cursor) { - data.push(cursor.value); - cursor.continue(); - } - }; + storageItem = cookieService.retrieve(this._databaseName); + if (storageItem != null) data = JSON.parse(storageItem.Value); break; //retrieve from localStorage service case PersistenceTypes.LocalStorage: var localStorageService = new LocalStorageService(); - var items = localStorageService.retrieve(this._databaseName); - data = JSON.parse(items); + storageItem = localStorageService.retrieve(this._databaseName); + if (storageItem != null) data = JSON.parse(storageItem.Value); break; //retrieve from sessionStorage service case PersistenceTypes.SessionStorage: var sessionStorageService = new SessionStorageService(); - var items = sessionStorageService.retrieve(this._databaseName); - data = JSON.parse(items); - break; - - //retrieve from blockchain service - case PersistenceTypes.BlockChain: + storageItem = sessionStorageService.retrieve(this._databaseName); + if (storageItem != null) data = JSON.parse(storageItem.Value); break; default: @@ -139,72 +94,40 @@ export class DataContext { return data; } - //Retrieves data from persistence store and returns an array. - //DatabaseProperties - The properties collection that defines the data and how it is stored. + /************************************************************************************* + * Retrieves data from persistence store and returns an array. + * DatabaseProperties: The database settings to be used when storing the items. + ************************************************************************************/ async retrieve(databaseProperties) { let data = []; + let storageItem = new StorageItem(); switch (databaseProperties.persistenceType) { //retrieve from cookie service case PersistenceTypes.Cookie: let cookieService = new CookieService(); - let cookieData = cookieService.retrieve( - databaseProperties.databaseName - ); - if (cookieData !== null && cookieData.length > 0) { - data = JSON.parse(cookieData); - } - break; - - //retrieve from indexedDB service - case PersistenceTypes.IndexedDB: - if (typeof this._database === "undefined" || this._database === null) { - await this.initializeIndexDB(); - } - - try { - let transaction = await this._database - .transaction(databaseProperties.objectStoreName) - .objectStore(databaseProperties.objectStoreName); - - transaction.openCursor().onsuccess = (e) => { - let cursor = e.target.result; - if (cursor) { - data.push(cursor.value); - cursor.continue(); - } - }; - return data; - } catch (e) { - console.log(e); - } + storageItem = cookieService.retrieve(databaseProperties.databaseName); + if (storageItem != null) data = JSON.parse(storageItem.Value); break; //retrieve from LocalStorage service case PersistenceTypes.LocalStorage: var localStorageService = new LocalStorageService(); - var items = localStorageService.retrieve( + storageItem = localStorageService.retrieve( databaseProperties.databaseName ); - if (items !== null) { - data = JSON.parse(items); - } + if (storageItem != null) data = JSON.parse(storageItem.Value); break; //retrieve from sessionStorage service case PersistenceTypes.SessionStorage: var sessionStorageService = new SessionStorageService(); - var items = sessionStorageService.retrieve( + storageItem = sessionStorageService.retrieve( databaseProperties.databaseName ); - if (items !== null) { - data = JSON.parse(items); - } + if (storageItem != null) data = JSON.parse(storageItem.Value); break; - //retrieve from blockchain service - case PersistenceTypes.BlockChain: - break; default: break; } @@ -212,8 +135,10 @@ export class DataContext { return data; } - // Saves items to the data store based on properties set in service initialization. - // Items-the array of objects to be saved to the data store. + /************************************************************************************* + * Saves items to the data store based on properties set in service initialization. + * Items: The array of objects or values to be stored. + ************************************************************************************/ async persist(items) { switch (this._persistenceType) { //persist to Cookie service @@ -223,25 +148,6 @@ export class DataContext { cookieService.save(this._databaseName, cookieData); break; - //persist to IndexedDB service. - case PersistenceTypes.indexedDB: - if (typeof this._database === "undefined" || this._database === null) { - await this.initializeIndexDB(); - } - let transaction = await this._database.transaction( - this._objectStoreName, - TransactionModes.ReadWrite - ); - transaction.oncomplete = (e) => {}; - transaction.onerror = (e) => {}; - - let objectTable = await transaction.objectStore(this._objectStoreName); - - for (i = 0; i <= items.length; i++) { - let request = await objectTable.put(items[i]); - } - break; - //persist to LocalStorage service case PersistenceTypes.LocalStorage: var localStorageService = new LocalStorageService(); @@ -254,17 +160,16 @@ export class DataContext { sessionStorageService.save(this._database, JSON.stringify(items)); break; - //persist to blockchain service - case PersistenceTypes.BlockChain: - break; default: break; } } - // Saves items to the data store based on database properties object that is passed in. - // PersistenceType|Cookie: Convert array to JSON string and store it in a cookie. - // PersistenceType|IndexedDB: Add each element in the array to the database. + /************************************************************************************* + * Saves items to the data store based on database properties object that is passed in. + * DatabaseProperties: The database settings to be used when storing the items. + * Items: The array of objects or values to be stored. + ************************************************************************************/ async persist(databaseProperties, items) { switch (databaseProperties.persistenceType) { //persist to Cookie service @@ -274,25 +179,6 @@ export class DataContext { cookieService.save(databaseProperties.databaseName, cookieData); break; - //persist to IndexedDB service. - case PersistenceTypes.indexedDB: - if (typeof this._database === "undefined" || this._database === null) { - this.initializeIndexDB(); - } - const transaction = await this._database.transaction( - databaseProperties.objectStoreName, - TransactionModes.ReadWrite - ); - - const objectStore = await transaction.objectStore( - databaseProperties.objectStoreName - ); - - for (var i = 0; i < items.length; i++) { - const request = await objectStore.put(items[i]); - } - break; - //persist to LocalStorage service case PersistenceTypes.LocalStorage: var localStorageService = new LocalStorageService(); @@ -311,9 +197,6 @@ export class DataContext { ); break; - //persist to blockchain service - case PersistenceTypes.BlockChain: - break; default: break; } diff --git a/v2/js/services/databaseSettings.js b/v2/js/services/databaseSettings.js index f08d3f6..3575d45 100644 --- a/v2/js/services/databaseSettings.js +++ b/v2/js/services/databaseSettings.js @@ -1,6 +1,11 @@ -/* - Persistence store class with default property values. These property values can be overwritten by constructor values. -*/ +/************************************************************************************* + * Persistence store class with default property values which can be overwritten by constructor values. + * DatabaseName|string: The name of the database. + * DatabaseVersion|int: The version of the database being used. + * TableName|string: The name of the table used to store data. + * KeyPathField|string: The name of the field/property used to store key values. + * PersistenceType|string: The type of persistence used to store data. + ************************************************************************************/ export class DatabaseSettings { constructor( databaseName, diff --git a/v2/js/services/exceptions.js b/v2/js/services/exceptions.js index 2f766bd..fbccbea 100644 --- a/v2/js/services/exceptions.js +++ b/v2/js/services/exceptions.js @@ -1,23 +1,32 @@ "use strict"; +/************************************************************************ + * Custom exceptions file. + * Allows for custom exception messages that are specific + * to the application. + ***********************************************************************/ -// export class Exceptions { -// constructor() { -// this.PersistenceServiceNotEnabled.prototpe = Error.prototype; -// } -// PersistenceServiceNotEnabled(message = "") { -// this.message = message; -// this.name = "PersistenceServiceNotEnabled"; -// } -// } - +/************************************************************************ + * Provides PersistenceServiceNotEnabled error information when thrown. + * Message|string: The specific error message is set at the location of the error. + ************************************************************************/ export function PersistenceServiceNotEnabled(message = "") { this.message = message; this.name = "PersistenceServiceNotEnabled"; } + +// The custom exception must be attached to the Error prototype object +// in order to be recognized by the runtime PersistenceServiceNotEnabled.prototpe = Error.prototype; +/************************************************************************ + * Provides DataServiceUnavailable error information when thrown. + * Message|string: The specific error message is set at the location of the error. + ************************************************************************/ export function DataServiceUnavailable(message = "") { this.name = "DataServiceUnavailable"; this.message = message; } + +// The custom exception must be attached to the Error prototype object +// in order to be recognized by the runtime DataServiceUnavailable.prototype = Error.prototype; diff --git a/v2/js/services/googleService.js b/v2/js/services/googleService.js deleted file mode 100644 index ed28f07..0000000 --- a/v2/js/services/googleService.js +++ /dev/null @@ -1,52 +0,0 @@ -"use strict"; - -// NOT YET IMPLEMENTED -// Google Service to search Google Books and provide info on titles. -//import { GoogleConfigurationOptions } from "./googleConfiguration.js"; - -//Placeholder class for implementation. -class GoogleConfigurationOptions { - constructor() { - this.APIKeys = { - GoogleBooks: "xxxxxxxxxxxxxxxxxxxx", - }; - } -} - -export class GoogleService { - constructor() { - this._apiKey = this.getAPIKey(); - this._baseURL = "https://www.googleapis.com/books/v1/volumes?q="; - this._querySuffix = `&key=${this._apiKey}`; - this._searchTerms = { - Title: "intitle", - Author: "inauthor", - Publisher: "inpublisher", - Subject: "subject", - ISBN: "isbn", - LCCN: "lccn", - OCLC: "oclc", - }; - } - - async search(term) { - searchTerm = `+${this._searchTerms.Title}`; - let fullURL = this._baseURL + term + searchTerm + this._querySuffix; - let result = ""; - - result = await restRequest(fullURL); - - return result; - } - - async restRequest(destination) { - let response = await fetch(destination); - const jsonResult = await response.json(); - return jsonResult; - } - - getAPIKey() { - var gco = new GoogleConfigurationOptions(); - return gco.APIKeys.GoogleBooks; - } -} diff --git a/v2/js/services/indexedDBService.js b/v2/js/services/indexedDBService.js deleted file mode 100644 index 1cd5e41..0000000 --- a/v2/js/services/indexedDBService.js +++ /dev/null @@ -1,5 +0,0 @@ -export class IndexedDBService { - constructor() {} -} - -var dbManager = new IndexedDBService(); diff --git a/v2/js/services/localStorageService.js b/v2/js/services/localStorageService.js index 182f4e9..235370d 100644 --- a/v2/js/services/localStorageService.js +++ b/v2/js/services/localStorageService.js @@ -1,33 +1,54 @@ +/******************************************************************** + * Import StorageItem class for a strongly typed storage object. + ********************************************************************/ import { StorageItem } from "./storageItem.js"; +/******************************************************************** + * Session storage wrapper to provide access to window.localStorage + * if it's available. + ********************************************************************/ export class LocalStorageService { constructor() { this._storageAvailable = this.storageAvailable("localStorage"); } - save(storageItemName, storageValue) { + /***************************************************************** + * Add an item to window.localStorage. + * StorageItemName|string: The name of the item being stored. + * StorageItemValue|object: The value being stored. + ****************************************************************/ + save(storageItemName, storageItemValue) { if (this._storageAvailable) { - let storageItem = new StorageItem(storageItemName, storageValue); - window.localStorage.setItem(storageItem.Name, storageItem.Value); + window.localStorage.setItem(storageItemName, storageItemValue); } else { console.log("Local storage is not available."); } } + /***************************************************************** + * Retrieve an item from window.localStorage. + * StorageItemName|string: The name of the item to be retrieved. + ****************************************************************/ retrieve(storageItemName) { - let item = new StorageItem(); + let item = null; if (this._storageAvailable) { if (storageItemName.length > 0) { - item = window.localStorage.getItem(storageItemName); + let storedValue = window.localStorage.getItem(storageItemName); + if (storedValue != null) { + item = new StorageItem(storageItemName, storedValue); + } } } else { console.log("Local storage is not available."); } - return item; } + /***************************************************************** + * Remove an item from window.localStorage. + * StorageItemName|string: The name of the item to be removed. + ****************************************************************/ remove(storageItemName) { if (this._storageAvailable) { if (storageItemName.length > 0) { @@ -38,6 +59,9 @@ export class LocalStorageService { } } + /***************************************************************** + * Clear all items from window.localStorage. + ****************************************************************/ clear() { if (this._storageAvailable) { window.localStorage.clear(); @@ -47,6 +71,9 @@ export class LocalStorageService { } /*********************************************************************************** + * Checks for window.localStorage or window.sessionStorage. + * Type|string: The name of the storage type being tested. + * Reference: * Storage avaialability test taken from MDN Web Docs * https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API ***********************************************************************************/ diff --git a/v2/js/services/sessionStorageService.js b/v2/js/services/sessionStorageService.js index 8424aea..69a4fa1 100644 --- a/v2/js/services/sessionStorageService.js +++ b/v2/js/services/sessionStorageService.js @@ -1,10 +1,22 @@ +/******************************************************************** + * Import StorageItem class for a strongly typed storage object. + ********************************************************************/ import { StorageItem } from "./storageItem.js"; +/******************************************************************** + * Session storage wrapper to provide access to window.sessionStorage + * if it's available. + ********************************************************************/ export class SessionStorageService { constructor() { this._storageAvailable = this.storageAvailable("sessionStorage"); } + /***************************************************************** + * Add an item to window.sessionStorage. + * StorageItemName|string: The name of the item being stored. + * StorageItemValue|object: The value being stored. + ****************************************************************/ save(storageItemName, storageItemValue) { if (this._storageAvailable) { window.sessionStorage.setItem(storageItemName, storageItemValue); @@ -13,12 +25,30 @@ export class SessionStorageService { } } + /***************************************************************** + * Retrieve an item from window.sessionStorage. + * StorageItemName|string: The name of the item to be retrieved. + ****************************************************************/ retrieve(storageItemName) { + let item = null; + if (this._storageAvailable) { - return window.sessionStorage.getItem(storageItemName); + if (storageItemName.length > 0) { + let storedValue = window.sessionStorage.getItem(storageItemName); + if (storedValue != null) { + item = new StorageItem(storageItemName, storedValue); + } + } + } else { + console.log("Session storage is not available."); } + return item; } + /***************************************************************** + * Remove an item from window.sessionStorage. + * StorageItemName|string: The name of the item to be removed. + ****************************************************************/ remove(storageItemName) { if (this._storageAvailable) { window.sessionStorage.removeItem(storageItemName); @@ -27,6 +57,9 @@ export class SessionStorageService { } } + /***************************************************************** + * Clear all items from window.sessionStorage. + ****************************************************************/ clear() { if (this._storageAvailable) { window.sessionStorage.clear(); @@ -35,7 +68,10 @@ export class SessionStorageService { } } - /*********************************************************************************** + /********************************************************************************** + * Checks for window.localStorage or window.sessionStorage. + * Type|string: The name of the storage type being tested. + * Reference: * Storage avaialability test taken from MDN Web Docs * https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API ***********************************************************************************/ diff --git a/v2/js/services/storageItem.js b/v2/js/services/storageItem.js index 84477ff..c022b6b 100644 --- a/v2/js/services/storageItem.js +++ b/v2/js/services/storageItem.js @@ -1,3 +1,8 @@ +/************************************************************************************* + * StorageItem class to be used with various storage types. + * Name|string: The name of the storage item. + * Value|object: The value to be stored. + ************************************************************************************/ export class StorageItem { constructor(name, value) { this.Name = name;