mirror of
https://github.com/leanote/desktop-app.git
synced 2025-10-14 15:11:24 +00:00
sqlite 基本实现
问题: 历史记录, attach 还是不流畅!!
This commit is contained in:
BIN
.gitignore.swp
BIN
.gitignore.swp
Binary file not shown.
30
src/node_modules/db.js
generated
vendored
30
src/node_modules/db.js
generated
vendored
@@ -1,28 +1,2 @@
|
||||
var Datastore = require('nedb');
|
||||
var path = require('path');
|
||||
var Evt = require('evt');
|
||||
|
||||
// 数据库初始化
|
||||
// var dbPath = require('nw.gui').App.dataPath + '/nedb';
|
||||
// var dbPath = Evt.getBasePath() + '/Users/life/Library/Application Support/Leanote' + '/nedb';
|
||||
// nedb2 为了port
|
||||
var dbPath = Evt.getBasePath() + '/nedb2';
|
||||
// console.error(dbPath);
|
||||
|
||||
// test
|
||||
if(dbPath.length < 6) {
|
||||
var dbPath = '/Users/life/Library/Application Support/Leanote' + '/nedb2';
|
||||
}
|
||||
|
||||
// console.log(dbPath);
|
||||
// g, 表全局环境
|
||||
var db = {};
|
||||
var dbNames = ['notebooks', 'notes', 'users', 'tags', 'images', 'attachs', 'noteHistories', 'g'];
|
||||
for(var i in dbNames) {
|
||||
var name = dbNames[i];
|
||||
var p = path.join(dbPath, name + '.db');
|
||||
// console.log(p);
|
||||
db[name] = new Datastore({ filename: p, autoload: true });
|
||||
}
|
||||
module.exports = db;
|
||||
console.log('db inited');
|
||||
// adapter
|
||||
module.exports = require('./db/db_sqlite');
|
28
src/node_modules/db/db_nedb.js
generated
vendored
Normal file
28
src/node_modules/db/db_nedb.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
var Datastore = require('nedb');
|
||||
var path = require('path');
|
||||
var Evt = require('../evt');
|
||||
|
||||
// 数据库初始化
|
||||
// var dbPath = require('nw.gui').App.dataPath + '/nedb';
|
||||
// var dbPath = Evt.getBasePath() + '/Users/life/Library/Application Support/Leanote' + '/nedb';
|
||||
// nedb2 为了port
|
||||
var dbPath = Evt.getBasePath() + '/nedb2';
|
||||
// console.error(dbPath);
|
||||
|
||||
// test
|
||||
if(dbPath.length < 6) {
|
||||
var dbPath = '/Users/life/Library/Application Support/Leanote' + '/nedb2';
|
||||
}
|
||||
|
||||
// console.log(dbPath);
|
||||
// g, 表全局环境
|
||||
var db = {};
|
||||
var dbNames = ['notebooks', 'notes', 'users', 'tags', 'images', 'attachs', 'noteHistories', 'g'];
|
||||
for(var i in dbNames) {
|
||||
var name = dbNames[i];
|
||||
var p = path.join(dbPath, name + '.db');
|
||||
// console.log(p);
|
||||
db[name] = new Datastore({ filename: p, autoload: true });
|
||||
}
|
||||
module.exports = db;
|
||||
console.log('db inited');
|
646
src/node_modules/db/db_sqlite.js
generated
vendored
Normal file
646
src/node_modules/db/db_sqlite.js
generated
vendored
Normal file
@@ -0,0 +1,646 @@
|
||||
var sqlite3 = require('sqlite3');
|
||||
var path = require('path');
|
||||
var Evt = require('../evt');
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
// 数据库初始化
|
||||
var dbPath = Evt.getBasePath() + '/sqlite3';
|
||||
|
||||
// test
|
||||
if(dbPath.length < 6) {
|
||||
var dbPath = '/Users/life/Library/Application Support/Leanote' + '/sqlite3';
|
||||
}
|
||||
|
||||
// g, 表全局环境
|
||||
var dbs = {};
|
||||
var dbNames = ['notebooks', 'notes', 'users', 'tags', 'images', 'attachs', 'noteHistories', 'g'];
|
||||
var sqls = {
|
||||
'notebooks': {
|
||||
'create': ['create table %t(',
|
||||
'NotebookId TEXT PRIMARY KEY,',
|
||||
'ServerNotebookId TEXT,',
|
||||
'UserId TEXT,',
|
||||
'ParentNotebookId TEXT default "",',
|
||||
'Seq INTEGER default -1,',
|
||||
'Title TEXT,',
|
||||
'UrlTitle TEXT,',
|
||||
'NumberNotes INTEGER default 0,',
|
||||
'IsTrash INTEGER default 0,',
|
||||
'IsBlog INTEGER default 0,',
|
||||
'CreatedTime TEXT,',
|
||||
'UpdatedTime TEXT,',
|
||||
'IsDeleted INTEGER default 0,',
|
||||
'LocalIsDelete INTEGER default 0,',
|
||||
'IsDirty INTEGER default 0,',
|
||||
'LocalIsNew INTEGER default 0,',
|
||||
'Usn INTEGER default 0',
|
||||
')'].join(' '),
|
||||
'index': [
|
||||
'CREATE INDEX UserId_index ON %t (UserId)',
|
||||
'CREATE INDEX ServerNotebookId_index ON %t (ServerNotebookId)',
|
||||
'CREATE INDEX Title_index ON %t(Title)',
|
||||
'CREATE INDEX IsDirty_index ON %t(IsDirty)'
|
||||
],
|
||||
},
|
||||
// attachs 用json存
|
||||
'notes': {
|
||||
'create': ['create table %t(',
|
||||
'NoteId TEXT PRIMARY KEY,',
|
||||
'NotebookId TEXT,',
|
||||
'UserId TEXT,',
|
||||
'Title TEXT,',
|
||||
'Desc TEXT,',
|
||||
'ImgSrc TEXT,',
|
||||
'Tags TEXT,',
|
||||
'Abstract TEXT,',
|
||||
'Content TEXT,',
|
||||
'IsMarkdown INTEGER,',
|
||||
'FromUserId TEXT,',
|
||||
'IsBlog INTEGER default 0,',
|
||||
'IsTrash INTEGER default 0,',
|
||||
'Usn INTEGER default 0,',
|
||||
'CreatedTime TEXT,',
|
||||
'UpdatedTime TEXT,',
|
||||
'PublicTime TEXT,',
|
||||
'InitSync INTEGER default 0,',
|
||||
'IsDirty INTEGER default 0,',
|
||||
'ServerNoteId TEXT,',
|
||||
'IsDeleted INTEGER default 0,',
|
||||
'LocalIsDelete INTEGER default 0,',
|
||||
'Star INTEGER default 0,',
|
||||
'LocalIsNew INTEGER default 0,',
|
||||
'Attachs TEXT,',
|
||||
'ContentIsDirty INTEGER default 0,',
|
||||
'IsContentDirty INTEGER default 0',
|
||||
')'].join(' '),
|
||||
'index': [
|
||||
'CREATE INDEX NotebookId_index ON %t (NotebookId)',
|
||||
'CREATE INDEX Title_index ON %t (Title)',
|
||||
'CREATE INDEX UpdatedTime_index ON %t (UpdatedTime)',
|
||||
'CREATE INDEX ServerNoteId_index ON %t (ServerNoteId)',
|
||||
'CREATE INDEX IsDirty_index ON %t (IsDirty)',
|
||||
]
|
||||
},
|
||||
'tags': {
|
||||
'create': ['create table %t(',
|
||||
'TagId TEXT PRIMARY KEY,',
|
||||
'Tag TEXT,',
|
||||
'IsDirty INTEGER default 0,',
|
||||
'IsDeleted INTEGER default 0,',
|
||||
'Usn INTEGER default 0,',
|
||||
'Count INTEGER default 0,',
|
||||
'LocalIsDelete INTEGER default 0,',
|
||||
'CreatedTime TEXT,',
|
||||
'UpdatedTime TEXT',
|
||||
')'].join(' '),
|
||||
'index': [
|
||||
]
|
||||
},
|
||||
// state 是json
|
||||
'users': {
|
||||
'create': ['create table %t(',
|
||||
'_id TEXT PRIMARY KEY,',
|
||||
'UserId TEXT,',
|
||||
'IsActive INTEGER,',
|
||||
'Ok INTEGER,',
|
||||
'Token TEXT,',
|
||||
'Email TEXT,',
|
||||
'Usn INTEGER,',
|
||||
'Username TEXT,',
|
||||
'Pwd TEXT,',
|
||||
'Host TEXT,',
|
||||
'LastSyncTime TEXT,',
|
||||
'LastSyncUsn INTEGER,',
|
||||
'State TEXT',
|
||||
')'].join(' '),
|
||||
'index': [
|
||||
'CREATE INDEX UserId_index ON %t (UserId)',
|
||||
'CREATE INDEX IsActive_index ON %t (IsActive)'
|
||||
]
|
||||
},
|
||||
|
||||
'attachs': {
|
||||
'create': ['create table %t(',
|
||||
'FileId TEXT PRIMARY KEY,',
|
||||
'ServerFileId TEXT,',
|
||||
'UserId TEXT,',
|
||||
'NoteId TEXT,',
|
||||
'Path TEXT,',
|
||||
'Name TEXT,',
|
||||
'Title TEXT,',
|
||||
'IsDirty INTEGER default 0,',
|
||||
'Type TEXT,',
|
||||
'Size INTEGER,',
|
||||
'CreatedTime TEXT',
|
||||
')'].join(' '),
|
||||
'index': [
|
||||
]
|
||||
},
|
||||
|
||||
'images': {
|
||||
'create': ['create table %t(',
|
||||
'FileId TEXT PRIMARY KEY,',
|
||||
'ServerFileId TEXT,',
|
||||
'UserId TEXT,',
|
||||
'NoteId TEXT,',
|
||||
'Path TEXT,',
|
||||
'Name TEXT,',
|
||||
'Title TEXT,',
|
||||
'IsDirty INTEGER default 0,',
|
||||
'Type TEXT,',
|
||||
'Size INTEGER,',
|
||||
'CreatedTime TEXT',
|
||||
')'].join(' '),
|
||||
'index': [
|
||||
]
|
||||
},
|
||||
|
||||
'noteHistories': {
|
||||
'create': ['create table %t(',
|
||||
'_id TEXT PRIMARY KEY,',
|
||||
'NoteId TEXT,',
|
||||
'Histories TEXT,', // [{Content: "xxx", UpdatedTime: new Date()}]
|
||||
'UpdatedTime TEXT',
|
||||
')'].join(' '),
|
||||
'index': [
|
||||
'CREATE INDEX NoteId_index ON %t (NoteId)',
|
||||
'CREATE INDEX UpdatedTime_index ON %t (UpdatedTime)'
|
||||
]
|
||||
},
|
||||
|
||||
'g': {
|
||||
'create': ['create table %t(',
|
||||
'_id TEXT PRIMARY KEY,',
|
||||
'NotebookWidth INTEGER,',
|
||||
'NoteListWidth INTEGER',
|
||||
'MdEditorWidth INTEGER',
|
||||
'MdEditorWidthForWritting INTEGER',
|
||||
'opI1 INTEGER',
|
||||
'opI2 INTEGER',
|
||||
'opS1 TEXT',
|
||||
'opS2 TEXT',
|
||||
'Theme TEXT',
|
||||
')'].join(' '),
|
||||
'index': [
|
||||
]
|
||||
},
|
||||
};
|
||||
|
||||
for(var i in dbNames) {
|
||||
var name = dbNames[i];
|
||||
var tablePath = path.join(dbPath, name + '.db');
|
||||
|
||||
var db = new sqlite3.Database(tablePath);
|
||||
if(!fs.existsSync(tablePath)) {
|
||||
var sql = sqls[name];
|
||||
if(!sql) {
|
||||
return;
|
||||
}
|
||||
|
||||
db.serialize(function() {
|
||||
var cmds = [sql.create].concat(sql.index);
|
||||
for(var i = 0; i < cmds.length; ++i) {
|
||||
var cmd = cmds[i].replace('%t', name);
|
||||
// console.log('run cmd');
|
||||
// console.log(cmd);
|
||||
db.run(cmd);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dbs[name] = db;
|
||||
}
|
||||
|
||||
// 每一种
|
||||
|
||||
function BaseDb(dbname) {
|
||||
this.dbname = dbname;
|
||||
}
|
||||
|
||||
// 插入
|
||||
BaseDb.prototype.insert = function(data, callback) {
|
||||
var me = this;
|
||||
var _db = dbs[me.dbname];
|
||||
var fields = [];
|
||||
var values = [];
|
||||
var valuesToken = [];
|
||||
|
||||
// console.log('insert data...........');
|
||||
// console.log(JSON.stringify(data));
|
||||
|
||||
/*
|
||||
if(me.dbname == 'notebooks' ||
|
||||
me.dbname == 'notes' ||
|
||||
me.dbname == 'tags' ||
|
||||
) {
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
for(var field in data) {
|
||||
var value = data[field];
|
||||
|
||||
value = me.fixValue(field, value);
|
||||
|
||||
fields.push(field);
|
||||
values.push(value);
|
||||
valuesToken.push('?');
|
||||
}
|
||||
var sql = 'INSERT INTO ' + me.dbname + ' (' + fields.join(',') +') VALUES (' + valuesToken.join(',') + ')';
|
||||
console.log(values);
|
||||
console.log(sql);
|
||||
_db.run(sql, values, function(err) {
|
||||
console.log(err + '------');
|
||||
callback && callback(err, data);
|
||||
});
|
||||
};
|
||||
// key in ("life", "xx");
|
||||
BaseDb.prototype._in = function(key, arr) {
|
||||
var me = this;
|
||||
if(!arr) {
|
||||
return '1=1';
|
||||
}
|
||||
for(var i = 0; i < arr; i++) {
|
||||
arr[i] = '"' + arr[i] + '"';
|
||||
}
|
||||
return key + ' in ' + '(' + arr.join(',') + ')';
|
||||
};
|
||||
|
||||
// todo
|
||||
// query = {$in: [], Tags: {$in: [title]}};
|
||||
BaseDb.prototype._where = function(query) {
|
||||
var me = this;
|
||||
// 返回字符串
|
||||
var where = [];
|
||||
for(var field in query) {
|
||||
var value = query[field];
|
||||
if(typeof value == 'boolean') {
|
||||
value = value ? 1 : 0;
|
||||
where.push(field + '="' + value + '" ');
|
||||
}
|
||||
else if(typeof value == 'string') {
|
||||
where.push(field + '="' + value + '" ');
|
||||
}
|
||||
// 如果是日期
|
||||
else if(value instanceof Date) {
|
||||
|
||||
}
|
||||
// 对象类型
|
||||
else {
|
||||
if(field == 'Tags' && value['$in'] && value['$in'].length > 0) {
|
||||
where.push(field + ' "LIKE %' + value['$in'][0] + '%" ');
|
||||
}
|
||||
// $gt ? 搜索
|
||||
// 1) [{Title: reg}, {Content: reg}
|
||||
// 2) [{FileId: {$in: fileIds}}, {ServerFileId: {$in: fileIds}}]
|
||||
// 3) [{LocalIsDelete : { $exists : false }}, {LocalIsDelete: false}]
|
||||
else if(field == '$or') {
|
||||
// console.log(value[0]);
|
||||
var or1 = value[0];
|
||||
var or2 = value[1];
|
||||
|
||||
if(or1['Title']) {
|
||||
var key = or1.Title.toString().replace(/\//g, '');
|
||||
where.push(' (Title LIKE "%' + key + '%" OR Content LIKE "%' + key + '%"' + ') ');
|
||||
}
|
||||
else if(or1['FileId']) {
|
||||
var fileIds = or1['FileId']['$in'];
|
||||
var serverFileIds = or2['ServerFileId']['$in'];
|
||||
|
||||
var orWhere = ' (' + me._in('FileId', fileIds) + ' OR ' + me._in('ServerFileId', serverFileIds) + ') ';
|
||||
where.push(orWhere);
|
||||
}
|
||||
else if(or1['LocalIsDelete']) {
|
||||
where.push(' LocalIsDelete="0" ');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return where.join(' AND ');
|
||||
};
|
||||
|
||||
// 修复值为bool, Tags, Date, json
|
||||
BaseDb.prototype.fixValue = function(key, value) {
|
||||
// bool
|
||||
if(typeof value == 'boolean') {
|
||||
value = value ? 1 : 0;
|
||||
}
|
||||
else if(typeof value == 'object') {
|
||||
// Tgas
|
||||
if(key == 'Tags' && value) {
|
||||
value = value.join(',');
|
||||
}
|
||||
// 日期
|
||||
else if(value instanceof Date) {
|
||||
value = value.getTime();
|
||||
}
|
||||
// json
|
||||
else {
|
||||
value = JSON.stringify(value);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
},
|
||||
|
||||
// update set
|
||||
BaseDb.prototype._set = function(data) {
|
||||
var me = this;
|
||||
data = data['$set'];
|
||||
// 返回字符串
|
||||
var sets = [];
|
||||
var values = [];
|
||||
for(var i in data) {
|
||||
var value = data[i];
|
||||
|
||||
value = me.fixValue(i, value);
|
||||
|
||||
values.push(value);
|
||||
|
||||
sets.push(i + '=?');
|
||||
}
|
||||
return {sets: sets.join(','), values: values};
|
||||
};
|
||||
|
||||
// 更新
|
||||
BaseDb.prototype.update = function(query, set, option, callback) {
|
||||
var me = this;
|
||||
var _db = dbs[me.dbname];
|
||||
|
||||
var where = me._where(query);
|
||||
var setsAndValues = me._set(set);
|
||||
|
||||
var sql = 'UPDATE ' + me.dbname + ' ';
|
||||
if(set) {
|
||||
sql += ' SET ' + setsAndValues.sets;
|
||||
}
|
||||
if(where) {
|
||||
sql += ' WHERE ' + where;
|
||||
}
|
||||
|
||||
if(typeof option == 'function') {
|
||||
callback = option;
|
||||
}
|
||||
|
||||
// console.log(sql);
|
||||
|
||||
_db.run(sql, setsAndValues.values, function(err) {
|
||||
// console.error('update error');
|
||||
if(err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
callback && callback(err, err ? 0 : 1);
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Notes.find(query).sort({'UpdatedTime': -1}).exec(function(err, notes) {
|
||||
if(err) {
|
||||
log(err);
|
||||
return callback && callback(false);
|
||||
}
|
||||
return callback && callback(notes);
|
||||
});
|
||||
*/
|
||||
|
||||
BaseDb.prototype.fixTime = function(row) {
|
||||
if(!row) {
|
||||
return;
|
||||
}
|
||||
row.CreatedTime && (row.CreatedTime = new Date(Math.floor(row.CreatedTime)));
|
||||
row.UpdatedTime && (row.UpdatedTime = new Date(Math.floor(row.UpdatedTime)));
|
||||
row.PublicTime && (row.PublicTime = new Date(Math.floor(row.PublicTime)));
|
||||
};
|
||||
|
||||
BaseDb.prototype.fixRow = function(row) {
|
||||
return row;
|
||||
};
|
||||
|
||||
BaseDb.prototype.fixRows = function(rows) {
|
||||
if(!rows) {
|
||||
return;
|
||||
}
|
||||
for(var i = 0; i < rows.length; ++i) {
|
||||
if(rows[i]) {
|
||||
this.fixTime(rows[i]);
|
||||
rows[i] = this.fixRow(rows[i]);
|
||||
}
|
||||
}
|
||||
return rows;
|
||||
};
|
||||
BaseDb.prototype._find = (function() {
|
||||
var me;
|
||||
|
||||
// var me = this;
|
||||
function F(upper, dbname, query, callback) {
|
||||
me = upper;
|
||||
this.dbname = dbname;
|
||||
this.query = query;
|
||||
this.callback = callback;
|
||||
|
||||
if(callback) {
|
||||
this.exec(callback);
|
||||
}
|
||||
}
|
||||
// limit 15 offset 20 跳过20条记录选出15条记录
|
||||
F.prototype.limit = function(limit, offset) {
|
||||
this.limitQ = limit;
|
||||
this.offset = offset;
|
||||
return this;
|
||||
}
|
||||
F.prototype.sort = function(sort) {
|
||||
this.sortQ = sort;
|
||||
return this;
|
||||
}
|
||||
F.prototype.exec = function(callback) {
|
||||
var where = me._where(this.query);
|
||||
|
||||
// select * from dbname where xxxx order by title desc, createdTime asc
|
||||
|
||||
var sql = 'select * from ' + this.dbname;
|
||||
if (where) {
|
||||
sql += ' where ' + where;
|
||||
}
|
||||
|
||||
if(this.sortQ) {
|
||||
var sortArr = [];
|
||||
for(var i in this.sortQ) {
|
||||
var sortType = this.sortQ[i] < 0 ? 'DESC' : 'ASC';
|
||||
sortArr.push(i + ' ' + sortType + ' ');
|
||||
}
|
||||
|
||||
var sortStr = sortArr.join(', ');
|
||||
if(sortStr) {
|
||||
sql += ' order by ' + sortStr;
|
||||
}
|
||||
}
|
||||
|
||||
if(this.limitQ) {
|
||||
sql += ' limit ' + this.limitQ;
|
||||
}
|
||||
if(this.offset) {
|
||||
sql +=' offset ' + this.offset;
|
||||
}
|
||||
|
||||
console.log(sql);
|
||||
console.log(me.dbname);
|
||||
|
||||
dbs[me.dbname].all(sql, function(err, rows) {
|
||||
var rows = me.fixRows(rows);
|
||||
callback && callback(err, rows);
|
||||
});
|
||||
}
|
||||
return F;
|
||||
})();
|
||||
|
||||
// 查找
|
||||
BaseDb.prototype.find = function(query, callback) {
|
||||
var me = this;
|
||||
return new this._find(this, me.dbname, query, callback);
|
||||
};
|
||||
|
||||
BaseDb.prototype.findOne = function(query, callback) {
|
||||
var me = this;
|
||||
var q = new this._find(this, me.dbname, query);
|
||||
q.limit(1).exec(function(err, rows) {
|
||||
if(!err && rows && rows.length > 0) {
|
||||
var rows = me.fixRows(rows);
|
||||
console.log(rows + '>>>>>>>>>>>>>>>>>');
|
||||
callback && callback(err, rows[0]);
|
||||
}
|
||||
else {
|
||||
callback && callback(err, false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// ok
|
||||
BaseDb.prototype.count = function(query, callback) {
|
||||
var me = this;
|
||||
var sql = 'select count(*) as count from ' + me.dbname;
|
||||
var where = this._where(query);
|
||||
if(where) {
|
||||
sql += ' where ' + where;
|
||||
}
|
||||
dbs[me.dbname].all(sql, function(err, rows) {
|
||||
if(!err && rows) {
|
||||
var row = rows[0];
|
||||
callback && callback(err, row['count']);
|
||||
}
|
||||
else {
|
||||
callback && callback(err, rows);
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Notes.remove({_id: note._id}, function(err, n) {
|
||||
if(err) {
|
||||
callback && callback(false);
|
||||
} else {
|
||||
Notebook.reCountNotebookNumberNotes(note.NotebookId);
|
||||
callback && callback(true);
|
||||
}
|
||||
});
|
||||
*/
|
||||
BaseDb.prototype.remove = function(query, callback) {
|
||||
var me = this;
|
||||
var sql = 'delete from ' + me.dbname;
|
||||
var where = this._where(query);
|
||||
if(where){
|
||||
sql += ' where ' + where;
|
||||
}
|
||||
dbs[me.dbname].run(sql, function(err) {
|
||||
callback && callback(err, err ? 0 : 1);
|
||||
});
|
||||
};
|
||||
|
||||
// 子类继承之
|
||||
|
||||
function Notebooks() {}
|
||||
Notebooks.prototype = new BaseDb('notebooks');
|
||||
|
||||
function Notes() {}
|
||||
Notes.prototype = new BaseDb('notes');
|
||||
Notes.prototype.fixRow = function(row) {
|
||||
if(!row) {
|
||||
return;
|
||||
}
|
||||
if(row.Tags && typeof Tags == 'string') {
|
||||
row.Tags = row.Tags.split(',');
|
||||
}
|
||||
try {
|
||||
row.Attachs && (row.Attachs = JSON.parse(row.Attachs));
|
||||
} catch(e) {
|
||||
row.Attachs = null;
|
||||
}
|
||||
return row;
|
||||
};
|
||||
|
||||
function Tags() {}
|
||||
Tags.prototype = new BaseDb('tags');
|
||||
|
||||
function Users() {}
|
||||
Users.prototype = new BaseDb('users');
|
||||
Users.fixRow = function(row) {
|
||||
var State = row['State'];
|
||||
if(!State) {
|
||||
return row;
|
||||
}
|
||||
row.State = JSON.parse(State);
|
||||
return row;
|
||||
}
|
||||
|
||||
function Attachs() {}
|
||||
Attachs.prototype = new BaseDb('attachs');
|
||||
|
||||
function Images() {}
|
||||
Images.prototype = new BaseDb('images');
|
||||
|
||||
function NoteHistories() {}
|
||||
NoteHistories.prototype = new BaseDb('noteHistories');
|
||||
NoteHistories.fixRow = function(row) {
|
||||
var Histories = row['Histories'];
|
||||
if(!Histories) {
|
||||
return row;
|
||||
}
|
||||
row.Histories = JSON.parse(Histories);
|
||||
return row;
|
||||
}
|
||||
function G() {}
|
||||
G.prototype = new BaseDb('g');
|
||||
|
||||
var exports = {
|
||||
notebooks: new Notebooks(),
|
||||
notes: new Notes(),
|
||||
tags: new Tags(),
|
||||
users: new Users(),
|
||||
attachs: new Attachs(),
|
||||
images: new Images(),
|
||||
noteHistories: new NoteHistories(),
|
||||
g: new G()
|
||||
};
|
||||
|
||||
/*
|
||||
notes.insert({NoteId: 'xxx3', 'title': "你好吗?", 'NotebookId': 'life', Tags: ['red', '你好'], CreatedTime: new Date()}, function(err, data){
|
||||
console.log(err);
|
||||
});
|
||||
notes.update({NoteId: 'xxx3'}, {$set: {title: "你知道的", Tags: [], CreatedTime: new Date()}}, function(err) {
|
||||
console.log(err);
|
||||
});
|
||||
notes.remove({NoteId: 'xxx3'}, function(err, rows) {
|
||||
console.log("??");
|
||||
console.log(err);
|
||||
console.log(rows);
|
||||
});
|
||||
|
||||
exports.notes.find({'$or': [{Title: new RegExp("你")}]}).sort({Title: -1}).exec(function(err, rows) {
|
||||
console.log(err);
|
||||
console.log(rows);
|
||||
});
|
||||
*/
|
||||
|
||||
module.exports = exports;
|
||||
console.log('sqlite3 db inited');
|
475
src/node_modules/db_sqlite.js
generated
vendored
475
src/node_modules/db_sqlite.js
generated
vendored
@@ -1,475 +0,0 @@
|
||||
var sqlite3 = require('sqlite3');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var Evt = require('evt');
|
||||
|
||||
// 数据库初始化
|
||||
// var dbPath = require('nw.gui').App.dataPath + '/nedb';
|
||||
// var dbPath = Evt.getBasePath() + '/Users/life/Library/Application Support/Leanote' + '/nedb';
|
||||
// nedb2 为了port
|
||||
var dbPath = Evt.getBasePath() + '/sqlite3';
|
||||
// console.error(dbPath);
|
||||
|
||||
// test
|
||||
if(dbPath.length < 6) {
|
||||
var dbPath = '/Users/life/Library/Application Support/Leanote' + '/sqlite3';
|
||||
}
|
||||
|
||||
// console.log(dbPath);
|
||||
// g, 表全局环境
|
||||
var dbs = {};
|
||||
var dbNames = ['notebooks', 'notes', 'users', 'tags', 'images', 'attachs', 'noteHistories', 'g'];
|
||||
var sqls = {
|
||||
'notebooks': {
|
||||
'create': `create table %t(
|
||||
NotebookId TEXT PRIMARY KEY,
|
||||
ServerNotebookId TEXT,
|
||||
UserId TEXT,
|
||||
ParentNotebookId TEXT,
|
||||
Seq INTEGER,
|
||||
Title TEXT,
|
||||
UrlTitle TEXT,
|
||||
NumberNotes INTEGER,
|
||||
IsTrash INTEGER,
|
||||
IsBlog INTEGER,
|
||||
CreatedTime TEXT,
|
||||
UpdatedTime TEXT,
|
||||
IsDeleted INTEGER,
|
||||
IsDirty INTEGER,
|
||||
LocalIsNew INTEGER
|
||||
)`,
|
||||
'index': [
|
||||
'CREATE INDEX UserId_index ON %t (UserId)',
|
||||
'CREATE INDEX ServerNotebookId_index ON %t (ServerNotebookId)',
|
||||
'CREATE INDEX Title_index ON %t(Title)',
|
||||
'CREATE INDEX IsDirty_index ON %t(IsDirty)'
|
||||
],
|
||||
},
|
||||
// attachs 用json存
|
||||
'notes': {
|
||||
'create': `create table %t(
|
||||
NoteId TEXT PRIMARY KEY,
|
||||
NotebookId TEXT,
|
||||
UserId TEXT,
|
||||
Title TEXT,
|
||||
Desc TEXT,
|
||||
ImgSrc TEXT,
|
||||
Tags TEXT,
|
||||
Abstract TEXT,
|
||||
Content TEXT,
|
||||
IsMarkdown INTEGER,
|
||||
FromUserId TEXT,
|
||||
IsBlog INTEGER,
|
||||
IsTrash INTEGER,
|
||||
Usn INTEGER,
|
||||
CreatedTime TEXT,
|
||||
UpdatedTime TEXT,
|
||||
PublicTime TEXT,
|
||||
InitSync INTEGER,
|
||||
IsDirty INTEGER,
|
||||
ServerNoteId TEXT,
|
||||
LocalIsDelete INTEGER,
|
||||
Star INTEGER,
|
||||
LocalIsNew INTEGER,
|
||||
Attachs TEXT,
|
||||
IsContentDirty INTEGER
|
||||
)`,
|
||||
'index': [
|
||||
'CREATE INDEX NotebookId_index ON %t (NotebookId)',
|
||||
'CREATE INDEX Title_index ON %t (Title)',
|
||||
'CREATE INDEX UpdatedTime_index ON %t (UpdatedTime)',
|
||||
'CREATE INDEX ServerNoteId_index ON %t (ServerNoteId)',
|
||||
'CREATE INDEX IsDirty_index ON %t (IsDirty)',
|
||||
]
|
||||
},
|
||||
'tags': {
|
||||
'create': `create table %t(
|
||||
TagId TEXT PRIMARY KEY,
|
||||
Tag TEXT,
|
||||
IsDirty INTEGER,
|
||||
Usn INTEGER,
|
||||
Count INTEGER,
|
||||
LocalIsDelete INTEGER,
|
||||
CreatedTime TEXT,
|
||||
UpdatedTime TEXT
|
||||
)`,
|
||||
'index': [
|
||||
]
|
||||
},
|
||||
// state 是json
|
||||
'users': {
|
||||
'create': `create table %t(
|
||||
UserId TEXT PRIMARY KEY,
|
||||
IsActive INTEGER,
|
||||
Ok INTEGER,
|
||||
Token TEXT,
|
||||
Email TEXT,
|
||||
Usn INTEGER,
|
||||
Username TEXT,
|
||||
Pwd TEXT,
|
||||
Host TEXT,
|
||||
LastSyncTime TEXT,
|
||||
LastSyncUsn INTEGER,
|
||||
State TEXT
|
||||
)`,
|
||||
'index': [
|
||||
'CREATE INDEX IsActive_index ON %t (IsActive)'
|
||||
]
|
||||
},
|
||||
|
||||
'attachs': {
|
||||
'create': `create table %t(
|
||||
FileId TEXT PRIMARY KEY,
|
||||
ServerFileId TEXT,
|
||||
UserId TEXT,
|
||||
NoteId TEXT,
|
||||
Path TEXT,
|
||||
Name TEXT,
|
||||
Title TEXT,
|
||||
IsDirty INTEGER,
|
||||
Type TEXT,
|
||||
Size INTEGER,
|
||||
CreatedTime TEXT
|
||||
)`,
|
||||
'index': [
|
||||
]
|
||||
},
|
||||
|
||||
'images': {
|
||||
'create': `create table %t(
|
||||
FileId TEXT PRIMARY KEY,
|
||||
ServerFileId TEXT,
|
||||
UserId TEXT,
|
||||
NoteId TEXT,
|
||||
Path TEXT,
|
||||
Name TEXT,
|
||||
Title TEXT,
|
||||
IsDirty INTEGER,
|
||||
Type TEXT,
|
||||
Size INTEGER,
|
||||
CreatedTime TEXT
|
||||
)`,
|
||||
'index': [
|
||||
]
|
||||
},
|
||||
|
||||
'noteHistories': {
|
||||
'create': `create table %t(
|
||||
HistoryId TEXT PRIMARY KEY,
|
||||
NoteId TEXT,
|
||||
Content TEXT,
|
||||
UpdatedTime TEXT
|
||||
)`,
|
||||
'index': [
|
||||
'CREATE INDEX NoteId_index ON %t (NoteId)',
|
||||
'CREATE INDEX UpdatedTime_index ON %t (UpdatedTime)'
|
||||
]
|
||||
},
|
||||
|
||||
// g必须吗 ?
|
||||
|
||||
}
|
||||
for(var i in dbNames) {
|
||||
var name = dbNames[i];
|
||||
var tablePath = path.join(dbPath, name + '.db');
|
||||
|
||||
if(!fs.existsSync(tablePath)) {
|
||||
var db = new sqlite3.Database(tablePath);
|
||||
var sql = sqls[name];
|
||||
if(!sql) {
|
||||
return;
|
||||
}
|
||||
|
||||
db.serialize(function() {
|
||||
var cmds = [sql.create].concat(sql.index);
|
||||
for(var i = 0; i < cmds.length; ++i) {
|
||||
var cmd = cmds[i].replace('%t', name);
|
||||
console.log('run cmd');
|
||||
console.log(cmd);
|
||||
db.run(cmd);
|
||||
}
|
||||
});
|
||||
|
||||
dbs.'_' + name = db;
|
||||
}
|
||||
}
|
||||
|
||||
// 每一种
|
||||
|
||||
var nedb2Sqlite = {
|
||||
/*
|
||||
Notes.insert(noteOrContent, function (err, newDoc) {
|
||||
},
|
||||
|
||||
Notes.update(
|
||||
{UserId: userId, IsTrash: true},
|
||||
{$set: {LocalIsDelete: true, IsDirty: true}},
|
||||
{multi: true},
|
||||
function(err, n) {
|
||||
// Web.alertWeb(n);
|
||||
callback && callback();
|
||||
});
|
||||
|
||||
Notes.update({NoteId: noteOrContent.NoteId}, { $set: updates }, {}, function (err, numReplaced) {
|
||||
if(err) {
|
||||
|
||||
Notes.find(query).sort({'UpdatedTime': -1}).exec(function(err, notes) {
|
||||
if(err) {
|
||||
log(err);
|
||||
return callback && callback(false);
|
||||
}
|
||||
return callback && callback(notes);
|
||||
});
|
||||
|
||||
Notes.count({NotebookId: notebookId, IsTrash: false, LocalIsDelete: false}, function(err, n) {
|
||||
console.log(n);
|
||||
if(err || n > 0) {
|
||||
return callback(true);
|
||||
}
|
||||
callback(false);
|
||||
});
|
||||
|
||||
Notes.findOne({NoteId: noteId}, function(err, doc) {
|
||||
if(err || !doc) {
|
||||
log('不存在');
|
||||
callback && callback(false);
|
||||
} else {
|
||||
callback && callback(doc);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Notes.remove({_id: note._id}, function(err, n) {
|
||||
if(err) {
|
||||
callback && callback(false);
|
||||
} else {
|
||||
Notebook.reCountNotebookNumberNotes(note.NotebookId);
|
||||
callback && callback(true);
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
// 插入
|
||||
insert: function(dbname, data, callback) {
|
||||
var me = this;
|
||||
var _db = dbs[dbname];
|
||||
var fields = [];
|
||||
var values = [];
|
||||
var valuesToken = [];
|
||||
for(var field in data) {
|
||||
var value = data[field];
|
||||
|
||||
value = me.fixValue(field, value);
|
||||
|
||||
fields.push(field);
|
||||
values.push(value);
|
||||
valuesToken.push('?');
|
||||
}
|
||||
_db.run('INSERT INTO ' + dbname + ' (' + fields.join(',') +') VALUES (' + valuesToken.join(',') + ')', values, function(err) {
|
||||
callback && callback(err, data);
|
||||
});
|
||||
},
|
||||
|
||||
// todo
|
||||
// query = {$in: [], Tags: {$in: [title]}};
|
||||
_where: function(query) {
|
||||
// 返回字符串
|
||||
var where = [];
|
||||
for(var field in query) {
|
||||
var value = query[field];
|
||||
if(typeof value == 'boolean') {
|
||||
value = value ? 1 : 0;
|
||||
}
|
||||
else if(typeof value == 'string') {
|
||||
where.push(field + '="' + v + '" ');
|
||||
}
|
||||
// 如果是日期
|
||||
else if(value instanceof Date) {
|
||||
|
||||
}
|
||||
// 对象类型
|
||||
else {
|
||||
if(field == 'Tags' && value['$in'] && value['$in'].length > 0) {
|
||||
where.push(field + ' "LIKE %' + value['$in'][0] + '%" ');
|
||||
}
|
||||
// $gt ?
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return where.join('AND');
|
||||
},
|
||||
|
||||
// 修复值为bool, Tags, Date, json
|
||||
fixValue: function(key, value) {
|
||||
// bool
|
||||
if(typeof value == 'boolean') {
|
||||
value = value ? 1 : 0;
|
||||
}
|
||||
else if(typeof value == 'object') {
|
||||
// Tgas
|
||||
if(field == 'Tags') {
|
||||
value = value.join(',');
|
||||
}
|
||||
// 日期
|
||||
else if(value instanceof Date) {
|
||||
value = value.getTime();
|
||||
}
|
||||
// json
|
||||
else {
|
||||
value = JSON.stringify(value);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
},
|
||||
|
||||
// update set
|
||||
_set: function(data) {
|
||||
var me = this;
|
||||
data = data['$set'];
|
||||
// 返回字符串
|
||||
var set = [];
|
||||
for(var i in data) {
|
||||
var value = data[i];
|
||||
|
||||
value = me.fixValue(i, value);
|
||||
|
||||
set.push(i + '="' + value + '"');
|
||||
}
|
||||
return set.join(',');
|
||||
},
|
||||
|
||||
// 更新
|
||||
update: function(dbname, query, set, option, callback) {
|
||||
var me = this;
|
||||
var _db = dbs[dbname];
|
||||
|
||||
var where = me._where(query);
|
||||
var set = me._set(set);
|
||||
|
||||
var sql = 'UPDATE tbl SET ' + set;
|
||||
if(where) {
|
||||
sql += ' WHERE ' + where;
|
||||
}
|
||||
|
||||
if(typeof option == 'function') {
|
||||
callback = option;
|
||||
}
|
||||
|
||||
_db.run(sql, function(err) {
|
||||
callback && callback(err, err ? 0 : 1);
|
||||
});
|
||||
},
|
||||
|
||||
/*
|
||||
Notes.find(query).sort({'UpdatedTime': -1}).exec(function(err, notes) {
|
||||
if(err) {
|
||||
log(err);
|
||||
return callback && callback(false);
|
||||
}
|
||||
return callback && callback(notes);
|
||||
});
|
||||
*/
|
||||
_find: (function() {
|
||||
var me = this;
|
||||
function F(dbname, query, callback) {
|
||||
this.query = query;
|
||||
this.callback = callback;
|
||||
|
||||
if(callback) {
|
||||
this.exec(callback);
|
||||
}
|
||||
}
|
||||
// limit 15 offset 20 跳过20条记录选出15条记录
|
||||
F.prototype.limit = function(limit, offset) {
|
||||
this.limitQ = limit;
|
||||
this.offset = offset;
|
||||
}
|
||||
F.prototype.sort = function(sort) {
|
||||
this.sortQ = sort;
|
||||
}
|
||||
F.prototype.exec = function(callback) {
|
||||
if(callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
var where = me._where(query);
|
||||
|
||||
// select * from dbname where xxxx order by title desc, createdTime asc
|
||||
var _db = dbs[this.dbname];
|
||||
|
||||
var sql = 'select * from ' + this.dbname;
|
||||
if (where) {
|
||||
sql += ' where ' + where;
|
||||
}
|
||||
|
||||
if(this.sortQ) {
|
||||
var sortArr = [];
|
||||
for(var i in this.sortQ) {
|
||||
var sortType = this.sortQ[i] < 0 ? 'DESC' : 'ASC';
|
||||
sortArr.push(i + ' ' + sortType + ' ');
|
||||
}
|
||||
|
||||
sql += ' sort by ' + sortArr.join(', ');
|
||||
}
|
||||
|
||||
if(this.limitQ) {
|
||||
sql += ' limit ' + this.limitQ;
|
||||
}
|
||||
if(this.offset) {
|
||||
sql +=' offset ' + this.offset;
|
||||
}
|
||||
|
||||
_db.all(sql, function(err, rows) {
|
||||
this.callback && this.callback(err, rows);
|
||||
});
|
||||
}
|
||||
return F;
|
||||
})(),
|
||||
|
||||
// 查找
|
||||
find: function(dbname, query, callback) {
|
||||
return new this._find(dbname, query, callback);
|
||||
},
|
||||
findOne: function(dbname, query, callback) {
|
||||
var q = new this._find(dbname, query);
|
||||
q.limit(1).exec(callback);
|
||||
},
|
||||
// TODO
|
||||
count: function(dbname, query, callback) {
|
||||
var sql = 'select count(*) from ' + dbname;
|
||||
var where = this._where(query);
|
||||
if(where) {
|
||||
sql += ' where ' + where;
|
||||
}
|
||||
dbs[dbname].all(sql, function(err, rows) {
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
/*
|
||||
Notes.remove({_id: note._id}, function(err, n) {
|
||||
if(err) {
|
||||
callback && callback(false);
|
||||
} else {
|
||||
Notebook.reCountNotebookNumberNotes(note.NotebookId);
|
||||
callback && callback(true);
|
||||
}
|
||||
});
|
||||
*/
|
||||
remove: function(dbname, query, callback) {
|
||||
var sql = 'delete from ' + dbname;
|
||||
var where = this._where(query);
|
||||
if(where){
|
||||
sql += ' where ' + where;
|
||||
}
|
||||
db.run(sql, function(err) {
|
||||
callback && callback(err, err ? 0 : 1);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
module.exports = dbs;
|
||||
console.log('sqlite3 db inited');
|
3
src/node_modules/note.js
generated
vendored
3
src/node_modules/note.js
generated
vendored
@@ -186,7 +186,7 @@ var Note = {
|
||||
}
|
||||
// 更新之
|
||||
else {
|
||||
var histories = history.Histories;
|
||||
var histories = history.Histories || [];
|
||||
histories.push(newHistory);
|
||||
db.noteHistories.update({_id: noteId}, {$set: {Histories: histories, "UpdatedTime": new Date()}});
|
||||
}
|
||||
@@ -1235,7 +1235,6 @@ var Note = {
|
||||
var me = this;
|
||||
Notes.find({UserId: User.getCurActiveUserId(), IsDirty: true}, function(err, notes) {
|
||||
if(err) {
|
||||
log(err);
|
||||
return callback && callback(false);
|
||||
} else {
|
||||
// 每一个笔记得到图片, 附件信息和数据
|
||||
|
Reference in New Issue
Block a user