Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial commit.

  • Loading branch information...
commit 39cd4c23d5259041003cf2d5683a79895ef589da 1 parent fb6c628
simov authored
View
1  .gitignore
@@ -6,6 +6,7 @@ lib-cov
*.out
*.pid
*.gz
+*.bak
pids
logs
View
60 lib/data-type.js
@@ -0,0 +1,60 @@
+
+function DataType () {
+
+}
+
+DataType.prototype.type = [
+ {regex: /(bit|binary)(?:\s*\(\s*(\d+)\s*\))?/i, options: {value: 2}},
+ {regex: /(tinyint|smallint|mediumint|integer|int|bigint)(?:\s*\(\s*(\d+)\s*\))?(\s+unsigned)?(\s+zerofill)?/i, options: {value: 2, unsigned: 3, zerofill: 4}},
+ {regex: /(real|double|float)(?:\s*\(\s*(\d+\s*,\s*\d+)\s*\))?(\s+unsigned)?(\s+zerofill)?/i, options: {value: 2, unsigned: 3, zerofill: 4}},
+ {regex: /(decimal|numeric)(?:\s*\(\s*(\d+(?:\s*,\s*\d+)?)\s*\))?(\s+unsigned)?(\s+zerofill)?/i, options: {value: 2, unsigned: 3, zerofill: 4}},
+ {regex: /(datetime|date|timestamp|time|year|tinyblob|blob|mediumblob|longblob)/i, options: {}},
+ {regex: /(varchar)\s*\(\s*(\d+)\s*\)(?:\s+character\s+set\s+(\w+))?(?:\s+collate\s+(\w+))?/i, options: {value: 2, characterSet: 3, collate: 4}},
+ {regex: /(char)(?:\s*\(\s*(\d+)\s*\))?(?:\s+character\s+set\s+(\w+))?(?:\s+collate\s+(\w+))?/i, options: {value: 2, characterSet: 3, collate: 4}},
+ {regex: /(varbinary)\s*\(\s*(\d+)\s*\)/i, options: {value: 2}},
+ {regex: /(tinytext|text|mediumtext|longtext)(\s+binary)?(?:\s+character\s+set\s+(\w+))?(?:\s+collate\s+(\w+))?/i, options: {binary: 2, characterSet: 3, collate: 4}},
+ {regex: /(enum|set)\s*\(\s*(.+)\s*\)(?:\s+character\s+set\s+(\w+))?(?:\s+collate\s+(\w+))?/i, options: {values: 2, characterSet: 3, collate: 4}}
+];
+
+DataType.prototype.get = function (sql, cb) {
+
+ function numbers (str) {
+ var values = str.split(',');
+ for (var i=0; i < values.length; i++) {
+ values[i] = parseInt(values[i], 10);
+ }
+ return values;
+ }
+
+ function strings (str) {
+ var values = str.split(',');
+ for (var i=0; i < values.length; i++) {
+ values[i] = values[i].replace(/(`|'|")/gi, '');
+ }
+ return values;
+ }
+
+ for (var i=0; i < this.type.length; i++) {
+ var type = this.type[i],
+ match = sql.match(type.regex);
+ if (match) {
+ var dataType = {name: match[1]};
+ for (key in type.options) {
+ var index = type.options[key];
+ if (match[index]) {
+ var value = null;
+ switch (key) {
+ case 'value': value = numbers(match[index]); break;
+ case 'unsigned': case 'zerofill': case 'binary': value = true; break;
+ case 'characterSet': case 'collate': case 'binary': value = match[index]; break;
+ case 'values': value = strings(match[index]); break;
+ }
+ dataType[key] = value;
+ }
+ }
+ return cb(dataType);
+ }
+ }
+}
+
+exports.DataType = DataType;
View
293 lib/validator.js
@@ -0,0 +1,293 @@
+
+var moment = require('moment');
+var dataType = new (require('./data-type').DataType);
+
+
+function Validator () {
+
+}
+
+Validator.prototype.check = function (value, type, cb) {
+ var self = this;
+ dataType.get(type, function (type) {
+ var func = self.type(type.name);
+ cb(self[func](value, type));
+ });
+}
+
+Validator.prototype.type = function (type) {
+ var func = '';
+ switch (true) {
+ case /tinyint|smallint|mediumint|integer|bigint|int|bit|select/i.test(type):
+ func = 'exact';
+ break;
+ case /decimal|numeric/i.test(type):
+ func = 'fixedPoint';
+ break;
+ case /real|double|float/i.test(type):
+ func = 'approximate';
+ break;
+ case /varchar|char/i.test(type):
+ func = 'char';
+ break;
+ case /tinytext|mediumtext|longtext|text/i.test(type):
+ func = 'text';
+ break;
+ case /date|year/i.test(type):
+ func = 'date';
+ break;
+ case /time/i.test(type):
+ func = 'time';
+ break;
+ case /datetime|timestamp/i.test(type):
+ func = 'datetime';
+ break;
+ case /enum|set/i.test(type):
+ func = 'enum';
+ break;
+ }
+ return func;
+}
+
+Validator.prototype.exact = function (value, type) {
+ var num = parseInt(value);
+ if (isNaN(num)) {
+ return { message: 'not valid' };
+ } else {
+ var range = NUMBER[type.name][type.unsigned?'unsigned':'signed'];
+ return (num >= range.min && num <= range.max) ? null
+ : new Error('out of range');
+ }
+}
+
+Validator.prototype.fixedPoint = function (value, type) {
+ var num = parseFloat(value);
+ if (isNaN(num)) {
+ return { message: 'not valid' };
+ } else {
+ if (type.value.length) {
+ var range = createRange(type);
+ return (num >= range.min && num <= range.max) ? null
+ : new Error('out of range');
+ } else {
+ // no validation - uses default system/database ranges
+ return null;
+ }
+ }
+}
+
+Validator.prototype.approximate = function (value, type) {
+ // for now it will use the fixed point validation
+ this.fixedPoint(value, type);
+}
+
+Validator.prototype.char = function (value, type) {
+ if (type.value.length) {
+ return (value.length < type.value[0]) ? null
+ : new Error('out of range');
+ } else {
+ // no validation - uses default system/database ranges
+ return null;
+ }
+}
+
+Validator.prototype.text = function (value, type) {
+ if (type.name === 'tinytext') {
+ return (value.length < 255) ? null
+ : new Error('out of range');
+ } else {
+ // no validation - text:0-64Kb,meduimtext:0-16Mb,longtext:0-4Gb
+ return null;
+ }
+}
+
+Validator.prototype.date = function (value, type) {
+ var regex = REGEX.date;
+ for (var i=0; i < regex.length; i++) {
+ if (regex[i].test(value)) {
+ var length = regex[i].exec(value)[1].length,
+ format = i == 0
+ ? (length == 4 ? 'YYYY-MM-DD' : 'YY-MM-DD')
+ : (length == 4 ? 'YYYYMMDD' : 'YYMMDD');
+ if (moment(value, format).isValid()) return null;
+ }
+ }
+ return new Error('malformed');
+}
+
+Validator.prototype.time = function (value, type) {
+ var regex = REGEX.time;
+ for (var i=0; i < regex.length; i++) {
+ if (regex[i].test(value)) return null;
+ }
+ return new Error('malformed');
+}
+
+Validator.prototype.datetime = function (value, type) {
+ var regex = REGEX.datetime;
+ for (var i=0; i < regex.length; i++) {
+ if (regex[i].test(value)) {
+ var match = regex[i].exec(value),
+ time = match[5],
+ length = match[1].length,
+ format =
+ i == 0
+ ? (length == 4
+ ? (time ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD')
+ : (time ? 'YY-MM-DD HH:mm:ss' : 'YY-MM-DD'))
+ : (length == 4
+ ? (time ? 'YYYYMMDDHHmmss' : 'YYYYMMDD')
+ : (time ? 'YYMMDDHHmmss' : 'YYMMDD'));
+ if (moment(value, format).isValid()) return null;
+ }
+ }
+ return new Error('malformed');
+}
+
+Validator.prototype.enum = function (value, type) {
+ // not implemented
+ return null;
+}
+
+exports.Validator = Validator;
+
+
+// private api
+
+function createRange (type) {
+ // example:
+ // type.value = [6,2]
+ // min: -9999.99
+ // max: 9999.99
+ // type.value = [6,2] unsigned
+ // min: 0
+ // max: 9999.99
+ function gen (length) {
+ var str = '';
+ for (var i=0; i < length; i++) {
+ str += '9';
+ }
+ return str;
+ }
+ var m = type.value[0],
+ d = type.value[1] ? type.value[1] : 0;
+ m = gen(m-d), d = gen(d);
+ var num = parseFloat(m+'.'+d);
+ return type.unsigned
+ ? { min: 0, max: num }
+ : { min: num*(-1), max: num };
+}
+
+
+var REGEX = {
+ // DATE
+ date: [
+ // YYYY|YY-MM|M-DD|D
+ new RegExp(
+ '^(\\d{4}|\\d{2})'+ // year YYYY|YY
+ '[^a-zA-Z\\d\\s]+'+ // separator
+ '(1[0-2]|0?[0-9])'+ // month 1-12
+ '[^a-zA-Z\\d\\s]+'+ // separator
+ '(3[0-1]|(1|2)[0-9]|0?[0-9])'+ // day 1-31
+ '[^\\d]*$' // anything but number at the end
+ , 'i'),
+ // YYYY|YYMMDD
+ new RegExp(
+ '^(\\d{4}|\\d{2})'+ // year YYYY|YY
+ '(1[0-2]|0[0-9])'+ // month 01-12
+ '(3[0-1]|(0|1|2)[0-9])$' // day 01-31
+ , 'i')
+ ],
+ // TIME
+ time: [
+ // D? H|HH:M|MM:S|SS, D? H|HH:M|MM, D? H|HH
+ new RegExp(
+ '^((3[0-4]|[0-2]?[0-9])\\s)?'+ // day 0-34
+ '(2[0-4]|[0-1]?[0-9])'+ // hour 0-24
+ '(:'+ // separator
+ '([0-5]?[0-9]))?'+ // minute 0-59?
+ '(:'+ // separator
+ '([0-5]?[0-9]))?'+ // second 0-59?
+ '[^\\d]*$' // anything but number at the end
+ , 'i'),
+ // H|HH|HHH:M|MM:S|SS, H|HH|HHH:M|MM
+ new RegExp(
+ '^(8[0-3][0-8]|[0-7]?[0-9]?[0-9]?)'+// hour 0-838
+ ':'+ // separator
+ '([0-5]?[0-9])'+ // minute 0-59
+ '(:'+ // separator
+ '([0-5]?[0-9]))?'+ // second 0-59?
+ '[^\\d]*$' // anything but number at the end
+ , 'i'),
+ // HH|HHHMMSS
+ new RegExp(
+ '^(8[0-3][0-8]|[0-7]?[0-9][0-9])'+ // hour 00-838
+ '([0-5][0-9])'+ // minute 00-59
+ '([0-5][0-9])'+ // second 00-59
+ '[^\\d]*$' // anything but number at the end
+ , 'i'),
+ // SS
+ new RegExp(
+ '^[0-5]?[0-9]$' // second 0-59
+ , 'i')
+ ],
+ // DATETIME, TIMESTAMP
+ datetime: [
+ // YYYY|YY-MM|M-DD|D HH|H:MM|M:SS|S
+ new RegExp(
+ '^(\\d{4}|\\d{2})'+ // year YYYY|YY
+ '[^a-zA-Z\\d]+'+ // separator
+ '(1[0-2]|0?[0-9])'+ // month 1-12
+ '[^a-zA-Z\\d]+'+ // separator
+ '(3[0-1]|(1|2)[0-9]|0?[0-9])'+ // day 1-31
+
+ '([^a-zA-Z\\d]+'+ // separator
+ '(2[0-4]|[0-1]?[0-9])'+ // hour 0-24
+ '[^a-zA-Z\\d]+'+ // separator
+ '([0-5]?[0-9])'+ // minute 0-59
+ '[^a-zA-Z\\d]+'+ // separator
+ '([0-5]?[0-9]))?'+ // second 0-59
+ '[^\\d]*$' // anything but number at the end
+ , 'i'),
+ // YYYY|YYMMDDHHMMSS
+ new RegExp(
+ '^(\\d{4}|\\d{2})'+ // year YYYY|YY
+ '(1[0-2]|0[0-9])'+ // month 01-12
+ '(3[0-1]|(0|1|2)[0-9])'+ // day 01-31
+
+ '((2[0-4]|[0-1][0-9])'+ // hour 0-24
+ '([0-5][0-9])'+ // minute 00-59
+ '([0-5][0-9]))?$' // second 00-59
+ , 'i')
+ ]
+};
+
+var NUMBER = {
+ bigint: {
+ signed: { min: -9223372036854775808, max: 9223372036854775807 },
+ unsigned: { min: 0, max: 18446744073709551615 }
+ },
+ integer: {
+ signed: { min: -2147483648, max: 2147483647 },
+ unsigned: { min: 0, max: 4294967295 }
+ },
+ int: {
+ signed: { min: -2147483648, max: 2147483647 },
+ unsigned: { min: 0, max: 4294967295 }
+ },
+ mediumint: {
+ signed: { min: -8388608, max: 8388607 },
+ unsigned: { min: 0, max: 16777215 }
+ },
+ smallint: {
+ signed: { min: -32768, max: 32767 },
+ unsigned: { min: 0, max: 65535 }
+ },
+ tinyint: {
+ signed: { min: -128, max: 127 },
+ unsigned: { min: 0, max: 255 }
+ },
+ bit: {
+ signed: { min: 1, max: 64 }
+ }
+}
View
30 package.json
@@ -0,0 +1,30 @@
+{
+ "name": "mysql-validator",
+ "version": "0.1.0",
+ "description": "MySql data type validation.",
+ "keywords": [
+ "mysql",
+ "data",
+ "validation"
+ ],
+ "license": "MIT",
+ "homepage": "http://simov.github.com/mysql-validator/",
+ "author": {
+ "name": "simo",
+ "email": "simeonvelichkov@gmail.com"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/simov/mysql-validator.git"
+ },
+ "dependencies": {
+ "moment": "*"
+ },
+ "devDependencies": {
+ "mysql": "2.0.0-alpha2",
+ "mocha": "*",
+ "should": "*",
+ "colors": "*"
+ },
+ "main": "./lib/validator"
+}
View
65 test/data-type.js
@@ -0,0 +1,65 @@
+
+var fs = require('fs'),
+ moment = require('moment');
+require('colors');
+
+var mysql = require('mysql'),
+ c = mysql.createConnection({
+ user: 'liolio',
+ password: 'karamba',
+ typeCast: false,
+ multipleStatements: true
+ });
+var table = {},
+ dataType = new (require('../lib/data-type')).DataType;
+
+describe('mysql database', function () {
+ before(function (done) {
+ var schema = fs.readFileSync('./test/fixtures/schema.sql', 'utf8');
+ c.query(schema, function (err, rows) {
+ if (err) throw err;
+ done();
+ });
+ });
+
+ it('should get columns info', function (done) {
+ c.query('describe `datatypes`;', function (err, rows) {
+ if (err) throw err;
+ for (var i=0; i < rows.length; i++) {
+ var column = rows[i];
+ table[column.Field] = {
+ type: column.Type,
+ allowNull: column.Null === 'YES' ? true : false,
+ key: column.Key.toLowerCase(),
+ defaultValue: column.Default,
+ extra: column.Extra
+ }
+ }
+ rows.length.should.equal(Object.keys(table).length);
+ done();
+ });
+ });
+
+ it('should test data types', function (done) {
+ var keys = Object.keys(table);
+ console.log('');
+ function loop (index) {
+ if (index == keys.length) {
+ return done();
+ }
+ var column = table[keys[index]];
+ dataType.get(column.type, function (type) {
+ console.log(column.type.yellow, type);
+ loop(++index);
+ });
+ }
+ loop(0);
+ });
+
+ after(function (done) {
+ c.query('drop schema `mysql-validator`;', function (err, rows) {
+ if (err) throw err;
+ done();
+ });
+ });
+});
View
155 test/date.js
@@ -0,0 +1,155 @@
+
+var fs = require('fs'),
+ moment = require('moment');
+require('colors');
+
+var mysql = require('mysql'),
+ c = mysql.createConnection({
+ user: 'liolio',
+ password: 'karamba',
+ typeCast: false,
+ multipleStatements: true
+ });
+
+var validator = new (require('../lib/validator').Validator);
+
+
+function testDates (tests, expected, cb) {
+ var sql = '';
+ for (var i=0; i < tests.length; i++) {
+ sql += 'insert into `datetime` (`date`) values ("'+tests[i]+'");';
+ }
+ c.query(sql, function (err, result) {
+ if (err) throw err;
+ c.query('select `date` from `datetime`;', function (err, rows) {
+ if (err) throw err;
+ console.log('');
+ for (var j=0; j < tests.length; j++) {
+ var ok = rows[j].date === eval(expected);
+ var err = validator.date(tests[j]);
+ // print
+ console.log('\t'+
+ (ok ? rows[j].date.green : rows[j].date.red),
+ tests[j].yellow,
+ (!err ? 'valid'.green : 'invalid'.red)
+ );
+ // ?
+ }
+ c.query('delete from `datetime`;', function (err, result) {
+ if (err) throw err;
+ cb();
+ });
+ });
+ });
+}
+
+
+describe('data type', function () {
+ before(function (done) {
+ c.query('create schema if not exists `mysql-express-admin`;'+
+ 'use `mysql-express-admin`;',
+ function (err, rows) {
+ if (err) throw err;
+ var schema = fs.readFileSync('./test/fixtures/schema.sql', 'utf8');
+ c.query(schema, function (err, rows) {
+ if (err) throw err;
+ done();
+ });
+ });
+ });
+
+ describe('DATE', function () {
+ it('should be well formatted', function (done) {
+ var dates = TEST.format,
+ expected = '"2012-11-02"';
+ testDates(dates, expected, function () {
+ done();
+ });
+ });
+ it('should be a valid day of the month: YYYY-MM-DD', function (done) {
+ var dates = TEST.monthDays1,
+ expected = 'test[j]';
+ testDates(dates, expected, function () {
+ done();
+ });
+ });
+ it('should be a valid day of the month: YY-MM-DD', function (done) {
+ var dates = TEST.monthDays2,
+ expected = 'moment(test[j], "YY-MM-DD").format("YYYY-MM-DD")';
+ testDates(dates, expected, function () {
+ done();
+ });
+ });
+ it('should be a valid day of the month: YYYYMMDD', function (done) {
+ var dates = TEST.monthDays3,
+ expected = 'moment(test[j], "YYYYMMDD").format("YYYY-MM-DD")';
+ testDates(dates, expected, function () {
+ done();
+ });
+ });
+ it('should be a valid day of the month: YYMMDD', function (done) {
+ var dates = TEST.monthDays4,
+ expected = 'moment(test[j], "YYMMDD").format("YYYY-MM-DD")';
+ testDates(dates, expected, function () {
+ done();
+ });
+ });
+ });
+
+ after(function (done) {
+ c.query('drop schema `mysql-express-admin`;',
+ function (err, rows) {
+ if (err) throw err;
+ done();
+ });
+ });
+});
+
+var TEST = {
+ format: [
+ // YYYY-MM-DD, YY-MM-DD, YYYYMMDD, YYMMDD
+ '2012-11-02', '12-11-02', '20121102', '121102',
+ // separator
+ '2012~`!@#$%^&*()-_=+{}[]\\|:;<>,.?/11---02', // without " ' space
+ '2012w11aa02', '2012-1102',
+ '2012*11 02', '2012 11 02',
+ // out of range
+ '20122-11-02', '2012-13-02', '2012-11-32',
+ '201221102', '20121302', '20121132',
+ // single value for month/day
+ '2012112', '2012-11-2',
+ // after date
+ '2012-11-02 w', '12-11-02 w', '2012-11-02w', '12-11-02w',
+ '20121102w', '121102w', '20121102 w', '121102 w'
+ ],
+ // monthDays: [
+ // // YYYY-MM-DD
+ // '2012-02-28', '2012-02-29', '2012-02-30',
+ // '2012-11-30', '2012-11-31',
+ // // YY-MM-DD
+ // '12-02-28', '12-02-29', '12-02-30',
+ // '12-11-30', '12-11-31',
+ // // YYYYMMDD
+ // '20120228', '20120229', '20120230',
+ // '20121130', '20121131',
+ // // YYMMDD
+ // '120228', '120229', '120230',
+ // '121130', '121131'
+ // ],
+ monthDays1: [
+ '2012-02-28', '2012-02-29', '2012-02-30',
+ '2012-11-30', '2012-11-31'
+ ],
+ monthDays2: [
+ '12-02-28', '12-02-29', '12-02-30',
+ '12-11-30', '12-11-31'
+ ],
+ monthDays3: [
+ '20120228', '20120229', '20120230',
+ '20121130', '20121131'
+ ],
+ monthDays4: [
+ '120228', '120229', '120230',
+ '121130', '121131'
+ ]
+};
View
134 test/datetime.js
@@ -0,0 +1,134 @@
+
+var fs = require('fs'),
+ moment = require('moment');
+require('colors');
+
+var mysql = require('mysql'),
+ c = mysql.createConnection({
+ user: 'liolio',
+ password: 'karamba',
+ typeCast: false,
+ multipleStatements: true
+ });
+
+var validator = new (require('../lib/validator').Validator);
+
+
+function testDates (tests, cb) {
+ var sql = '';
+ for (var i=0; i < tests.length; i++) {
+ sql += 'insert into `datetime` (`datetime`) values ("'+tests[i]+'");';
+ }
+ c.query(sql, function (err, result) {
+ if (err) throw err;
+ c.query('select `datetime` from `datetime`;', function (err, rows) {
+ if (err) throw err;
+ console.log('');
+ for (var j=0; j < tests.length; j++) {
+ var err = validator.datetime(tests[j]);
+ // print
+ console.log('\t'+
+ (!err ? rows[j].datetime.green : rows[j].datetime.red),
+ tests[j].yellow,
+ (!err ? 'valid'.green : 'invalid'.red)
+ );
+ // ?
+ }
+ c.query('delete from `datetime`;', function (err, result) {
+ if (err) throw err;
+ cb();
+ });
+ });
+ });
+}
+
+
+describe('data type', function () {
+ before(function (done) {
+ c.query('create schema if not exists `mysql-express-admin`;'+
+ 'use `mysql-express-admin`;',
+ function (err, rows) {
+ if (err) throw err;
+ var schema = fs.readFileSync('./test/fixtures/schema.sql', 'utf8');
+ c.query(schema, function (err, rows) {
+ if (err) throw err;
+ done();
+ });
+ });
+ });
+
+ describe('DATETIME, TIMESTAMP', function () {
+ it('should be well formatted', function (done) {
+ testDates(TEST.format, function () {
+ done();
+ });
+ });
+ it('should be a valid day of the month', function (done) {
+ testDates(TEST.monthDays, function () {
+ done();
+ });
+ });
+ it('should be a valid time of the day', function (done) {
+ testDates(TEST.dayTime, function () {
+ done();
+ });
+ });
+ });
+
+ after(function (done) {
+ c.query('drop schema `mysql-express-admin`;',
+ function (err, rows) {
+ if (err) throw err;
+ done();
+ });
+ });
+});
+
+var TEST = {
+ format: [
+ // YYYY-MM-DD HH:MM:SS
+ '2012-11-04 2:12:14', '2012-11-4 2:2:5', '2012-1-4 00:5:16',
+ // YY-MM-DD HH:MM:SS
+ '12-11-04 2:12:14', '99-11-4 2:2:5', '12-1-4 00:5:16',
+ // YYYYMMDDHHMMSS
+ '20121104021214',
+ // YYMMDDHHMMSS
+ '121104000514',
+ // separator
+ '2012~`!@#$%^&*()-_=+{}[]\\|:;<>,.?/11-04 2:12:14',
+ '2012-11-04 2~`!@#$%^&*()-_=+{}[]\\|:;<>,.?/12:14',
+ '2012-11-04~`!@#$%^&*()-_=+{}[]\\|:;<>,.?/2:12:14',
+ // after time
+ '2012-11-04 2:12:14 w', '2012-11-04 2:12:14w',
+ '121104000514 w', '121104000514w',
+ // only date
+ '2012-02-28', '2012-02-28w', '2012-02-28 w',
+ '20120228'
+ ],
+ monthDays: [
+ // YYYY-MM-DD HH:MM:SS
+ '2012-02-28', '2012-02-29', '2012-02-30',
+ '2012-11-30', '2012-11-31',
+ // YY-MM-DD HH:MM:SS
+ '12-02-28', '12-02-29', '12-02-30',
+ '12-11-30', '12-11-31',
+ // YYYYMMDDHHMMSS
+ '20120228', '20120229', '20120230',
+ '20121130', '20121131',
+ // YYMMDDHHMMSS
+ '120228', '120229', '120230',
+ '121130', '121131'
+ ],
+ dayTime: [
+ // YYYY-MM-DD HH:MM:SS
+ '2012-11-04 4:56:16',
+ '2012-11-04 25:56:16', '2012-11-04 4:60:16', '2012-11-04 4:56:60',
+ // YY-MM-DD HH:MM:SS
+ '12-11-04 25:56:16', '12-11-04 4:56:60', '12-11-04 4:56:60',
+ // YYYYMMDDHHMMSS
+ '20121104045616',
+ '20121104255616', '20121104046016', '20121104045660',
+ // YYMMDDHHMMSS
+ '121104255616', '121104046016', '121104045660'
+ ]
+};
View
BIN  test/fixtures/mysql-validator.mwb
Binary file not shown
View
32 test/fixtures/schema.sql
@@ -0,0 +1,32 @@
+SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
+SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
+SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
+
+DROP SCHEMA IF EXISTS `mysql-validator` ;
+CREATE SCHEMA IF NOT EXISTS `mysql-validator` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
+USE `mysql-validator` ;
+
+-- -----------------------------------------------------
+-- Table `datatypes`
+-- -----------------------------------------------------
+DROP TABLE IF EXISTS `datatypes` ;
+
+CREATE TABLE IF NOT EXISTS `datatypes` (
+ `id` INT NOT NULL ,
+ `date` DATE NULL ,
+ `time` TIME NULL ,
+ `datetime` DATETIME NULL ,
+ `timestamp` TIMESTAMP NULL ,
+ `year` YEAR NULL ,
+ `int` INT NULL ,
+ `int-unsigned` INT UNSIGNED NULL ,
+ `int-zerofill` INT ZEROFILL NULL ,
+ `char` CHAR NULL ,
+ PRIMARY KEY (`id`) )
+ENGINE = InnoDB;
+
+
+
+SET SQL_MODE=@OLD_SQL_MODE;
+SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
+SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
View
13 test/index.js
@@ -0,0 +1,13 @@
+
+/*
+ Execute these commands before running the tests:
+
+ create user 'liolio'@'localhost' identified by 'karamba';
+ grant all on `mysql-validator`.* to 'liolio'@'localhost';
+*/
+
+// require('./mysql');
+require('./data-type');
+// require('./date');
+// require('./time');
+// require('./datetime');
View
4 test/mocha.opts
@@ -0,0 +1,4 @@
+--require should
+--reporter spec
+--timeout 100000
+--watch
View
41 test/mysql.js
@@ -0,0 +1,41 @@
+
+var fs = require('fs'),
+ moment = require('moment');
+
+var mysql = require('mysql'),
+ c = mysql.createConnection({
+ user: 'liolio',
+ password: 'karamba',
+ typeCast: false,
+ multipleStatements: true
+ });
+
+
+describe('mysql database', function () {
+ before(function (done) {
+ var schema = fs.readFileSync('./test/fixtures/schema.sql', 'utf8');
+ c.query(schema, function (err, rows) {
+ if (err) throw err;
+ done();
+ });
+ });
+
+ it('should store a record and select it', function (done) {
+ c.query('insert into `datatypes` (`date`) values ("2012-11-01");',
+ function (err, result) {
+ if (err) throw err;
+ c.query('select `date` from `datatypes` where id='+result.insertId,
+ function (err, rows) {
+ moment(rows[0].date).format('YYYY-MM-DD').should.equal('2012-11-01');
+ done();
+ });
+ });
+ });
+
+ after(function (done) {
+ c.query('drop schema `mysql-validator`;', function (err, rows) {
+ if (err) throw err;
+ done();
+ });
+ });
+});
View
105 test/time.js
@@ -0,0 +1,105 @@
+
+var fs = require('fs'),
+ moment = require('moment');
+require('colors');
+
+var mysql = require('mysql'),
+ c = mysql.createConnection({
+ user: 'liolio',
+ password: 'karamba',
+ typeCast: false,
+ multipleStatements: true
+ });
+
+var validator = new (require('../lib/validator').Validator);
+
+
+function testDates (tests, cb) {
+ var sql = '';
+ for (var i=0; i < tests.length; i++) {
+ sql += 'insert into `datetime` (`time`) values ("'+tests[i]+'");';
+ }
+ c.query(sql, function (err, result) {
+ if (err) throw err;
+ c.query('select `time` from `datetime`;', function (err, rows) {
+ if (err) throw err;
+ console.log('');
+ for (var j=0; j < tests.length; j++) {
+ var err = validator.time(tests[j]);
+ // print
+ console.log('\t'+
+ (!err ? rows[j].time.green : rows[j].time.red),
+ tests[j].yellow,
+ (!err ? 'valid'.green : 'invalid'.red)
+ );
+ // ?
+ }
+ c.query('delete from `datetime`;', function (err, result) {
+ if (err) throw err;
+ cb();
+ });
+ });
+ });
+}
+
+
+describe('data type', function () {
+ before(function (done) {
+ c.query('create schema if not exists `mysql-express-admin`;'+
+ 'use `mysql-express-admin`;',
+ function (err, rows) {
+ if (err) throw err;
+ var schema = fs.readFileSync('./test/fixtures/schema.sql', 'utf8');
+ c.query(schema, function (err, rows) {
+ if (err) throw err;
+ done();
+ });
+ });
+ });
+
+ describe('TIME', function () {
+ it('should be well formatted', function (done) {
+ var tests = TEST.format;
+ testDates(tests, function () {
+ done();
+ });
+ });
+ });
+
+ after(function (done) {
+ c.query('drop schema `mysql-express-admin`;',
+ function (err, rows) {
+ if (err) throw err;
+ done();
+ });
+ });
+});
+
+var TEST = {
+ format: [
+ // D HH:MM:SS, D HH:MM, D HH
+ '33 24:59:59', '33 24:59', '33 24',
+ // HH:MM:SS, HH:MM, SS
+ '24:59:59', '24:59', '59',
+ '837:59:59', '837:59', '837',
+ // HHMMSS
+ '245959',
+ // HHHMMSS
+ '8355959', '8355959w', '8355959 w',
+ // single value for hour/minute/second
+ '1:2:3',
+ // after time
+ '33 24:59:59 w', '33 24:59:59w',
+ '24:59:59 w', '24:59:59w',
+ '245959w', '245959 w',
+ /*invalid*/
+ // separator - ~`!@#$%^&*()-_=+{}[]\\|:;<>,.?/
+ '24-59-59', '24/59/59', '24.59.59',
+ '24~59~59', '24%59%59', '24+59+59',
+ '24w59w59', '24:5959',
+ '24:59 59', '24 59:59', '24 59 59',
+ // out of range
+ '839:59:59', '24:60:59', '24:59:60',
+ '246059', '245960'
+ ]
+};

0 comments on commit 39cd4c2

Please sign in to comment.
Something went wrong with that request. Please try again.