Support for Enum type in MySQL adapter. Requires patch to mainline JDB.
(See pull request: https://github.com/1602/jugglingdb/pull/296.) After this there are several ways to use Enum with the adapter as shown in datatypes.test.js.
This commit is contained in:
parent
c6b4a70fc4
commit
c1616fd998
|
@ -0,0 +1,52 @@
|
|||
function Enum() {
|
||||
if(arguments.length > 0){
|
||||
var dxList = [];
|
||||
dxList.push(''); // Want empty value to be at index 0 to match MySQL Enum values and MySQL non-strict behavior.
|
||||
for(var arg in arguments){
|
||||
arg = String(arguments[arg]);
|
||||
Object.defineProperty(this, arg.toUpperCase(), {configurable: false, enumerable: true, value: arg, writable: false});
|
||||
dxList.push(arg);
|
||||
}
|
||||
Object.defineProperty(this, '_values', {configurable: false, enumerable: false, value: dxList, writable: false});
|
||||
Object.defineProperty(this, '_string', {configurable: false, enumerable: false, value: stringified(this), writable: false});
|
||||
Object.freeze(this);
|
||||
return this;
|
||||
} else {
|
||||
throw "No arguments - can't create Enum.";
|
||||
}
|
||||
};
|
||||
Object.defineProperty(Enum.prototype, 'name', {configurable: false, enumerable: false, value: 'Enum', writable: false});
|
||||
|
||||
|
||||
var EnumFactory = (function() {
|
||||
function FakeEnumConstructor(args) {
|
||||
return Enum.apply(this, args);
|
||||
}
|
||||
|
||||
FakeEnumConstructor.prototype = Enum.prototype;
|
||||
|
||||
return function() {
|
||||
var returnObject = new FakeEnumConstructor(arguments);
|
||||
returnObject.constructor = Enum.constructor;
|
||||
return returnObject;
|
||||
}
|
||||
})();
|
||||
|
||||
function stringified(anEnum) {
|
||||
var s = [];
|
||||
for(var i in anEnum._values){
|
||||
if(anEnum._values[i] != ''){
|
||||
s.push("'" + anEnum._values[i] + "'");
|
||||
}
|
||||
}
|
||||
return s.join(',');
|
||||
}
|
||||
|
||||
exports.EnumFactory = EnumFactory;
|
||||
exports.Enum = Enum;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
12
lib/mysql.js
12
lib/mysql.js
|
@ -3,6 +3,8 @@
|
|||
*/
|
||||
var mysql = require('mysql');
|
||||
var jdb = require('jugglingdb');
|
||||
var Enums = require('./enumFactory');
|
||||
|
||||
|
||||
exports.initialize = function initializeSchema(schema, callback) {
|
||||
if (!mysql) return;
|
||||
|
@ -58,6 +60,12 @@ exports.initialize = function initializeSchema(schema, callback) {
|
|||
|
||||
// MySQL specific column types
|
||||
schema.constructor.registerType(function Point() {});
|
||||
|
||||
schema.EnumFactory = Enums.EnumFactory; // factory for Enums
|
||||
schema.Enum = Enums.Enum; // constructor for Enums
|
||||
|
||||
schema.constructor.registerType(Enums.Enum);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -644,6 +652,10 @@ function datatype(p) {
|
|||
case 'Point':
|
||||
dt = 'POINT';
|
||||
break;
|
||||
case 'Enum':
|
||||
dt = 'ENUM(' + p.type._string + ')';
|
||||
dt = stringOptions(p, dt); // Enum columns can have charset/collation.
|
||||
break;
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
var should = require('./init.js');
|
||||
var assert = require('assert');
|
||||
var Schema = require('jugglingdb').Schema;
|
||||
|
||||
var db, settings, adapter, EnumModel, ANIMAL_ENUM;
|
||||
|
||||
describe('MySQL specific datatypes', function() {
|
||||
|
||||
before(setup);
|
||||
|
||||
it('should run migration', function(done) {
|
||||
db.automigrate(function(){
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a model instance with Enums', function(done) {
|
||||
var em = EnumModel.create({animal: ANIMAL_ENUM.CAT, condition: 'sleepy', mood: 'happy'}, function(err, obj) {
|
||||
assert.ok(!err);
|
||||
assert.equal(obj.condition, 'sleepy');
|
||||
EnumModel.findOne({where: {animal: ANIMAL_ENUM.CAT}}, function(err, found){
|
||||
assert.ok(!err);
|
||||
assert.equal(found.mood, 'happy');
|
||||
assert.equal(found.animal, ANIMAL_ENUM.CAT);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail spectacularly with invalid enum values', function(done) {
|
||||
var em = EnumModel.create({animal: 'horse', condition: 'sleepy', mood: 'happy'}, function(err, obj) {
|
||||
assert.ok(!err);
|
||||
EnumModel.find(obj.id, function(err, found){
|
||||
assert.ok(!err);
|
||||
assert.equal(found.animal, ''); // MySQL fun.
|
||||
assert.equal(found.animal, 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should disconnect when done', function(done) {
|
||||
db.disconnect();
|
||||
done()
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function setup(done) {
|
||||
|
||||
require('./init.js');
|
||||
|
||||
db = getSchema();
|
||||
|
||||
ANIMAL_ENUM = db.EnumFactory('dog', 'cat', 'mouse');
|
||||
|
||||
EnumModel = db.define('EnumModel', {
|
||||
animal: { type: ANIMAL_ENUM, null: false },
|
||||
condition: { type: db.EnumFactory('hungry', 'sleepy', 'thirsty') },
|
||||
mood: { type: new db.Enum('angry', 'happy', 'sad') }
|
||||
});
|
||||
|
||||
blankDatabase(db, done);
|
||||
|
||||
}
|
||||
|
||||
var query = function (sql, cb) {
|
||||
db.adapter.query(sql, cb);
|
||||
};
|
||||
|
||||
var blankDatabase = function (db, cb) {
|
||||
var dbn = db.settings.database;
|
||||
var cs = db.settings.charset;
|
||||
var co = db.settings.collation;
|
||||
query('DROP DATABASE IF EXISTS ' + dbn, function(err) {
|
||||
var q = 'CREATE DATABASE ' + dbn;
|
||||
if(cs){
|
||||
q += ' CHARACTER SET ' + cs;
|
||||
}
|
||||
if(co){
|
||||
q += ' COLLATE ' + co;
|
||||
}
|
||||
query(q, function(err) {
|
||||
query('USE '+ dbn, cb);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
getFields = function (model, cb) {
|
||||
query('SHOW FIELDS FROM ' + model, function(err, res) {
|
||||
if (err) {
|
||||
cb(err);
|
||||
} else {
|
||||
var fields = {};
|
||||
res.forEach(function(field){
|
||||
fields[field.Field] = field;
|
||||
});
|
||||
cb(err, fields);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getIndexes = function (model, cb) {
|
||||
query('SHOW INDEXES FROM ' + model, function(err, res) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
cb(err);
|
||||
} else {
|
||||
var indexes = {};
|
||||
// Note: this will only show the first key of compound keys
|
||||
res.forEach(function(index) {
|
||||
if (parseInt(index.Seq_in_index, 10) == 1) {
|
||||
indexes[index.Key_name] = index
|
||||
}
|
||||
});
|
||||
cb(err, indexes);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue