1 var Type = require("./index").Type, 2 comb = require("comb"); 3 4 var stringDefaults = { 5 allowNull : true, 6 primaryKey : false, 7 foreignKey : false, 8 "default" : null, 9 unique : false, 10 description : "" 11 }; 12 13 var getStringType = function(cmpFun) { 14 return function(val) { 15 if (!val) { 16 val = null; 17 } else if (typeof val != "string") { 18 val = "" + val; 19 } 20 cmpFun && cmpFun(val); 21 return val; 22 }; 23 }; 24 25 var checkStringType = function(type, cmpFun) { 26 return function(val) { 27 if (typeof val != "string") throw new Error(type + " requires a string type."); 28 cmpFun && cmpFun(val); 29 }; 30 }; 31 32 //String Types 33 /** 34 * 35 * 36 * Mysql CHAR datatype 37 * 38 * @function 39 * @param {Object} options options for the CHAR data type. 40 * @param {Number} [options.length=255] the length of the field 41 * @param {Boolean} [options.allowNull=true] should the field allow null 42 * @param {Boolean} [options.default = null] default value of the field 43 * @param {Boolean} [options.description = ""] description fo the field. 44 * 45 * @return {Type} A Type representing a CHAR column. 46 * 47 * @name CHAR 48 * @memberOf moose.adapters.mysql.types 49 * 50 */ 51 exports.CHAR = function(options) { 52 var ops = comb.merge({}, stringDefaults, {length : 255, type : "CHAR"}, options || {}); 53 if (ops.length > 4294967295) { 54 throw new Error("Max char type length is 255"); 55 } 56 var cmpFun = function(val) { 57 if (ops.length == undefined && val.length > 255) throw new Error("value not of length " + (ops.length || 255)); 58 else if (val && val.length != ops.length) throw new Error("value not of length " + (ops.length || 255)); 59 }; 60 ops.setSql = getStringType(cmpFun); 61 ops.checkType = checkStringType(ops.type, cmpFun); 62 return new Type(ops); 63 }; 64 65 /** 66 * 67 * 68 * String alias for {@link varchar} datatype. 69 * 70 * @function 71 * @param {Object} options options for the STRING data type. 72 * @param {Number} [options.length=255] the length of the field 73 * @param {Boolean} [options.allowNull=true] should the field allow null 74 * @param {Boolean} [options.default = null] default value of the field 75 * @param {Boolean} [options.description = ""] description fo the field. 76 * 77 * @return {Type} A Type representing a VARCHAR column. 78 * 79 * @name STRING 80 * @memberOf moose.adapters.mysql.types 81 * 82 */ 83 exports.STRING = (exports.VARCHAR = function(options) { 84 var ops = comb.merge({}, stringDefaults, {length : 255, type : "VARCHAR"}, options || {}); 85 if (ops.length > 4294967295) { 86 throw new Error("Max char type length is 255 please use text"); 87 } 88 var cmpFun = function(val) { 89 if ((val.length > ops.length) || val.length > 255) 90 throw new Error("value greater than valid varchar length of " + (ops.length || 255)); 91 }; 92 ops.setSql = getStringType(cmpFun); 93 ops.checkType = checkStringType(ops.type, cmpFun); 94 return new Type(ops); 95 }); 96 97 /** 98 * 99 * Mysql TINYTEXT datatype 100 * 101 * @function 102 * @param {Object} options options for the TINYTEXT data type. 103 * @param {Number} [options.length] the length of the field 104 * @param {Boolean} [options.allowNull=true] should the field allow null 105 * @param {Boolean} [options.default = null] default value of the field 106 * @param {Boolean} [options.description = ""] description fo the field. 107 * 108 * @return {Type} A Type representing a TINYTEXT column. 109 * 110 * @name TINYTEXT 111 * @memberOf moose.adapters.mysql.types 112 * 113 */ 114 exports.TINYTEXT = function(options) { 115 var ops = comb.merge({}, stringDefaults, {length : null, type : "TINYTEXT"}, options || {}); 116 var cmpFun = function(val) { 117 if (val.length > 255) throw new Error("value greater than valid tinytext length of 255"); 118 }; 119 ops.setSql = getStringType(cmpFun); 120 ops.checkType = checkStringType(ops.type, cmpFun); 121 return new Type(ops); 122 }; 123 124 /** 125 * 126 * 127 * Mysql MEDIUMTEXT datatype 128 * 129 * @function 130 * @param {Object} options options for the MEDIUMTEXT data type. 131 * @param {Number} [options.length] the length of the field 132 * @param {Boolean} [options.allowNull=true] should the field allow null 133 * @param {Boolean} [options.default = null] default value of the field 134 * @param {Boolean} [options.description = ""] description fo the field. 135 * 136 * @return {Type} A Type representing a MEDIUMTEXT column. 137 * 138 * @name MEDIUMTEXT 139 * @memberOf moose.adapters.mysql.types 140 * 141 */ 142 exports.MEDIUMTEXT = function(options) { 143 var ops = comb.merge({}, stringDefaults, {length : null, type : "MEDIUMTEXT"}, options || {}); 144 var cmpFun = function(val) { 145 if (val.length > 16777215) throw new Error("value greater than valid tinytext length of 16777215"); 146 }; 147 ops.setSql = getStringType(cmpFun); 148 ops.checkType = checkStringType(ops.type, cmpFun); 149 return new Type(ops); 150 }; 151 152 /** 153 * 154 * 155 * Mysql LONGTEXT datatype 156 * 157 * @function 158 * @param {Object} options options for the LONGTEXT data type. 159 * @param {Number} [options.length] the length of the field 160 * @param {Boolean} [options.allowNull=true] should the field allow null 161 * @param {Boolean} [options.default = null] default value of the field 162 * @param {Boolean} [options.description = ""] description fo the field. 163 * 164 * @return {Type} A Type representing a LONGTEXT column. 165 * 166 * @name LONGTEXT 167 * @memberOf moose.adapters.mysql.types 168 * 169 */ 170 exports.LONGTEXT = function(options) { 171 var ops = comb.merge({}, stringDefaults, {length : null, type : "LONGTEXT"}, options || {}); 172 var cmpFun = function(val) { 173 if (val.length > 4294967295) throw new Error("value greater than valid tinytext length of 4294967295"); 174 }; 175 ops.setSql = getStringType(cmpFun); 176 ops.checkType = checkStringType(ops.type, cmpFun); 177 return new Type(ops); 178 }; 179 180 /** 181 * 182 * 183 * Mysql TEXT datatype 184 * 185 * @function 186 * @param {Object} options options for the TEXT data type. 187 * @param {Number} [options.length] the length of the field 188 * @param {Boolean} [options.allowNull=true] should the field allow null 189 * @param {Boolean} [options.default = null] default value of the field 190 * @param {Boolean} [options.description = ""] description fo the field. 191 * 192 * @return {Type} A Type representing a TEXT column. 193 * 194 * @name TEXT 195 * @memberOf moose.adapters.mysql.types 196 * 197 */ 198 exports.TEXT = function(options) { 199 var ops = comb.merge({}, stringDefaults, {length : 4294967295, type : "TEXT"}, options || {}); 200 var cmpFun = function(val) { 201 if (val.length > 65535) throw new Error("value greater than valid tinytext length of 65535"); 202 }; 203 ops.setSql = getStringType(cmpFun); 204 ops.checkType = checkStringType(ops.type, cmpFun); 205 return new Type(ops); 206 }; 207 208 209 var checkEnumType = function(enumTypes, type) { 210 var enums = comb.merge([], enumTypes); 211 return function(val) { 212 if (typeof val != "string" || enums.indexOf(val) == -1) { 213 throw new Error(type + " value must be a string and contained in the enum set"); 214 } 215 }; 216 }; 217 218 var checkSetType = function(enumTypes, type) { 219 var check = checkEnumType(enumTypes, type); 220 return function(val) { 221 if (typeof val == "string") { 222 return check(val); 223 } 224 val.forEach(function(v) { 225 return check(v); 226 }); 227 }; 228 }; 229 230 231 var getSetType = function(cmpFunc) { 232 return function(val) { 233 if (typeof val == "string") { 234 val = val.split(","); 235 } 236 cmpFunc && cmpFunc(val); 237 return val; 238 }; 239 }; 240 241 /** 242 * 243 * 244 * Mysql ENUM datatype 245 * 246 * @function 247 * @param {Object} options options for the TINYTEXT data type. 248 * @param {Array} options.enums the characters allowed for this ENUM 249 * @param {Number} [options.length] the length of the field 250 * @param {Boolean} [options.allowNull=true] should the field allow null 251 * @param {Boolean} [options.default = null] default value of the field 252 * @param {Boolean} [options.description = ""] description fo the field. 253 * 254 * @return {Type} A Type representing a ENUM column. 255 * 256 * @name ENUM 257 * @memberOf moose.adapters.mysql.types 258 * 259 */ 260 exports.ENUM = function(options) { 261 var ops = comb.merge({}, stringDefaults, {type : "ENUM", enums : []}, options || {}); 262 if (ops.enums && ops.enums.length > 65535) { 263 throw new Error("Max number of enum values is 65535"); 264 } 265 ops.setSql = getStringType(checkEnumType(ops.enums, ops.type)); 266 ops.checkType = checkEnumType(ops.enums, ops.type); 267 return new Type(ops); 268 }; 269 270 /** 271 * 272 * 273 * Mysql SET datatype 274 * 275 * @function 276 * @param {Object} options options for the SET data type. 277 * @param {Array} options.enums the characters allowed in this SET 278 * @param {Number} [options.length] the length of the field 279 * @param {Boolean} [options.allowNull=true] should the field allow null 280 * @param {Boolean} [options.default = null] default value of the field 281 * @param {Boolean} [options.description = ""] description fo the field. 282 * 283 * @return {Type} A Type representing a SET column. 284 * 285 * @name SET 286 * @memberOf moose.adapters.mysql.types 287 * 288 */ 289 exports.SET = function(options) { 290 var ops = comb.merge({}, stringDefaults, {type : "SET", enums : []}, options || {}); 291 if (ops.enums && ops.enums.length > 64) { 292 throw new Error("Max number of enum values is 64"); 293 } 294 ops.setSql = getSetType(checkSetType(ops.enums, ops.type)); 295 ops.checkType = checkSetType(ops.enums, ops.type); 296 return new Type(ops); 297 }; 298