Add schema.isActual and automigrate on sqlite start

This commit is contained in:
Anatoliy Chakkaev 2012-02-20 22:33:11 +04:00
parent 8e1ff15589
commit e8c6f68353
7 changed files with 84 additions and 12 deletions

View File

@ -179,6 +179,7 @@ AbstractClass.find = function find(id, cb) {
substractDirtyAttributes(obj, data);
this.call(obj, data);
} else {
data.id = id;
obj = new this(data);
this.cache[data.id] = obj;
}

View File

@ -306,7 +306,11 @@ MySQL.prototype.autoupdate = function (cb) {
Object.keys(this._models).forEach(function (model) {
wait += 1;
self.query('SHOW FIELDS FROM ' + model, function (err, fields) {
self.alterTable(model, fields, done);
if (!err && fields.length) {
self.alterTable(model, fields, done);
} else {
self.createTable(model, done);
}
});
});
@ -320,10 +324,34 @@ MySQL.prototype.autoupdate = function (cb) {
}
};
MySQL.prototype.alterTable = function (model, actualFields, done) {
MySQL.prototype.isActual = function (cb) {
var ok = false;
var self = this;
var wait = 0;
Object.keys(this._models).forEach(function (model) {
wait += 1;
self.query('SHOW FIELDS FROM ' + model, function (err, fields) {
self.alterTable(model, fields, done, true);
});
});
function done(err, needAlter) {
if (err) {
console.log(err);
}
ok = ok || needAlter;
if (--wait === 0 && cb) {
cb(null, !ok);
}
}
};
MySQL.prototype.alterTable = function (model, actualFields, done, checkOnly) {
var self = this;
var m = this._models[model];
var propNames = Object.keys(m.properties);
var propNames = Object.keys(m.properties).filter(function (name) {
return !!m.properties[name];
});
var sql = [];
// change/add new fields
@ -352,7 +380,11 @@ MySQL.prototype.alterTable = function (model, actualFields, done) {
});
if (sql.length) {
this.query('ALTER TABLE `' + model + '` ' + sql.join(',\n'), done);
if (checkOnly) {
done(null, true);
} else {
this.query('ALTER TABLE `' + model + '` ' + sql.join(',\n'), done);
}
} else {
done();
}

View File

@ -14,7 +14,11 @@ exports.initialize = function initializeSchema(schema, callback) {
schema.client = db;
schema.adapter = new SQLite3(schema.client);
process.nextTick(callback);
if (s.database === ':memory:') {
schema.adapter.automigrate(callback);
} else {
process.nextTick(callback);
}
};
function SQLite3(client) {

View File

@ -100,6 +100,18 @@ Schema.prototype.autoupdate = function (cb) {
}
};
/**
* Check whether migrations needed
*/
Schema.prototype.isActual = function (cb) {
this.freeze();
if (this.adapter.isActual) {
this.adapter.isActual(cb);
} else if (cb) {
cb(null, true);
}
};
Schema.prototype.log = function (sql, t) {
this.emit('log', sql, t);
};

View File

@ -4,8 +4,8 @@ function safeRequire(module) {
try {
return require(module);
} catch (e) {
console.log('Run "npm install ' + module + '" command to use jugglingdb using this database');
return false
console.log('Run "npm install ' + module + '" command to use jugglingdb using this database engine');
process.exit(1);
}
}

View File

@ -584,6 +584,20 @@ function testOrm(schema) {
}
});
it('should return id in find result even after updateAttributes', function (test) {
Post.create(function (err, post) {
var id = post.id;
test.ok(post.published === false);
post.updateAttributes({title: 'hey', published: true}, function () {
Post.find(id, function (err, post) {
test.ok(post.published === true);
test.ok(post.id);
test.done();
});
});
});
});
it('all tests done', function (test) {
test.done();
process.nextTick(allTestsDone);

View File

@ -119,21 +119,30 @@ it 'should autoupgrade', (test) ->
schema.autoupdate (err) ->
getFields 'User', (err, fields) ->
# change nullable for email
test.equal fields.email.Null, 'YES'
test.equal fields.email.Null, 'YES', 'Email is not null'
# change type of name
test.equal fields.name.Type, 'varchar(50)'
test.equal fields.name.Type, 'varchar(50)', 'Name is not varchar(50)'
# add new column
test.ok fields.newProperty
test.ok fields.newProperty, 'New column was not added'
if fields.newProperty
test.equal fields.newProperty.Type, 'int(11)'
test.equal fields.newProperty.Type, 'int(11)', 'New column type is not int(11)'
# drop column
test.ok not fields.pendingPeriod
test.ok not fields.pendingPeriod, 'drop column'
# user still exists
userExists (yep) ->
test.ok yep
test.done()
it 'should check actuality of schema', (test) ->
# drop column
User.schema.isActual (err, ok) ->
test.ok ok
User.defineProperty 'email', false
User.schema.isActual (err, ok) ->
test.ok not ok
test.done()
it 'should disconnect when done', (test) ->
schema.disconnect()
test.done()