我封裝了一個專門用於操做Db模塊的JS類文件。封裝的JS類文件以下:
`1. /**sql
- * @version 1.0 sqlite操做文件
- * @todo 待解決的事情: 採用面向對象實現,這樣在拼接SQL的時候就不用受到上次調用一樣方法的影響,這樣不用再每一個方法都傳一個固定的object對象
- */
- (function(window){
- var u = {};
- u.trim = function(str){
- if(String.prototype.trim){
- return str == null ? "" : String.prototype.trim.call(str);
- }else{
- return str.replace(/(^\s*)|(\s*$)/g, "");
- }
- };
- u.isArray = function(obj){
- if(Array.isArray){
- return Array.isArray(obj);
- }else{
- return obj instanceof Array;
- }
- };
- // 文件操做狀態碼
- u.fsCode = ['沒有錯誤','找不到文件錯誤','不可讀取錯誤','編碼格式錯誤','無效操做錯誤','無效修改錯誤','磁盤溢出錯誤','文件已存在錯誤'];
- u.db = null; // 數據庫對象
- u.dbInfo = null; // 存儲了是否打開了數據庫的相關信息
-
- // 數據庫存放在widget的路徑,對應要複製到fs目錄下的地址固定爲fs://sqlite/
- u.dbPath = {"draft" : "widget://res/draft.sqlite"};
- u.fs = null;
- u.storeArr = []; // 用於存放配置對象的數組
- u.idleIds = []; // 空閒已經被釋放的optionId
- /**
- * 建立一個用於存放各類屬性的對象
- */
- u.createObj = function(){
- if(u.idleIds.length > 0){
- var optionId = u.idleIds.pop();
- }else{
- var optionId = u.storeArr.length;
- }
-
- u.storeArr[optionId] = new Object;
-
- return optionId;
- };
- /**
- * 打開數據庫
- * */
- u._openDb = function(optionId,success,fail){
- if(!u.db){
- u.db = api.require('db');
- }
- if (u.storeArr[optionId].dbName == '') {
- console.error('sqlite數據庫名稱爲空');
- return false;
- }
-
- // 獲取用戶是否已經打開該數據庫了
- if(!u.dbInfo){
- u.dbInfo = $api.getStorage('sqlite_dbInfo');
- if(u.dbInfo == undefined){
- u.dbInfo = {};
- }
- }
-
- if(u.dbInfo[u.storeArr[optionId].dbName]){
- // 該數據庫已經打開了,無需從新打開
- if (typeof success == 'function'){
- success();
- }
- return true;
- }
-
- if (!u.fs) {
- u.fs = api.require('fs');
- }
-
- var filepath = u.getDbPath(u.storeArr[optionId].dbName);
- //先檢查fs 有無數據庫文件
- u.fs.exist({
- path: filepath
- },function(ret,err){
- if(ret.exist){
- //找到數據庫了 並查詢看能用不
- u._simpleOpenDb(optionId,filepath,success,fail);
- }else{
- //沒有找到數據庫 就拷貝一份到fs 目錄
- u.fs.copyTo({
- oldPath: u.dbPath[u.storeArr[optionId].dbName],
- newPath: "fs://sqlite"
- },function(ret,err){
- if (ret.status) {
- u._simpleOpenDb(optionId,filepath,success,fail);
- }else {
- if(typeof fail == 'function'){
- if(err.code != undefined){
- var msg = u.fsCode[err.code];
- }else{
- var msg = '文件複製失敗';
- }
- fail(msg);
- }
- }
- });
- }
- });
- };
- /**
- * 打開數據庫
- */
- u._simpleOpenDb = function(optionId,filepath,success,fail){
- // 打開數據庫
- u.db.openDatabase({
- name : u.storeArr[optionId].dbName,
- path : filepath
- }, function(ret, err) {
- if(ret.status){
- u.dbInfo[u.storeArr[optionId].dbName] = true;
- $api.setStorage('sqlite_dbInfo',u.dbInfo);
- if(typeof success == 'function'){
- success();
- }
- } else {
- if(typeof fail == 'function'){
- fail(err.msg);
- }
- }
- });
- };
- /*
- * 判斷某個數據庫是否已經打開
- * */
- u.judgeDb = function(dbName){
- };
- /**
- * 關閉數據庫
- */
- u.closeDb = function(optionId,callback){
- if(!u.db){
- u.db = api.require('db');
- }
- u.db.closeDatabase({
- name : u.storeArr[optionId].dbName
- }, function(ret, err){
- if(ret.status){
- u.dbInfo[u.storeArr[optionId].dbName] = true;
- $api.setStorage('sqlite_dbInfo',u.dbInfo);
- if(typeof callback == 'function'){
- callback();
- }
- }else{
- api.toast({msg:'關閉數據庫'+dbName+'失敗!'});
- }
- });
- };
- /**
- * 設置要鏈接的數據庫和數據表
- */
- u.config = function(optionId,tbName,dbName){
- u.storeArr[optionId].tbName = tbName;
- u.storeArr[optionId].dbName = dbName;
- u.storeArr[optionId].fields = '*';
- u.storeArr[optionId].where_str = ''; // where條件語句
- u.storeArr[optionId].order_str = ''; // order by語句
- u.storeArr[optionId].limit_str = ''; // limit 子句
- u.storeArr[optionId].group_str = ''; // group by 子句
- u.storeArr[optionId].last_sql = ''; // 最終的SQL語句
- u.storeArr[optionId].distinct_str = '';
- u.storeArr[optionId].having_str = '';
-
- return this;
- };
- /**
- * 獲取數據庫對應的fs路徑
- */
- u.getDbPath = function(dbName){
- return 'fs://sqlite/'+dbName + '.sqlite';
- };
- /**
- * 執行數據庫操做
- */
- u._execute = function(optionId,callback,destroy){
- // 打開數據庫
- u._openDb(optionId,function(){
- u.db.executeSql({
- name: u.storeArr[optionId].dbName,
- sql: u.storeArr[optionId].last_sql
- }, function(ret, err){
- if(ret.status){
- if(undefined == destroy || destroy){
- u.destoryObj(optionId);
- }
- callback && callback(ret.status,'ok');
- }else{
- if(err.msg == 'Database Not Open'){
- // 從新打開一遍數據庫
- var filepath = u.getDbPath(u.storeArr[optionId].dbName);
- u._simpleOpenDb(optionId,filepath,function(){
- u.db.executeSql({
- name: u.storeArr[optionId].dbName,
- sql: u.storeArr[optionId].last_sql
- }, function(ret, err){
- if(undefined == destroy || destroy){
- u.destoryObj(optionId);
- }
- if(ret.status){
- callback && callback(ret.status,'ok');
- }else{
- callback && callback(false,err.msg);
- }
- });
- },function(){
- if(undefined == destroy || destroy){
- u.destoryObj(optionId);
- }
- api.toast({
- msg:msg
- });
- });
- }else{
- if(undefined == destroy || destroy){
- u.destoryObj(optionId);
- }
- callback && callback(false,err.msg);
- }
- }
- });
- },function(msg){
- if(undefined == destroy || destroy){
- u.destoryObj(optionId);
- }
- api.toast({
- msg:msg
- });
- });
- };
- u._query = function(optionId,callback,destroy){
- // 打開數據庫
- u._openDb(optionId,function(){
- u.db.selectSql({
- name : u.storeArr[optionId].dbName,
- sql: u.storeArr[optionId].last_sql
- }, function(ret, err){
- if(ret.status){
- if(undefined == destroy || destroy){
- u.destoryObj(optionId);
- }
- callback && callback(ret.status,ret.data);
- }else{
- if(err.msg == 'Database Not Open'){
- // 從新打開一遍數據庫
- var filepath = u.getDbPath(u.storeArr[optionId].dbName);
- u._simpleOpenDb(optionId,filepath,function(){
- u.db.selectSql({
- name: u.storeArr[optionId].dbName,
- sql: u.storeArr[optionId].last_sql
- }, function(ret, err){
- if(undefined == destroy || destroy){
- u.destoryObj(optionId);
- }
- if(ret.status){
- callback && callback(ret.status,ret.data);
- }else{
- callback && callback(false,err.msg);
- }
- });
- },function(){
- if(undefined == destroy || destroy){
- u.destoryObj(optionId);
- }
- api.toast({
- msg:msg
- });
- });
- }else{
- if(undefined == destroy || destroy){
- u.destoryObj(optionId);
- }
- callback && callback(false,err.msg);
- }
- }
- });
- },function(msg){
- if(undefined == destroy || destroy){
- u.destoryObj(optionId);
- }
- api.toast({
- msg:msg
- });
- });
- };
- /**
- * 查詢
- */
- u.select = function(optionId,callback,destroy){
- u.storeArr[optionId].last_sql = 'SELECT '+u.storeArr[optionId].distinct_str+u.storeArr[optionId].fields+' FROM `'+u.storeArr[optionId].tbName+'` '+u.storeArr[optionId].where_str + u.storeArr[optionId].group_str + u.storeArr[optionId].having_str + u.storeArr[optionId].order_str + u.storeArr[optionId].limit_str;
-
- u._query(optionId,function(status,data){
- callback && callback(status,data);
- },destroy);
- };
- /**
- * 更新
- * @param 是否銷燬對象標識,默認不傳爲true
- */
- u.save = function(optionId,data,callback,destroy){
- if(undefined == data || !data ){
- console.error('請傳遞要更新的參數');
- return false;
- }
-
- if (typeof(data) == 'string') {
- var update = data;
- }else if(typeof(data) == 'object'){
- if(u.isArray(data)){
- console.error('不容許爲數組類型');
- return false;
- }
-
- var str = [],type = '';
- for (var i in data) {
- type = typeof(data[i]);
- switch (type) {
- case "string" :
- str.push(i+'="'+u.quotesConvert(data[i])+'"');
- break;
- case "object" :
- if(undefined == data[i].type){
- console.error(i+'的type參數錯誤');
- return false;
- }
- if(undefined == data[i].value){
- console.error(i+'的value參數錯誤');
- return false;
- }
- if(isNaN(data[i].value)){
- console.error(i+'的value只容許爲數字');
- return false;
- }
- data[i].type = data[i].type.toLowerCase();
- if(data[i].type == 'dec'){
- str.push(i+'='+i+'-'+data[i].value);
- }else if(data[i].type == 'inc'){
- str.push(i+'='+i+'+'+data[i].value);
- }else{
- console.error('更新參數'+i+'的type內容只容許爲dec或inc');
- return false;
- }
- break;
- case 'number' :
- str.push(i+'='+data[i]);
- break;
- default :
- console.error('更新參數'+i+'的內容類型只能爲對象、字符串或數字');
- }
- }
- if(str.length == 0){
- console.error('更新參數爲空');
- return false;
- }
- var update = str.join(',');
- }else{
- console.error('更新參數類型錯誤');
- return false;
- }
- u.storeArr[optionId].last_sql = 'UPDATE `'+u.storeArr[optionId].tbName+'` SET '+update+u.storeArr[optionId].where_str + u.storeArr[optionId].order_str + u.storeArr[optionId].limit_str;
-
- u._execute(optionId,function(status,msg){
- callback && callback(status,msg);
- },destroy);
- };
- /**
- * 添加
- * @param obj option配置選項對象,必須傳遞
- * @param data 插入的數據,數組形式。
- * @param callback 程序執行結果回調函數
- */
- u.add = function(optionId,data,callback,destroy){
- // 拼接SQL
- if(!u.isArray(data) || data.length == 0){
- console.error('請傳遞數組或數組爲空');
- return false;
- }
-
- var element = data.shift();
-
- if(u.isArray(element) && typeof(element) != 'object'){
- console.error('插入的數據類型必須是json對象');
- return false;
- }
-
- var fields = [];
- var values = [];
- for (var i in element) {
- fields.push(i);
- values.push(u.quotesConvert(element[i]));
- }
-
- var fields_str = fields.join('`,`');
-
- if(!fields_str){
- console.error('數據類型有誤');
- return false;
- }
-
- var sql = ' INSERT INTO `'+u.storeArr[optionId].tbName+'`(`'+fields_str+'`) VALUES ("'+values.join('","')+'")';
-
- if (data.length > 0) {
- var val = [],join_str='';
- values=[];
- for (var i = 0; i < data.length;++i) {
- val = [];
- for (var item in data[i]) {
- val.push(u.quotesConvert(data[i][item]));
- }
- join_str = val.join('","');
- if(join_str){
- values.push('("'+join_str+'")');
- }
- }
- u.storeArr[optionId].last_sql = sql +','+values.join(',');
- } else {
- u.storeArr[optionId].last_sql = sql;
- }
-
- // 執行SQL
- u._execute(optionId,function(status,msg){
- callback && callback(status,msg);
- },destroy);
- };
- /**
- * 刪除
- */
- u.del = function(optionId,callback,destroy){
- if(u.storeArr[optionId].where_str == ''){
- console.error('請傳遞where條件');
- return false;
- }
-
- u.storeArr[optionId].last_sql = 'DELETE FROM `'+u.storeArr[optionId].tbName+'` '+u.storeArr[optionId].where_str + u.storeArr[optionId].order_str + u.storeArr[optionId].limit_str;
-
- u._execute(optionId,function(status,msg){
- callback && callback(status,msg);
- },destroy);
- };
- /**
- * group 子句
- */
- u.group = function(optionId,group){
- if(group){
- u.storeArr[optionId].group_str = ' GROUP BY '+group+' ';
- }
-
- return this;
- };
- /**
- * distinct
- */
- u.distinct = function(optionId,distinct){
- if(typeof(distinct) == 'boolean' && distinct){
- u.storeArr[optionId].distinct_str = ' DISTINCT ';
- }
- };
- /**
- * having子句
- */
- u.having = function(optionId,having){
- if(typeof(having) == 'string' && having) {
- u.storeArr[optionId].having_str = ' HAVING '+having+' ';
- }
-
- return this;
- }
- /**
- * order子句
- */
- u.order = function(optionId,order){
- if(order){
- u.storeArr[optionId].order_str = ' ORDER BY '+order;
- }
-
- return this;
- };
- /**
- * limit條件
- */
- u.limit = function(optionId,offset,length){
- if (length == undefined) {
- if(offset){
- u.storeArr[optionId].limit_str = (' LIMIT '+offset);
- }else{
- u.storeArr[optionId].limit_str = '';
- }
- }else if( undefined != offset){
- u.storeArr[optionId].limit_str = (' LIMIT '+offset+','+length);
- }
-
- return this;
- };
- /**
- * 轉換雙引號或單引號前加 \ 符號
- */
- u.quotesConvert = function(text,mark){
- if(typeof(text) != 'string' || !text){
- return text;
- }
-
- if(undefined == mark){
- mark = '"';
- }
-
- mark = mark.substr(0,1);
- if(mark == '\\'){
- mark == '\\\\';
- }
-
- if (mark == '"'){
- var wrapper = '\'';
- }else{
- var wrapper = '"';
- }
- var str = 'var tmp=text.replace(/\\'+mark+'/g,'+wrapper+mark+wrapper+');tmp.replace(/'+mark+'/g,'+wrapper+'\\\\'+mark+wrapper+')'
- var result = eval(str);
- return result;
- };
- /*
- * where條件
- */
- u.where = function(optionId,where){
- var type = typeof(where);
- switch(type){
- case "string" :
- if(!where){
- u.storeArr[optionId].where_str = '';
- }else{
- u.storeArr[optionId].where_str = ' WHERE '+where;
- }
- break;
- case "object" :
- var str = "";
- var exeTimes = 0; // 執行次數,用來獲取是不是json對象的第一個元素
- for (var i in where) {
- i = u.trim(i);
- if(!i){
- continue;
- }
- ++exeTimes;
- if(i == ')'){
- str += ')';
- continue;
- }
- i = i.replace(/\s+/g,' ');
- var arr = i.split(' ');
- if(undefined != arr[0]){
- arr[0] = arr[0].toLowerCase();
- }
- if(undefined != arr[1]){
- arr[1] = arr[1].toLowerCase();
- }
-
- if(exeTimes == 1 || (arr[0] == ')' || arr[0] == '(' || arr[0] == 'and' || arr[0] == 'or' || arr[1] == 'and' || arr[1] == 'or')) {
- if(arr[arr.length - 1] == 'like' || arr[arr.length - 1] == '<' || arr[arr.length - 1] == '>' || arr[arr.length - 1] == '=' || arr[arr.length - 1] == '>=' || arr[arr.length - 1] == '<=' || arr[arr.length - 1] == '<>' ) {
- str += (' '+i);
- } else {
- str += (' '+i+'=');
- }
- }else{
- if(arr[arr.length - 1] != undefined){
- arr[arr.length - 1] = arr[arr.length - 1].toLowerCase();
- }
- if(arr[arr.length - 1] == 'like' || arr[arr.length - 1] == '<' || arr[arr.length - 1] == '>' || arr[arr.length - 1] == '=' || arr[arr.length - 1] == '>=' || arr[arr.length - 1] == '<=' || arr[arr.length - 1] == '<>' ) {
- str += (' AND '+i);
- } else {
- str += (' AND '+i+'=');
- }
- }
- if (typeof(where[i]) == 'string') {
- where[i] = u.quotesConvert(where[i]);
- str += ('"'+where[i]+'"');
- } else if (!isNaN(where[i])) {
- str += where[i];
- }
- }
- if(!str){
- u.storeArr[optionId].where_str = '';
- }else{
- u.storeArr[optionId].where_str = ' WHERE '+str;
- }
- break;
- default :
- console.error('where條件錯誤');
- }
-
- return this;
- };
- /**
- * 指定要查詢的字段
- */
- u.fields = function(optionId,fields){
- if(u.isArray(fields)){
- u.storeArr[optionId].fields = fields.join(',');
- }else if(typeof(fields) == 'string'){
- u.storeArr[optionId].fields = fields;
- }
-
- return this;
- };
- /**
- * SQL語句查詢
- */
- u.query = function(optionId,sql,callback,destroy){
- u.storeArr[optionId].last_sql = sql;
- u._query(optionId,function(status,data){
- callback && callback(status,data);
- },destroy);
- };
- /**
- * SQL語句添加。刪除、更新操做
- */
- u.exec = function(optionId,sql,callback,destroy){
- u.storeArr[optionId].last_sql = sql;
- u._execute(optionId,function(status,msg){
- callback && callback(status,msg);
- },destroy);
- };
- /**
- * 銷燬對象
- */
- u.destoryObj = function(optionId){
- if(undefined != u.storeArr[optionId]){
- u.storeArr[optionId] = null;
- u.idleIds.push(optionId);
- };
- };
- window.$sqlite_api = u;
- })(window);
複製代碼數據庫
用法以下:json
-
- var sql = 'create table goods(id integer primary key autoincrement,'+
- 'name varchar(20),price decimal(10,2),'+
- 'shop_id integer, descri varchar(100),'+
- 'updatetime datetime)';
-
- // 建立Db對象惟一標識,每次操做都必須建立一個新的Db操做標識,每次操做完成該對象會自動被銷燬,每一個方法的第一個參數都必須寫這個惟一標識符
- var optionId1 = $sqlite_api.createObj();
- $sqlite_api.config(optionId1,'','draft').exec(optionId1,sql,function(status,msg){
- if(status){
- alert('sql執行成功');
- }else{
- alert(msg);
- }
- });
- //插入單條數據
- var arr = [{"name":"jim11","age":25,"address":"england","add_time":"2012-01-12 12:12:12"}];
- var optionId2 = $sqlite_api.createObj();
- $sqlite_api.config(optionId2,'user','draft').add(optionId2,arr,function(status,msg){
- if(status){
- alert('插入數據成功');
- }else{
- alert('操做失敗'+msg);
- }
- });
-
- // 插入多條數據
- var arr1 = [{"name":"lucas","age":43,"address":"England","add_time":"2011-01-12 12:12:12"},{"name":"趙老四","age":20,"address":"CHINA","add_time":"2012-01-12 12:12:12"},{"name":"李村品","age":32,"address":"重慶","add_time":"2012-03-12 12:12:12"}];
- var optionId3 = $sqlite_api.createObj();
- $sqlite_api.config(optionId3,'user','draft').add(optionId3,arr1,function(status,msg){
- if(status){
- alert('插入多條數據成功');
- }else{
- alert('多條數據插入失敗'+msg);
- }
- });
-
- // 讀取全表數據
- var optionId4 = $sqlite_api.createObj();
- $sqlite_api.config(optionId4,'user','draft').select(optionId4,function(status,data){
- if(status){
- alert('讀取成功1'+JSON.stringify({"data":data}));
- }else{
- alert('讀取失敗:失敗緣由:'+data);
- }
- });
- // 讀取指定數據
- var optionId5 = $sqlite_api.createObj();
- $sqlite_api.config(optionId5,'user','draft').where(optionId5,{"name":"lucy","age >":10}).select(optionId5,function(status,data){
- if(status){
- alert('讀取成功2'+JSON.stringify({"data":data}));
- }else{
- alert('讀取失敗:失敗緣由:'+data);
- }
- });
- //var optionId6 = $sqlite_api.createObj();
- $sqlite_api.config(optionId6,'user','draft').where(optionId6,{"(name LIKE":"%lucy%","age >":10,") or (name":"張三",")":""}).select(optionId6,function(status,data){
- if(status){
- alert('讀取成功3'+JSON.stringify({"data":data}));
- }else{
- alert('讀取失敗:失敗緣由:'+data);
- }
- });
- //// 讀取add_time在2012-01-12 12:12:12以後的用戶中年齡最大的用戶的姓名和地址
- var optionId7 = $sqlite_api.createObj();
- $sqlite_api.config(optionId7,'user','draft').order(optionId7,'age desc').limit(optionId7,1).fields(optionId7,['name','address']).where(optionId7,{"add_time >":"2012-01-12 12:12:12"}).select(optionId7,function(status,data){
- if(status){
- alert('讀取成功4'+JSON.stringify({"data":data}));
- }else{
- alert('讀取失敗:失敗緣由:'+data);
- }
- });
-
- // 更新id=1的用戶年齡往上加2,address變動爲西安市
- var optionId8 = $sqlite_api.createObj();
- $sqlite_api.config(optionId8,'user','draft').where(optionId8,{"id":1}).save(optionId8,{"age":{"type":"inc","value":2},"address":"西安市"},function(status,msg){
- if(status){
- alert('SQL執行成功');
- }else{
- alert('失敗緣由1:'+msg);
- }
- });
-
- // // 驗證一下是否是還返回更新成功的提示
- var optionId9 = $sqlite_api.createObj();
- $sqlite_api.config(optionId9,'user','draft').where(optionId9,{"id":1}).save(optionId9,{"age":{"type":"inc","value":2},"address":"西安市"},function(status,msg){
- if(status){
- alert('SQL執行成功');
- }else{
- alert('失敗緣由2:'+msg);
- }
- });
-
- // // 更新id=2的用戶註冊時間爲2014-02-12 14:15:14
- var optionId10 = $sqlite_api.createObj();
- $sqlite_api.config(optionId10,'user','draft').where(optionId10,{"id":2}).save(optionId10,{"add_time":"2014-02-12 14:15:14","address":"重慶市","age":{"type":"inc","value":2}},function(status,msg){
- if(status){
- alert('SQL執行成功');
- }else{
- alert('失敗緣由:'+msg);
- }
- });
-
- var optionId11 = $sqlite_api.createObj();
- $sqlite_api.config(optionId11,'user','draft').where(optionId11,{"id":2,"or id":1}).select(optionId11,function(status,data){
- if(status){
- alert('SQL執行成功'+JSON.stringify({"data":data}));
- }else{
- alert('失敗緣由:'+data);
- }
- });
-
- // 刪除id爲1的記錄
- var optionId12 = $sqlite_api.createObj();
- $sqlite_api.config(optionId12,'user','draft').where(optionId12,{"id":1}).del(optionId12,function(status,msg){
- if(status){
- alert('SQL執行成功');
- }else{
- alert('失敗緣由:'+msg);
- }
- });
_複製代碼_`api