Skip to content

Commit

Permalink
feat: yukari insert
Browse files Browse the repository at this point in the history
  • Loading branch information
XadillaX committed Sep 21, 2016
1 parent b230cea commit 0463626
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 4 deletions.
97 changes: 97 additions & 0 deletions lib/yukari.js
Expand Up @@ -7,6 +7,9 @@
"use strict";

const _ = require("lodash");
const async = require("async");

const _emptyCallback = function() {};

class Yukari {
constructor(model, source) {
Expand Down Expand Up @@ -107,6 +110,100 @@ class Yukari {

return -1;
}

validateOne(name, value, callback) {
const self = this;
const fieldIdx = this.fieldAt(name);
if(-1 === fieldIdx) {
return callback(new Error(`No such field ${name}`));
}

const field = this.$schema[fieldIdx];

if(null === value) {
return callback(field.allowNull ? undefined : new Error(`Field ${name} can't be null.`));
}

if(!field.validators.length) {
return callback();
}

let err;
let i = 0;
async.whilst(
() => (!err && i < field.validators.length),
function(callback) {
const validator = field.validators[i++];
if(validator.length <= 1) {
const result = (validator.bind(self.$model))(value);
if(typeof result === "string" && result.length) {
err = new Error(result);
return callback(err);
}
} else {
return (validator.bind(self.$model))(value, function(_err) {
if(_err) {
err = _err;
}

return callback(err);
});
}
callback();
},
function() {
return callback(err);
});
}

validateAll(callback) {
const self = this;
async.eachLimit(Object.keys(this), 10, function(key, callback) {
if(!self.hasOwnProperty(key)) return callback();
if(key && (key[0] === "$" || typeof self[key] === "function" || self.fieldAt(key) === -1)) {
return callback();
}

self.validateOne(key, self[key], function(err) {
return callback(err);
});
}, function(err) {
return callback(err);
});
}

insert(callback) {
if(callback === undefined) {
callback = _emptyCallback;
}

if(this.$source !== "new") {
return callback(new Error("You must call this function via a new Yukari object."));
}

const self = this;

async.waterfall([
self.validateAll.bind(self),
self.$adapter.insert.bind(self.$adapter, self.$model, self)
], function(err, row, extra) {
if(err) return callback(err, null, extra);

// clone new row's data to self
for(const key in row) {
if(!row.hasOwnProperty(key)) continue;
if(key && key[0] === "$" && key !== "$origData") {
continue;
}

if(typeof row[key] === "function") continue;

self[key] = _.cloneDeep(row[key]);
}

return callback(undefined, self, extra);
});
}
}

module.exports = Yukari;
4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -28,7 +28,7 @@
"mocha": "3.0.1",
"mockjs": "^1.0.1-beta3",
"mysql": "^2.11.1",
"mysql2": "^1.0.0-rc.9",
"mysql2": "^1.1.0",
"should": "10.0.0",
"sync-runner": "^0.1.5",
"toshihiko-memcached": "^1.0.1",
Expand Down Expand Up @@ -73,4 +73,4 @@
"pre-push": "npm test"
}
}
}
}
8 changes: 6 additions & 2 deletions test/adapters/mysql.js
Expand Up @@ -145,7 +145,9 @@ describe("🐣 adapters/mysql", function() {
[ "mysql", "mysql2" ].forEach(name => {
describe(name, function() {
before(function(done) {
const adapter = new MySQLAdapter({}, correctOptions);
const options = cu.extendDeep({}, correctOptions);
options.package = name;
const adapter = new MySQLAdapter({}, options);
adapter.execute("DROP TABLE IF EXISTS `test1`;", function(err) {
should.ifError(err);
adapter.execute("DROP TABLE IF EXISTS `test2`;", function(err) {
Expand Down Expand Up @@ -217,7 +219,9 @@ describe("🐣 adapters/mysql", function() {
key3: { foo: "bar" },
key4: null,
key5: now,
key6: { dec: 168 }
key6: { dec: 168 },
$123: 1,
ok: function() {}
}, function(err, _row) {
should.ifError(err);
const row = cu.extendDeep({}, _row);
Expand Down

0 comments on commit 0463626

Please sign in to comment.