Skip to content

Instantly share code, notes, and snippets.

@TrevorBasinger
Last active August 29, 2015 14:19
Show Gist options
  • Save TrevorBasinger/32c13fae49fc93d29c0c to your computer and use it in GitHub Desktop.
Save TrevorBasinger/32c13fae49fc93d29c0c to your computer and use it in GitHub Desktop.
/* jshint laxbreak: true, laxcomma: true */
/* Create a view using the following:
* create view {{resource}}_view as
* select * from {{resource}} r1
* where r1.inserted_at = (select r2.inserted_at from {{resource}} r2
* where r1.internalid = r2.internalid
* order by CAST(r2.inserted_at as UNSIGNED) desc limit 1);
*
*/
var R = require ('ramda'),
Future = require ('data.future'),
M = require ('control.monads'),
c = require ('../lib/helpers/common'),
ns = require ('../lib/netsuite'),
mysql = require ('../lib/drivers/mysql'),
log = console.log,
logI = function (x) { log (x); return x; },
id = function (x) { return x; },
konst = R.curry (function (a, b) { return a; }),
// [NSRecord]
employees = require ('./employees.json'),
// insertDate :: Record -> Record
insertDate = function (r) {
var record = R.clone (r);
if (record && record.columns) {
record.columns.inserted_at = new Date().getTime();
}
return record;
},
// pluckColumns :: Object -> Object
pluckColumns = R.prop ('columns'),
// pluckAndFlattenColumns :: Object -> Object
pluckAndFlattenColumns = R.compose (R.mapObj (ns.flatten), pluckColumns),
// evalColumnTypes :: [NSRecord] -> Object
evalColumnTypes = R.compose (R.mapObj (c.typeOf), R.mergeAll),
// buildCol :: String -> String -> String
buildCol = R.curry (function (name, type) {
return name + " " + type;
}),
// escapeColumns :: [String] -> [String]
escapeColumns = function (xs) {
var fst = "`" + (xs[0]) + "`",
snd = xs[1];
return [fst, snd];
},
// getBuildStrings :: [NSRecord] -> [String]
getBuildStrings = R.pipe ( R.map (insertDate)
, R.map (pluckAndFlattenColumns)
, evalColumnTypes
, R.mapObj (ns.str2type)
, R.toPairs
, R.map (escapeColumns)
, R.map (R.apply (buildCol)) ),
// prependPrimaryKey :: [String] -> [String]
prependPrimaryKey = R.prepend ('id INT PRIMARY KEY AUTO_INCREMENT'),
// surround :: String -> String -> String -> String
surround = R.curry (function (start, end, str) {
return R.join ('', R.prepend (start, R.append (end, str.toString())));
}),
// mkCreateTableStr :: String -> [NSRecord] -> String
mkCreateTableStr = R.curry (function (resource, records) {
var joinColStr = R.pipe ( getBuildStrings
, prependPrimaryKey
, R.join (', ')
, surround ('(', ')') );
return "CREATE TABLE "+ resource + " " + joinColStr (records);
}),
// mkSelectStr :: String -> Record -> String
mkSelectStr = R.curry (function (resource, record) {
var rec = pluckAndFlattenColumns (record),
keys = R.join (", ", R.keys (rec)),
stmt = "select " + keys + " from " + resource + '_view where ',
mkSelectFromRecord = R.pipe ( R.toPairs
, R.map (preparePairs)
, R.map (R.join (' = '))
, R.join (' and ')
, surround (stmt, '') );
return mkSelectFromRecord (rec);
}),
// mkInsertStr :: String -> Record -> String
mkInsertStr = R.curry (function (str, obj) {
var r = pluckAndFlattenColumns (obj);
return mysql.mkInsert (str, R.keys (r), [r]);
}),
// tableExists :: Conf -> String -> Future Boolean
tableExists = function (conf, name) {
return mysql.query (conf, 'SHOW TABLES LIKE ' + mysql.escape (name))
.map (R.compose (R.lt (0), R.length));
},
// exists :: Conf -> String -> Record -> Future Boolean
exists = function (conf, name, record) {
return mysql.query (conf, mkSelectStr (name, record))
.map (R.compose (R.lt (0), R.length));
},
// createTable :: Conf -> String -> [NSRecord] -> Future Unit
createTable = R.curry (function (conf, resource, resources) {
var str = mkCreateTableStr (resource, resources);
return mysql.query (conf, str).map (konst ({}));
}),
// insertRecord :: Conf -> String -> NSRecord -> Future Unit
insertRecord = R.curry (function (conf, resource, record) {
var str = mkInsertStr (resource, insertDate (record));
return mysql.query (conf, str)
.map (konst ({}));
}),
// branch :: a -> a -> Boolean -> a
branch = R.curry (function (b, a, bool) { return bool ? a : b; }),
// preparePairs :: [[
preparePairs = function (xs) {
var ys = escapeColumns (xs);
return [ys[0], mysql.escapeVals (ys[1])];
},
// selectiveInsert :: Conf -> String -> Record -> Future Unit
selectiveInsert = R.curry (function (conf, resource, record) {
var insertF = insertRecord (conf, resource, record);
return exists (conf, resource, record)
.chain (branch (insertF, Future.of ({})));
}),
nil = null;
(function main () {
var conf = 'mysql://localhost/test',
resource = 'employees';
insertFutures = R.map (selectiveInsert (conf, resource), employees);
tableExists (conf, resource)
// Create Table if doesn't exist
.chain (branch (createTable (conf, resource, employees), Future.of (1)))
// Insert if not exists
.chain (konst (M.sequence (Future, insertFutures)))
// Run Future
.fork (log, id);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment