Goals of this design:
Keep plumbing/routing to a minimum
Write as little code as possible to get items from the database
Keep the class as clean as possible, datamembers for the class and functions for the class
Let's start with an example of a table with stock portfolio balances.
To start with create these classes -
1) database.js
2) portfoliorepository.js
3) portfolio.js
Portfolio.js
First this is your class that does stuff! It has member variables, functions. What we want to do is add a special category for database variables. These can be treated as private if you like. They will represent what columns are in the database and will hold values to be written.Ex:
function PortfolioBalance() { this.db = { LoginName: "", Date: "", CashBalance: 0, CashPortfolioPercent: 0, PreviousCashPortfolioPercent: 0, ReturnRate: 0.0, StocksPercent: "", StocksQuantity: "", TotalPortfolioValue: "", TradesForDay: "" }; //non database variables go here var parent = this; //class functions go here }
PortfolioRepository.js
Here is where stuff starts to get cool! The repository will only and should only be functions that query dynamoDB for data results. When the data gets returned we will use a function in database.js to create a list of 1 or more portfolio classes and return that. DO NOT add any other functions related to the class here! Also, do not create constructors for portfolio! As far as we are concerned, PortfolioBalance.db is the contract and all we need to populate portfolio balance. We can write a generic function in database.js to do this.
Ex:
var getPortfolioBalanceForUserOnDate = function ( loginName, date, callback ) { var search = { TableName: exports.table.Name, KeyConditions: { "LoginName": { "AttributeValueList": [{ "S": loginName }], "ComparisonOperator": "EQ" }, }, Limit: 1, ProjectionExpression: "#a,#b,#c,#d", ExpressionAttributeNames: { "#a": "StocksPercent", "#b": "CashPortfolioPercent", "#c" : "Date", "#d" : "PreviousCashPortfolioPercent"} }; databaseLib.query( search, function( data, err ) { var objects = databaseLib.convertToObjects( data, err, function() { return new PortfolioBalance(); } ); callback( objects, err ) ; }); };
Alright excitement level right now is 8/10. I will make that 10 on the next step. You can see this code deals with all your non-pretty dynamo db query stuff. That's all it should have and when it gets back a json result, that gets converted to a pretty list of PortfolioBalance() objects.
Database.js
Okay now we need some magic here to generate the classes.For the convertToObjects( data, err, function() { return new PortfolioBalance(); } )
the code might be similar to follows ->
var initalizeObject = function ( object, dataItem ) { var itemsToFill = Object.keys(object.db); //this still needs to look for M/N/L and do the conversion! for ( var index = 0; index < itemsToFill.length; index++ ) { object.db[itemsToFill[index]] = dataItem[itemsToFill[index]]; } }; var convertToObjects = function( data, err, creationFunction ) { if ( err ) { return null; } var objects = []; for ( var index = 0; index < data.Items.length; index++ ) { var newObject= creationFunction(); //create a new class object initalizeObject( newObject, data.Items[index] ); //initialize the class object based on the db member, and row from database objects.push( newObject); } return objects; };
Some points here -> We are using object.db or portfoliobalance.db as a contract on what to grab from the query results. The code above does a straight copy meaning you will get myvalue: { n: 0 } or all the data type values amazon gives you. I am working on stripping these out in my database class inteligently so my class is as clean as possible. Also note, since object.db or portfolioBalance.db is a contract, we could also validate that the dataItem contains all expected keys!
I may update this in the future with more code as I work on it, so hit me up in the comments if you are interested in more final code!
No comments:
Post a Comment