Comparing version 0.1.5 to 0.1.6
@@ -59,2 +59,7 @@ var fs = require("fs"); | ||
}; | ||
/** | ||
* 是否是boolean | ||
* @param {[type]} obj | ||
* @return {Boolean} | ||
*/ | ||
global.is_boolean = function(obj){ | ||
@@ -73,2 +78,23 @@ return obj === true || obj === false; | ||
/** | ||
* 判斷對象是否為空 | ||
* @param {[type]} obj | ||
* @return {Boolean} | ||
*/ | ||
global.is_empty = function(obj){ | ||
if (is_object(obj)) { | ||
return Object.keys(obj).length == 0; | ||
}else if (is_array(obj)) { | ||
return obj.length == 0; | ||
}else if (is_string(obj)) { | ||
return obj.length == 0; | ||
}else if (is_number(obj)) { | ||
return obj === 0; | ||
}else if (obj === null || obj === undefined) { | ||
return true; | ||
}else if (is_boolean(obj)) { | ||
return !obj; | ||
}; | ||
return false; | ||
} | ||
/** | ||
* 是否是个标量 | ||
@@ -75,0 +101,0 @@ * @param {[type]} obj [description] |
/** | ||
* 别名 | ||
* 模块别名,模块名到具体的路径,模块名不能有重复 | ||
* @type {Object} | ||
@@ -4,0 +4,0 @@ */ |
@@ -63,2 +63,3 @@ /** | ||
db_field_version: "", // | ||
db_nums_per_page: 20, //默认每页显示的条数 | ||
@@ -65,0 +66,0 @@ tpl_content_type: "text/html", //模版输出类型 |
@@ -104,6 +104,12 @@ /** | ||
var pathname = urlInfo.pathname || ""; | ||
pathname = pathname.split("/"); | ||
this.http.action = Dispatcher.getAction(pathname.pop() || ""); | ||
this.http.controller = Dispatcher.getController(pathname.pop() || ""); | ||
this.http.group = Dispatcher.getGroup(pathname.pop() || ""); | ||
// 过滤调用pathname最后有/的情况 | ||
pathname = pathname.split("/").filter(function(item){ | ||
item = item.trim(); | ||
if (item) { | ||
return item; | ||
}; | ||
}) | ||
this.http.action = Dispatcher.getAction(pathname.pop()); | ||
this.http.controller = Dispatcher.getController(pathname.pop()); | ||
this.http.group = Dispatcher.getGroup(pathname.pop()); | ||
}, | ||
@@ -133,2 +139,9 @@ getRoute: function(route){ | ||
}, | ||
/** | ||
* 正则匹配路由 | ||
* @param {[type]} matches [description] | ||
* @param {[type]} route [description] | ||
* @param {[type]} pathname [description] | ||
* @return {[type]} [description] | ||
*/ | ||
parseRegExp: function(matches, route, pathname){ | ||
@@ -155,2 +168,7 @@ route = this.getRoute(route); | ||
}, | ||
/** | ||
* 判断是否是一个正则路由,如果是则将字符串转成对应的正则返回 | ||
* @param {[type]} str [description] | ||
* @return {[type]} [description] | ||
*/ | ||
strToReg: function(str){ | ||
@@ -157,0 +175,0 @@ if (str.indexOf('/') !== 0) { |
@@ -71,3 +71,3 @@ /** | ||
match.forEach(function(item){ | ||
var value = self.http.req.post[item] || self.http.req.query[item] || ""; | ||
var value = self.http.post[item] || self.http.query[item] || ""; | ||
data.push(value); | ||
@@ -74,0 +74,0 @@ }); |
@@ -179,2 +179,5 @@ /** | ||
assign: function(name, value){ | ||
if (name === undefined || (is_string(name) && value === undefined)) { | ||
return this.initView().assign(name); | ||
}; | ||
this.initView().assign(name, value); | ||
@@ -181,0 +184,0 @@ return this; |
@@ -22,7 +22,7 @@ var url = require("url"); | ||
selectSql: 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%COMMENT%', | ||
initProp: function(){ | ||
initAttr: function(){ | ||
// 数据库类型 | ||
this.dbType = null; | ||
// 是否自动释放查询结果 | ||
this.autoFree = false; | ||
//this.autoFree = false; | ||
// 当前操作所属的模型名 | ||
@@ -35,10 +35,8 @@ this.model = "_think_"; | ||
this.modelSql = []; | ||
// 最后插入ID | ||
this.lastInsID = null; | ||
// 返回或者影响记录数 | ||
this.numRows = 0; | ||
//this.numRows = 0; | ||
// 返回字段数 | ||
this.numCols = 0; | ||
//this.numCols = 0; | ||
// 事务指令数 | ||
this.transTimes = 0; | ||
//this.transTimes = 0; | ||
// 错误信息 | ||
@@ -51,3 +49,3 @@ this.error = ""; | ||
// 当前查询ID | ||
this.queryId = null; | ||
//this.queryId = null; | ||
// 是否已经连接数据库 | ||
@@ -60,4 +58,8 @@ this.connected = false; | ||
init: function(){ | ||
this.initProp(); | ||
this.initAttr(); | ||
}, | ||
/** | ||
* 连接数据库 | ||
* @return {[type]} [description] | ||
*/ | ||
initConnect: function(){ | ||
@@ -68,2 +70,7 @@ if (!this.connected) { | ||
}, | ||
/** | ||
* 解析set集合 | ||
* @param {[type]} data [description] | ||
* @return {[type]} [description] | ||
*/ | ||
parseSet: function(data){ | ||
@@ -80,2 +87,7 @@ data = data || {}; | ||
}, | ||
/** | ||
* 解析字段名 | ||
* @param {[type]} key [description] | ||
* @return {[type]} [description] | ||
*/ | ||
parseKey: function(key){ | ||
@@ -107,2 +119,8 @@ return key; | ||
* field分析 | ||
* parseField("name"); | ||
* parseField("name,email"); | ||
* parseField({ | ||
* xx_name: "name", | ||
* xx_email: "email" | ||
* }) | ||
* @return {[type]} [description] | ||
@@ -151,2 +169,3 @@ */ | ||
} | ||
return ""; | ||
}, | ||
@@ -312,5 +331,15 @@ /** | ||
}, | ||
/** | ||
* 解析limit | ||
* @param {[type]} limit [description] | ||
* @return {[type]} [description] | ||
*/ | ||
parseLimit: function(limit){ | ||
return limit ? (" LIMIT " + limit) : ""; | ||
}, | ||
/** | ||
* 解析join | ||
* @param {[type]} join [description] | ||
* @return {[type]} [description] | ||
*/ | ||
parseJoin: function(join){ | ||
@@ -338,2 +367,7 @@ var joinStr = ""; | ||
}, | ||
/** | ||
* 解析order | ||
* @param {[type]} order [description] | ||
* @return {[type]} [description] | ||
*/ | ||
parseOrder: function(order){ | ||
@@ -393,3 +427,8 @@ var orderStr = ""; | ||
return " FOR UPDATE "; | ||
}, | ||
}, | ||
/** | ||
* 拼接select查询语句 | ||
* @param {[type]} options [description] | ||
* @return {[type]} [description] | ||
*/ | ||
buildSelectSql: function(options){ | ||
@@ -407,3 +446,3 @@ options = options || {}; | ||
page = parseInt(page, 10) || 1; | ||
listRows = listRows || options.limit || 20; | ||
listRows = listRows || options.limit || C('db_nums_per_page'); | ||
var offset = listRows * (page - 1); | ||
@@ -432,2 +471,8 @@ options.limit = offset + "," + listRows; | ||
}, | ||
/** | ||
* 解析sql语句 | ||
* @param {[type]} sql [description] | ||
* @param {[type]} options [description] | ||
* @return {[type]} [description] | ||
*/ | ||
parseSql: function(sql, options){ | ||
@@ -437,5 +482,13 @@ options = options || {}; | ||
return sql.replace(/\%([A-Z]+)\%/g, function(a, type){ | ||
return self[ucfirst(type)](options[type.toLowerCase()] || ""); | ||
type = type.toLowerCase(); | ||
return self["parse" + ucfirst(type)](options[type] || ""); | ||
}) | ||
}, | ||
/** | ||
* 插入一条记录 | ||
* @param {[type]} data [description] | ||
* @param {[type]} options [description] | ||
* @param {[type]} replace [description] | ||
* @return {[type]} [description] | ||
*/ | ||
insert: function(data, options, replace){ | ||
@@ -461,2 +514,37 @@ data = data || {}; | ||
}, | ||
/** | ||
* 插入多条记录 | ||
* @param {[type]} data [description] | ||
* @param {[type]} options [description] | ||
* @param {[type]} replace [description] | ||
* @return {[type]} [description] | ||
*/ | ||
insertAll: function(data, options, replace){ | ||
var fields = Object.keys(data[0]); | ||
var self = this; | ||
fields = fields.map(function(item){ | ||
return self.parseKey(item); | ||
}).join(","); | ||
var values = data.map(function(item){ | ||
var value = []; | ||
for(var key in item){ | ||
var val = item[key]; | ||
val = self.parseValue(val); | ||
if (is_scalar(val)) { | ||
value.push(val); | ||
}; | ||
} | ||
return "(" + value.join(",") + ")"; | ||
}).join(","); | ||
var sql = replace ? "REPLACE" : "INSERT"; | ||
sql += " INTO " + this.parseTable(options.table) + "(" + fields + ") VALUES " + values; | ||
return this.execute(sql); | ||
}, | ||
/** | ||
* 从一个选择条件的结果插入记录 | ||
* @param {[type]} fields [description] | ||
* @param {[type]} table [description] | ||
* @param {[type]} options [description] | ||
* @return {[type]} [description] | ||
*/ | ||
selectInsert: function(fields, table, options){ | ||
@@ -476,2 +564,7 @@ options = options || {}; | ||
}, | ||
/** | ||
* 删除记录 | ||
* @param {[type]} options [description] | ||
* @return {[type]} [description] | ||
*/ | ||
delete: function(options){ | ||
@@ -498,3 +591,3 @@ options = options || {}; | ||
update: function(data, options){ | ||
options = options || {} | ||
options = options || {}; | ||
this.model = options.model; | ||
@@ -528,11 +621,17 @@ var sql = [ | ||
if (value !== false) { | ||
return value; | ||
return get_promise(value); | ||
}; | ||
}; | ||
var result = this.query(sql); | ||
if (cache && result !== false) { | ||
S(key, result, cache); | ||
}; | ||
return result; | ||
return this.query(sql).then(function(data){ | ||
if (cache && data !== false) { | ||
S(key, data, cache); | ||
}; | ||
return data; | ||
}); | ||
}, | ||
/** | ||
* 转义字符 | ||
* @param {[type]} str [description] | ||
* @return {[type]} [description] | ||
*/ | ||
escapeString: function(str){ | ||
@@ -559,17 +658,2 @@ if (!str) { | ||
return model ? this.modelSql[model] : this.queryStr; | ||
}, | ||
getLastInsID: function(){ | ||
return this.lastInsID; | ||
}, | ||
getError: function(){ | ||
return this.error; | ||
}, | ||
query: function(){ | ||
}, | ||
execute: function(){ | ||
}, | ||
close: function(){ | ||
} | ||
@@ -576,0 +660,0 @@ } |
@@ -82,3 +82,3 @@ /** | ||
this.http.query = urlInfo.query; | ||
this.http.get = urlInfo.get; | ||
this.http.get = urlInfo.query; | ||
this.http.host = urlInfo.host; | ||
@@ -85,0 +85,0 @@ this.http.hostname = urlInfo.hostname; |
@@ -0,1 +1,3 @@ | ||
var util = require('util'); | ||
var querystring = require('querystring'); | ||
/** | ||
@@ -5,15 +7,2 @@ * Model类 | ||
*/ | ||
var MODEL_INSERT = 1; // 插入模型数据 | ||
var MODEL_UPDATE = 2; // 更新模型数据 | ||
var MODEL_BOTH = 3; // 包含上面两种方式 | ||
var MUST_VALIDATE = 1; // 必须验证 | ||
var EXISTS_VALIDATE = 0; // 表单存在字段则验证 | ||
var VALUE_VALIDATE = 2; // 表单值不为空则验证 | ||
var vm = require("vm"); | ||
var model = module.exports = Class(function(){ | ||
@@ -23,5 +12,5 @@ var _linkNum = []; | ||
return { | ||
initProps: function(){ | ||
initAttr: function(){ | ||
// 当前使用的扩展模型 | ||
this._extModel = null; | ||
//this._extModel = null; | ||
// 当前数据库操作对象 | ||
@@ -46,19 +35,19 @@ this.db = null; | ||
// 字段信息 | ||
this.fields = []; | ||
this.fields = {}; | ||
// 数据信息 | ||
this.data = []; | ||
this._data = {}; | ||
// 查询表达式参数 | ||
this.options = {}; | ||
// 自动验证定义 | ||
this._validate = []; | ||
//this._validate = []; | ||
// 自动完成定义 | ||
this._auto = []; | ||
//this._auto = []; | ||
// 字段映射定义 | ||
this._map = []; | ||
//this._map = []; | ||
// 命名范围定义 | ||
this._scope = []; | ||
//this._scope = []; | ||
// 是否自动检测数据表字段信息 | ||
this.autoCheckFields = true; | ||
// 是否批处理验证 | ||
this.patchValidate = false; | ||
//this.patchValidate = false; | ||
//初始化的promise | ||
@@ -76,6 +65,6 @@ this.promise = null; | ||
init: function(name, tablePrefix, connection){ | ||
this.initProps(); | ||
this.initAttr(); | ||
// 获取模型名称 | ||
if (name) { | ||
if (name.indexOf('.') > -1) { | ||
if (name.indexOf(".") > -1) { | ||
name = name.split("."); | ||
@@ -91,3 +80,3 @@ this.dbName = name[0]; | ||
// 设置表前缀 | ||
this.tablePrefix = tablePrefix === undefined ? (this.tablePrefix || C('db_prefix')) : tablePrefix; | ||
this.tablePrefix = tablePrefix === undefined ? (this.tablePrefix || C("db_prefix")) : tablePrefix; | ||
// 数据库初始化操作 | ||
@@ -100,32 +89,2 @@ // 获取数据库操作对象 | ||
/** | ||
* 获取模型名 | ||
* @access public | ||
* @return string | ||
*/ | ||
getModelName: function(){ | ||
var filename = this.__filename || __filename; | ||
if (!this.name) { | ||
var name = filename.split("/").pop().replace(C('class_file_suffix'), ""); | ||
this.name = name.substr(0, name.length - 5); | ||
}; | ||
return this.name; | ||
}, | ||
/** | ||
* 获取表名 | ||
* @return {[type]} [description] | ||
*/ | ||
getTableName: function(){ | ||
if (!this.trueTableName) { | ||
var tableName = this.tablePrefix || ""; | ||
if (this.tableName) { | ||
tableName += this.tableName; | ||
}else{ | ||
tableName += parse_name(this.name); | ||
} | ||
this.trueTableName = tableName.toLowerCase(); | ||
}; | ||
var tableName = (this.dbName ? this.dbName + "." : "") + this.trueTableName; | ||
return tableName; | ||
}, | ||
/** | ||
* 初始化数据库连接 | ||
@@ -151,3 +110,3 @@ * @access public | ||
delete _db[linkNum]; | ||
return get_promise(false); | ||
return get_promise(this); | ||
} | ||
@@ -166,2 +125,28 @@ if (params) { | ||
/** | ||
* 获取模型名 | ||
* @access public | ||
* @return string | ||
*/ | ||
getModelName: function(){ | ||
var filename = this.__filename || __filename; | ||
if (!this.name) { | ||
var name = filename.split("/").pop().replace(C('class_file_suffix'), ""); | ||
this.name = name.substr(0, name.length - 5); | ||
}; | ||
return this.name; | ||
}, | ||
/** | ||
* 获取表名 | ||
* @return {[type]} [description] | ||
*/ | ||
getTableName: function(){ | ||
if (!this.trueTableName) { | ||
var tableName = this.tablePrefix || ""; | ||
tableName += this.tableName || parse_name(this.name); | ||
this.trueTableName = tableName.toLowerCase(); | ||
}; | ||
var tableName = (this.dbName ? this.dbName + "." : "") + this.trueTableName; | ||
return tableName; | ||
}, | ||
/** | ||
* 获取缓存数据表字段信息的缓存文件 | ||
@@ -182,3 +167,3 @@ * @return {[type]} [description] | ||
// 只在第一次执行记录 | ||
if (!this.fields) { | ||
if (is_empty(this.fields)) { | ||
// 如果数据表字段没有定义则自动获取 | ||
@@ -194,3 +179,3 @@ if (C('db_fields_cache')) { | ||
}; | ||
return get_promise(true); | ||
return get_promise(this.fields); | ||
}, | ||
@@ -204,19 +189,4 @@ /** | ||
var self = this; | ||
return this.getDbFields(this.getTableName(), true).then(function(fields){ | ||
self.fields = { | ||
"_field": Object.keys(fields), | ||
"_autoinc": false | ||
}; | ||
var types = {}; | ||
for(var key in fields){ | ||
var val = fields[key]; | ||
types[key] = val.type; | ||
if (val.primary) { | ||
self.fields['_pk'] = key; | ||
if (val.autoinc) { | ||
self.fields['_autoinc'] = true; | ||
}; | ||
}; | ||
} | ||
self.fields['_type'] = types; | ||
return this.getTableFields(this.getTableName(), true).then(function(fields){ | ||
self.fields = fields; | ||
if (C('db_fields_cache')) { | ||
@@ -226,69 +196,42 @@ F(self.getFieldsCacheFile(), self.fields); | ||
return self.fields; | ||
}); | ||
}) | ||
}, | ||
/** | ||
* 获取数据表里的字段信息 | ||
* @param {[type]} table [description] | ||
* @return {[type]} [description] | ||
* 获取数据表的字段 | ||
* @param {[type]} table | ||
* @param {[type]} all | ||
* @return {[type]} | ||
*/ | ||
getDbFields: function(table, all){ | ||
table = table || this.options.table; | ||
getTableFields: function(table, all){ | ||
if (table === true) { | ||
table = undefined; | ||
all = true; | ||
}; | ||
if (table) { | ||
return this.db.getFields(table).then(function(fields){ | ||
return all ? fields : Object.keys(fields || {}); | ||
return this.db.getFields(table).then(function(data){ | ||
var fields = { | ||
"_field": Object.keys(data), | ||
"_autoinc": false | ||
}; | ||
var types = {}; | ||
for(var key in data){ | ||
var val = data[key]; | ||
types[key] = val.type; | ||
if (val.primary) { | ||
fields['_pk'] = key; | ||
if (val.autoinc) { | ||
fields['_autoinc'] = true; | ||
}; | ||
}; | ||
} | ||
fields['_type'] = types; | ||
return all ? fields : fields["_field"]; | ||
}) | ||
}; | ||
if (this.fields) { | ||
if (!is_empty(this.fields)) { | ||
return get_promise(all ? this.fields : this.fields["_field"]); | ||
}; | ||
return get_promise(false); | ||
return this.getTableFields(this.getTableName(), all); | ||
}, | ||
/** | ||
* 获取一条记录的某个字段值 | ||
* @return {[type]} [description] | ||
*/ | ||
getField: function(field, sepa){ | ||
var options = {field: field}; | ||
options = this.parseOptions(options); | ||
field = field.trim(); | ||
if (field.indexOf(",") > -1) { | ||
if (options.limit === undefined && is_number(sepa)) { | ||
options.limit = sepa; | ||
}; | ||
return this.db.select(options).then(function(data){ | ||
if (data) { | ||
var _field = _field.split(","); | ||
var field = Object.keys(data[0]); | ||
var key = field.shift(); | ||
var key2 = field.shift(); | ||
var cols = {}; | ||
var length = _field.length; | ||
data.forEach(function(item){ | ||
var name = item[key]; | ||
if (length === 2) { | ||
cols[name] = item[key2]; | ||
}else{ | ||
cols[name] = is_string(sepa) ? item.join(sepa) : item; | ||
} | ||
}); | ||
return cols; | ||
}; | ||
return {}; | ||
}) | ||
}else{ | ||
options.limit = is_number(sepa) ? sepa : 1; | ||
return this.db.select(options).then(function(data){ | ||
if (data) { | ||
if (sepa !== true && options.limit == 1) { | ||
return data[0]; | ||
}; | ||
return data.forEach(function(val){ | ||
return val[field]; | ||
}) | ||
}; | ||
return {}; | ||
}) | ||
} | ||
}, | ||
/** | ||
* 获取上一次操作的sql | ||
@@ -348,3 +291,3 @@ * @return {[type]} [description] | ||
where = { | ||
_string: where | ||
"_string": where | ||
} | ||
@@ -360,3 +303,3 @@ }; | ||
field: function(field){ | ||
if (field === true) { | ||
if (!field) { | ||
field = "*"; | ||
@@ -392,28 +335,42 @@ }; | ||
}, | ||
rollback: function(){ | ||
return this.db.rollback(); | ||
/** | ||
* 生成查询SQL 可用于子查询 | ||
* @param {[type]} options [description] | ||
* @return {[type]} [description] | ||
*/ | ||
buildSql: function(options){ | ||
var self = this; | ||
return this.parseOptions(options).then(function(options){ | ||
return "( " + self.db.buildSelectSql(options) + " )"; | ||
}) | ||
}, | ||
commit: function(){ | ||
return this.db.commit(); | ||
}, | ||
startTrans: function(){ | ||
this.commit(); | ||
this.db.startTrans(); | ||
return this; | ||
}, | ||
// rollback: function(){ | ||
// return this.db.rollback(); | ||
// }, | ||
// commit: function(){ | ||
// return this.db.commit(); | ||
// }, | ||
// startTrans: function(){ | ||
// this.commit(); | ||
// this.db.startTrans(); | ||
// return this; | ||
// }, | ||
/** | ||
* 解析参数 | ||
* @param {[type]} options [description] | ||
* @return {[type]} [description] | ||
* @return promise [description] | ||
*/ | ||
parseOptions: function(options){ | ||
options = extend(this.options, options); | ||
// 查询过后清空sql表达式组装 避免影响下次查询 | ||
this.options = {}; | ||
var fields = []; | ||
if (!options.table) { | ||
var promise = null; | ||
//获取数据表下的字段信息 | ||
if (options.table) { | ||
promise = this.getTableFields(options.table); | ||
}else{ | ||
options.table = this.getTableName(); | ||
fields = this.fields; | ||
}else{ | ||
fields = "*"; | ||
promise = get_promise(this.fields["_field"]); | ||
} | ||
//数据表别名 | ||
if (options.alias) { | ||
@@ -423,5 +380,30 @@ options.table += " " + options.alias; | ||
options.modal = this.name; | ||
if (options.where && is_object(where) && fields) { | ||
}; | ||
var self = this; | ||
return promise.then(function(fields){ | ||
// 字段类型验证 | ||
if (options.where && is_object(options.where) && !is_empty(fields)) { | ||
// 对数组查询条件进行字段类型检查 | ||
for(var key in options.where){ | ||
var val = options.where[key]; | ||
key = key.trim(); | ||
if (fields.indexOf(key)) { | ||
if (is_scalar(val)) { | ||
options.where = self.parseType(options.where, key); | ||
}; | ||
}else if(key.substr(0, 1) !== "_" && !(/[\.\|\&]/.test(key))){ | ||
delete options.where[key]; | ||
} | ||
} | ||
}; | ||
options = self._optionsFilter(options); | ||
return options; | ||
}); | ||
}, | ||
/** | ||
* 选项过滤器 | ||
* 具体的Model类里进行实现 | ||
* @param {[type]} options [description] | ||
* @return {[type]} [description] | ||
*/ | ||
_optionsFilter: function(options){ | ||
return options; | ||
@@ -447,2 +429,56 @@ }, | ||
/** | ||
* 对插入到数据库中的数据进行处理 | ||
* @param {[type]} data [description] | ||
* @return {[type]} [description] | ||
*/ | ||
parseData: function(data){ | ||
data = data || {}; | ||
if (!is_empty(this.fields)) { | ||
for(var key in data){ | ||
var val = data[key]; | ||
if (!this.fields["_field"].indexOf(key) > -1) { | ||
delete data[key]; | ||
}else if(is_scalar(val)){ | ||
data = this.parseType(data, key); | ||
} | ||
} | ||
}; | ||
//安全过滤 | ||
if (typeof this.options.filter == 'function') { | ||
for(var key in data){ | ||
data[key] = this.options.filter.call(this, key, data[key]); | ||
} | ||
delete this.options.filter; | ||
}; | ||
data = this._dataFilter(data); | ||
return data; | ||
}, | ||
/** | ||
* 数据过滤器 | ||
* 具体的Model类里进行实现 | ||
* @param {[type]} data [description] | ||
* @return {[type]} [description] | ||
*/ | ||
_dataFilter: function(data){ | ||
return data; | ||
}, | ||
/** | ||
* 数据插入之前操作 | ||
* @param {[type]} data [description] | ||
* @param {[type]} options [description] | ||
* @return {[type]} [description] | ||
*/ | ||
_beforeInsert: function(data, options){ | ||
return data; | ||
}, | ||
/** | ||
* 数据插入之后操作 | ||
* @param {[type]} data [description] | ||
* @param {[type]} options [description] | ||
* @return {[type]} [description] | ||
*/ | ||
_afterInsert: function(data, options){ | ||
return data; | ||
}, | ||
/** | ||
* 添加一条或者多条数据 | ||
@@ -454,22 +490,88 @@ * @param {[type]} data [description] | ||
add: function(data, options, replace){ | ||
data = data || ""; | ||
if (!data) { | ||
if (this.data) { | ||
data = this.data; | ||
this.data = {}; | ||
if (this._data) { | ||
data = this._data; | ||
this._data = {}; | ||
}else{ | ||
throw_error(L("_DATA_TYPE_INVALID_")); | ||
return false; | ||
return get_promise(false); | ||
} | ||
}; | ||
options = this.parseOptions(options); | ||
data = this.facade(data); | ||
data = this.parseData(data); | ||
var self = this; | ||
return this.parseOptions(options).then(function(options){ | ||
data = self._beforeInsert(data, options); | ||
//如果_beforeInsert返回false,则直接返回 | ||
if (data === false) { | ||
return false; | ||
}; | ||
return self.db.insert(data, options, replace).then(function(){ | ||
//获取插入的ID | ||
return self.db.getLastInsID().then(function(id){ | ||
if (id) { | ||
data[self.getPk()] = id; | ||
} | ||
self._afterInsert(data, options); | ||
return id; | ||
}) | ||
}); | ||
}); | ||
}, | ||
/** | ||
* 插入多条数据 | ||
* @param {[type]} data [description] | ||
* @param {[type]} options [description] | ||
* @param {[type]} replace [description] | ||
*/ | ||
addAll: function(data, options, replace){ | ||
if (!is_array(data) || !is_object(data[0])) { | ||
this.error = L("_DATA_TYPE_INVALID_"); | ||
return get_promise(false); | ||
}; | ||
var self = this; | ||
return this.parseOptions(options).then(function(options){ | ||
return self.db.insertAll(data, options, replace).then(function(){ | ||
return self.db.getLastInsID(); | ||
}) | ||
}) | ||
}, | ||
/** | ||
* 删除数据 | ||
* @return {[type]} [description] | ||
*/ | ||
delete: function(){ | ||
delete: function(options){ | ||
if (is_empty(options) && is_empty(this.options.where)) { | ||
// 如果删除条件为空 则删除当前数据对象所对应的记录 | ||
if (!is_empty(this._data) && this._data[this.getPk()]) { | ||
return this.delete(this._data[this.getPk()]); | ||
}else{ | ||
return get_promise(false); | ||
} | ||
}; | ||
var pkValue = ""; | ||
if (is_number(options) || is_string(options)) { | ||
var pk = this.getPk(); | ||
options += ""; | ||
var where = {}; | ||
if (options.indexOf(',') > -1) { | ||
where[pk] = ["IN", options]; | ||
}else{ | ||
where[pk] = options; | ||
} | ||
pkValue = where[pk]; | ||
options = { | ||
"where": where | ||
} | ||
}; | ||
var self = this; | ||
return this.parseOptions(options).then(function(options){ | ||
return self.db.delete(options); | ||
}) | ||
}, | ||
_beforeUpdate: function(data, options){ | ||
return data; | ||
}, | ||
_afterUpdate: function(data, options){ | ||
return data; | ||
}, | ||
/** | ||
@@ -479,9 +581,101 @@ * 更新数据 | ||
*/ | ||
update: function(){ | ||
update: function(data, options){ | ||
if (!data) { | ||
if (this._data) { | ||
data = this._data; | ||
this._data = {}; | ||
}else{ | ||
throw_error(L("_DATA_TYPE_INVALID_")); | ||
return get_promise(false); | ||
} | ||
}; | ||
data = this.parseData(data); | ||
var self = this; | ||
return this.parseOptions(options).then(function(options){ | ||
if (self._beforeUpdate(data, options) === false) { | ||
return false; | ||
}; | ||
var pkValue = ""; | ||
var pk = self.getPk(); | ||
if (is_empty(self.options.where)) { | ||
// 如果存在主键数据 则自动作为更新条件 | ||
if (!is_empty(data[pk])) { | ||
var where = {}; | ||
where[pk] = data[pk]; | ||
options.where = where; | ||
pkValue = data[pk]; | ||
delete data[pk]; | ||
}else{ | ||
self.error = L("_OPERATION_WRONG_"); | ||
return false; | ||
} | ||
}; | ||
return self.db.update(data, options).then(function(data){ | ||
if (data) { | ||
if (pkValue) { | ||
data[pk] = pkValue; | ||
}; | ||
self._afterUpdate(data, options); | ||
return data.affectedRows; | ||
}; | ||
return false; | ||
}) | ||
}) | ||
}, | ||
save: function(options){ | ||
return this.update(options); | ||
/** | ||
* 更新某个字段的值 | ||
* @param {[type]} field [description] | ||
* @param {[type]} value [description] | ||
* @return {[type]} [description] | ||
*/ | ||
updateField: function(field, value){ | ||
var data = {}; | ||
if (is_object(field)) { | ||
data = field; | ||
}else{ | ||
data[field] = value; | ||
} | ||
return this.update(data); | ||
}, | ||
/** | ||
* 字段值增长 | ||
* @return {[type]} [description] | ||
*/ | ||
updateInc: function(field, step){ | ||
step = parseInt(step, 10) || 1; | ||
return this.updateField(field, ["exp", field + "+" + step]); | ||
}, | ||
/** | ||
* 字段值减少 | ||
* @return {[type]} [description] | ||
*/ | ||
updateDec: function(field, step){ | ||
step = parseInt(step, 10) || 1; | ||
return this.updateField(field, ["exp", field + "-" + step]); | ||
}, | ||
/** | ||
* 查询语句的options | ||
* @return {[type]} [description] | ||
*/ | ||
queryOptions: function(options){ | ||
if (is_number(options) || is_string(options)) { | ||
var pk = this.getPk(); | ||
options += ""; | ||
var where = {}; | ||
if (options.indexOf(",") > -1) { | ||
where[pk] = ["IN", options]; | ||
}else{ | ||
where[pk] = options; | ||
} | ||
options = { | ||
"where": where | ||
}; | ||
}else if (!is_empty(options)) { | ||
options = { | ||
"where": options | ||
}; | ||
}; | ||
return options || {}; | ||
}, | ||
/** | ||
* 查询一条数据 | ||
@@ -491,13 +685,9 @@ * @return 返回一个promise | ||
find: function(options){ | ||
if (typeof options == 'number' || is_string(options)) { | ||
var where = {}; | ||
where[this.getPk()] = options; | ||
options = { | ||
'where': where | ||
} | ||
}; | ||
var self = this; | ||
options = this.queryOptions(options); | ||
options.limit = 1; | ||
options = this.parseOptions(options); | ||
return this.db.select(options).then(function(data){ | ||
return data ? data[0] : []; | ||
return this.parseOptions(options).then(function(options){ | ||
return self.db.select(options).then(function(data){ | ||
return data ? data[0] : []; | ||
}) | ||
}); | ||
@@ -510,31 +700,134 @@ }, | ||
select: function(options){ | ||
if (typeof options == 'number' || is_string(options)) { | ||
var pk = this.getPk(); | ||
options = options + ""; | ||
var where = {}; | ||
if (options.indexOf(",") > -1) { | ||
where[pk] = ["IN", options]; | ||
var self = this; | ||
options = this.queryOptions(options); | ||
return this.parseOptions(options).then(function(options){ | ||
return self.db.select(options); | ||
}); | ||
}, | ||
selectAdd: function(fields, table, options){ | ||
var self = this; | ||
return this.parseOptions(options).then(function(options){ | ||
fields = fields || options.field; | ||
table = table || self.getTableName(); | ||
return self.db.selectInsert(fields, table, options); | ||
}); | ||
}, | ||
/** | ||
* 获取一条记录的某个字段值 | ||
* @return {[type]} [description] | ||
*/ | ||
getField: function(field, sepa){ | ||
field = field.trim(); | ||
var options = this.parseOptions({ | ||
"field": field | ||
}); | ||
var multi = false; | ||
if (field.indexOf(",") > -1) { | ||
if (options.limit === undefined && is_number(sepa)) { | ||
options.limit = sepa; | ||
}; | ||
multi = true; | ||
}else{ | ||
options.limit = is_number(sepa) ? sepa : 1; | ||
} | ||
return this.db.select(options).then(function(data){ | ||
if (!data) { | ||
return {}; | ||
}; | ||
if (multi) { | ||
var length = field.split(",").length; | ||
var field = Object.keys(data[0]); | ||
var key = field.shift(); | ||
var key2 = field.shift(); | ||
var cols = {}; | ||
data.forEach(function(item){ | ||
var name = item[key]; | ||
if (length === 2) { | ||
cols[name] = item[key2]; | ||
}else{ | ||
cols[name] = is_string(sepa) ? item.join(sepa) : item; | ||
} | ||
}); | ||
return cols; | ||
}else{ | ||
where[pk] = options; | ||
if (sepa !== true && options.limit == 1) { | ||
return data[0]; | ||
}; | ||
return data.forEach(function(val){ | ||
return val[field]; | ||
}) | ||
} | ||
options = { | ||
where: where | ||
}); | ||
}, | ||
/** | ||
* SQL查询 | ||
* @return {[type]} [description] | ||
*/ | ||
query: function(sql, parse){ | ||
if (parse !== undefined && !is_boolean(parse) && !is_array(parse)) { | ||
parse = [].slice.call(arguments); | ||
parse.shift(); | ||
}; | ||
var self = this; | ||
return this.parseSql.then(function(sql){ | ||
return self.db.query(sql); | ||
}) | ||
}, | ||
/** | ||
* 执行SQL语法,非查询类的SQL语句,返回值为影响的行数 | ||
* @param {[type]} sql [description] | ||
* @param {[type]} parse [description] | ||
* @return {[type]} [description] | ||
*/ | ||
execute: function(sql, parse){ | ||
if (parse !== undefined && !is_boolean(parse) && !is_array(parse)) { | ||
parse = [].slice.call(arguments); | ||
parse.shift(); | ||
}; | ||
var self = this; | ||
return this.parseSql.then(function(sql){ | ||
return self.db.execute(sql); | ||
}) | ||
}, | ||
/** | ||
* 解析SQL语句 | ||
* @return {[type]} [description] | ||
*/ | ||
parseSql: function(sql, parse){ | ||
var promise = null; | ||
var self = this; | ||
if (parse === true) { | ||
promise = this.parseOptions().then(function(options){ | ||
return self.db.parseSql(options); | ||
}) | ||
}else if (is_array(parse)) { | ||
sql = util.format.apply(null, sql, parse); | ||
promise = get_promise(sql); | ||
}else{ | ||
var map = { | ||
"__TABLE__": this.getTableName(), | ||
"__PREFIX__": C('db_prefix') | ||
}; | ||
}else if(options === false){ | ||
options = this.parseOptions({}); | ||
return '( ' + this.db.buildSelectSql() + " )"; | ||
sql = sql.replace(/__[A-Z]__/g, function(a){ | ||
return map[a] || a; | ||
}) | ||
promise = get_promise(sql); | ||
} | ||
options = this.parseOptions(options); | ||
return this.db.select(options); | ||
this.db.setModel(this.name); | ||
return promise; | ||
}, | ||
/** | ||
* 对保存的数据进行处理 | ||
* @param {[type]} data [description] | ||
* @return {[type]} [description] | ||
* 设置数据对象值 | ||
* @return {[type]} [description] | ||
*/ | ||
facade: function(data){ | ||
return data; | ||
}, | ||
_before_write: function(){} | ||
data: function(data){ | ||
if (data === true) { | ||
return this._data; | ||
}; | ||
if (is_string(data)) { | ||
data = querystring.parse(data); | ||
}; | ||
this._data = data; | ||
return this; | ||
} | ||
} | ||
@@ -546,8 +839,4 @@ }).extend(function(){ | ||
var self = this; | ||
this.promise.then(function(data){ | ||
if (!data) { | ||
return false; | ||
}; | ||
var field = data["_field"]; | ||
console.log(field); | ||
this.promise.then(function(){ | ||
var field = self.fields["_field"]; | ||
field.forEach(function(item){ | ||
@@ -567,3 +856,3 @@ var name = "getBy" + parse_name(item, 1); | ||
}) | ||
}) | ||
}); | ||
} | ||
@@ -588,3 +877,16 @@ }; | ||
}); | ||
//方法别名 | ||
var aliasMethodMap = { | ||
update: "save", | ||
updateField: "setField", | ||
updateInc: "setInc", | ||
updateDec: "setDec" | ||
}; | ||
Object.keys(aliasMethodMap).forEach(function(key){ | ||
var value = aliasMethodMap[key]; | ||
methods[value] = function(){ | ||
return this[key].apply(this, arguments); | ||
} | ||
}) | ||
return methods; | ||
}) |
@@ -53,5 +53,5 @@ /** | ||
//加载系统行为配置 | ||
C('sys_tags', require(THINK_PATH + "/Conf/tags.js")); | ||
C('sys_tags', require(THINK_PATH + "/Conf/tag.js")); | ||
//加载用户的行为配置 | ||
var tagFile = COMMON_PATH + "/tags.js"; | ||
var tagFile = COMMON_PATH + "/tag.js"; | ||
if (is_file(tagFile)) { | ||
@@ -88,3 +88,3 @@ C('tags', require(tagFile)); | ||
}, | ||
//模拟PHP的自动加载 | ||
//think_require的自动加载 | ||
autoload: function(cls){ | ||
@@ -91,0 +91,0 @@ var sysfile = cls + ".class.js"; |
@@ -38,2 +38,7 @@ /** | ||
}, | ||
/** | ||
* 自定义正则校验 | ||
* @param {[type]} reg [description] | ||
* @return {[type]} [description] | ||
*/ | ||
regexp: function(reg){ | ||
@@ -98,7 +103,16 @@ return reg.test(this.field); | ||
}, | ||
/** | ||
* 2次值是否一致 | ||
* @param {[type]} field [description] | ||
* @return {[type]} [description] | ||
*/ | ||
confirm: function(field){ | ||
return this.field === field; | ||
}, | ||
/** | ||
* url | ||
* @return {[type]} [description] | ||
*/ | ||
url: function(){ | ||
return this.regexp(/^http(s?):\/\/(?:[A-za-z0-9-]+\.)+[A-za-z]{2,4}(?:[\/\?#][\/=\?%\-&~`@[\]\':+!\.#\w]*)?$/); | ||
}, | ||
@@ -141,8 +155,20 @@ /** | ||
}, | ||
/** | ||
* ip4校验 | ||
* @return {[type]} [description] | ||
*/ | ||
ip4: function(){ | ||
return net.isIPv4(this.field); | ||
}, | ||
/** | ||
* ip6校验 | ||
* @return {[type]} [description] | ||
*/ | ||
ip6: function(){ | ||
return net.isIPv6(this.field); | ||
}, | ||
/** | ||
* ip校验 | ||
* @return {[type]} [description] | ||
*/ | ||
ip: function(){ | ||
@@ -149,0 +175,0 @@ return net.isIP(this.field); |
@@ -13,2 +13,8 @@ /** | ||
assign: function(name, value){ | ||
if (name === undefined) { | ||
return this.tVar; | ||
}; | ||
if (is_string(name) && value === undefined) { | ||
return this.tVar[name]; | ||
}; | ||
if (is_object(name)) { | ||
@@ -15,0 +21,0 @@ this.tVar = extend(this.tVar, name); |
@@ -13,3 +13,10 @@ /** | ||
}; | ||
this.errmsg = ""; | ||
}, | ||
/** | ||
* 连接数据库 | ||
* @param {[type]} config [description] | ||
* @param {[type]} linknum [description] | ||
* @return {[type]} [description] | ||
*/ | ||
connect: function(config, linknum){ | ||
@@ -26,2 +33,7 @@ linknum = linknum || 0; | ||
}, | ||
/** | ||
* 查询一条sql | ||
* @param string str | ||
* @return promise | ||
*/ | ||
query: function(str){ | ||
@@ -37,6 +49,23 @@ this.initConnect(false); | ||
N('db_query', 1); | ||
return this._linkID.query(str); | ||
var self = this; | ||
return this._linkID.query(str).otherwise(function(err){ | ||
self.errmsg = err; | ||
}); | ||
}, | ||
execute: function(str){ | ||
return this.query(str); | ||
this.initConnect(false); | ||
if (!this._linkID) { | ||
return false; | ||
}; | ||
this.queryStr = str; | ||
if (this.queryID) { | ||
this.free(); | ||
}; | ||
N('db_execute', 1); | ||
var self = this; | ||
return this._linkID.query(str).otherwise(function(err){ | ||
self.errmsg = err; | ||
}).then(function(data){ | ||
return data ? data.affectedRows : false; | ||
}) | ||
}, | ||
@@ -83,5 +112,13 @@ /** | ||
}, | ||
error: function(){ | ||
/** | ||
* 获取错误信息 | ||
* @return {[type]} [description] | ||
*/ | ||
getError: function(){ | ||
return this.errmsg; | ||
}, | ||
/** | ||
* 关闭连接 | ||
* @return {[type]} [description] | ||
*/ | ||
close: function(){ | ||
@@ -93,2 +130,7 @@ if (this._linkID) { | ||
}, | ||
/** | ||
* 解析key | ||
* @param {[type]} key [description] | ||
* @return {[type]} [description] | ||
*/ | ||
parseKey: function(key){ | ||
@@ -101,4 +143,16 @@ key = (key || "").trim(); | ||
return key; | ||
}, | ||
/** | ||
* 获取最后插入的ID | ||
* @return {[type]} [description] | ||
*/ | ||
getLastInsID: function(){ | ||
return this.query("SELECT LAST_INSERT_ID()").then(function(data){ | ||
if (data) { | ||
return data[0][Object.keys(data[0])]; | ||
}; | ||
return 0; | ||
}); | ||
} | ||
} | ||
}); |
@@ -26,5 +26,5 @@ /** | ||
if (err) { | ||
return deferred.reject(err); | ||
return deferred.resolve(err); | ||
}; | ||
deferred.resolve(rows, fields); | ||
deferred.resolve(rows || [], fields); | ||
}) | ||
@@ -31,0 +31,0 @@ return deferred.promise; |
var path = require("path"); | ||
//APP根目錄 | ||
if (!global.APP_PATH) { | ||
@@ -7,2 +8,3 @@ global.APP_PATH = path.dirname(__dirname) + "/App"; | ||
} | ||
//RUNTIME目錄 | ||
if (!global.RUNTIME_PATH) { | ||
@@ -13,5 +15,11 @@ global.RUNTIME_PATH = global.APP_PATH + '/Runtime'; | ||
} | ||
//DEBUG模式 | ||
if (global.APP_DEBUG === undefined) { | ||
global.APP_DEBUG = false; | ||
}; | ||
//靜態資源的根目錄, 用於靜態資源也走THINKJS的處理 | ||
if (global.RESOURCE_PATH) { | ||
global.RESOURCE_PATH = ""; | ||
}; | ||
//THINKJS的根目錄 | ||
global.THINK_PATH = __dirname; | ||
@@ -18,0 +26,0 @@ //从package.json文件里获取版本号 |
{ | ||
"name": "thinkjs", | ||
"description": "thinkphp web framework for nodejs", | ||
"version": "0.1.5", | ||
"version": "0.1.6", | ||
"author": { | ||
@@ -6,0 +6,0 @@ "name": "welefen", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
149260
4401
25