sqlite.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. var dbName = ''
  2. var dbPath = ''
  3. var dbFilePath = ''
  4. const andStr = ' and '
  5. const orStr = ' or '
  6. const kongStr = ' '
  7. const douStr = ','
  8. // 事务操作
  9. const transactionBeginStr = 'begin'
  10. const transactionCommitStr = 'commit'
  11. const transactionRollbackStr = 'rollback'
  12. const dbNameKey = 'ljw_db_name_sqlite_key'
  13. const dbFilePathKey = 'ljw_db_file_path_sqlite_key'
  14. /**
  15. * 初始化和开启数据库
  16. */
  17. export const initDB = async (name) => {
  18. // 获取应用操作路径
  19. const dbDir = await new Promise((resolve, reject) => {
  20. plus.io.requestFileSystem(plus.io.PRIVATE_DOC, res => {
  21. console.log('requestFileSystem--res--' + res)
  22. res.root.getDirectory('db', {
  23. create: true
  24. }, res => {
  25. console.log('getDirectory--res--' + res.fullPath)
  26. resolve(res.fullPath)
  27. }, rej => {
  28. console.error('getDirectory--' + rej)
  29. reject(rej)
  30. });
  31. }, rej => {
  32. console.error('requestFileSystem--' + rej)
  33. reject(rej)
  34. })
  35. })
  36. console.log('dbDir--', dbDir)
  37. // 保存路劲
  38. dbName = name
  39. dbPath = dbDir
  40. dbFilePath = dbPath + dbName + '.db'
  41. // 存储一次
  42. uni.setStorageSync(dbNameKey, dbName)
  43. uni.setStorageSync(dbFilePathKey, dbFilePath)
  44. const isOpen = plus.sqlite.isOpenDatabase({
  45. name: dbName,
  46. path: dbFilePath
  47. });
  48. if (!isOpen) {
  49. // 开启数据库
  50. const status = await new Promise((resolve, reject) => {
  51. plus.sqlite.openDatabase({
  52. name: dbName,
  53. path: dbFilePath,
  54. success: function(e) {
  55. console.log('数据库成功开启');
  56. resolve(true)
  57. },
  58. fail: function(e) {
  59. console.error('数据库开启失败--', JSON.stringify(e));
  60. reject(e)
  61. }
  62. });
  63. })
  64. return status
  65. } else {
  66. console.log('数据库已是开启状态!')
  67. return true
  68. }
  69. }
  70. /**
  71. * 关闭数据库
  72. */
  73. export const closeDB = (db_name = '') => {
  74. return new Promise((resolve, reject) => {
  75. plus.sqlite.closeDatabase({
  76. name: dbNameBack(db_name),
  77. success: function(res) {
  78. console.log('数据库关闭ok')
  79. resolve(true)
  80. },
  81. fail: function(e) {
  82. if (e.message.includes('Not Open')) {
  83. resolve(true)
  84. } else {
  85. console.error('数据库关闭fail', e)
  86. }
  87. }
  88. })
  89. })
  90. }
  91. /**
  92. * 开启数据库
  93. */
  94. export const openDB = async (db_name = '', db_FilePath = '') => {
  95. const isOpen = plus.sqlite.isOpenDatabase({
  96. name: dbNameBack(db_name),
  97. path: dbFilePathBack(db_FilePath)
  98. });
  99. if (!isOpen) {
  100. // 开启数据库
  101. const status = await new Promise((resolve, reject) => {
  102. plus.sqlite.openDatabase({
  103. name: dbNameBack(db_name),
  104. path: dbFilePathBack(db_FilePath),
  105. success: function(e) {
  106. console.log('数据库成功开启');
  107. resolve(true)
  108. },
  109. fail: function(e) {
  110. console.error('数据库开启失败--', JSON.stringify(e));
  111. reject(e)
  112. }
  113. });
  114. })
  115. return status
  116. } else {
  117. console.log('数据库已是开启状态!')
  118. return true
  119. }
  120. }
  121. /**
  122. * 新建表 开启数据库后,如果想立即执行,则需要放到initDB 回调函数 或者 使用await
  123. *
  124. `CREATE TABLE if not exists ${EPsqlite.FA_QUESTION} (
  125. id INTEGER PRIMARY KEY AUTOINCREMENT,
  126. template_id INTEGER NOT NULL DEFAULT 0,
  127. appuser_id INTEGER DEFAULT 0,
  128. status TEXT DEFAULT '1'
  129. )`
  130. */
  131. export const createTable = (sql, db_name = '') => {
  132. return new Promise((resolve, reject) => {
  133. plus.sqlite.executeSql({
  134. name: dbNameBack(db_name),
  135. sql: sql,
  136. success: function(e) {
  137. console.log('createTable success!');
  138. resolve(true)
  139. },
  140. fail: function(e) {
  141. console.log('createTable failed: ' + JSON.stringify(e));
  142. reject(e)
  143. }
  144. });
  145. })
  146. }
  147. /**
  148. * 插入数据
  149. */
  150. export const insertData = (tableName, datas, db_name = '') => {
  151. return new Promise((resolve, reject) => {
  152. plus.sqlite.executeSql({
  153. name: dbNameBack(db_name),
  154. sql: disponseInsertData(tableName, datas),
  155. success: function(e) {
  156. console.log('insertData success!');
  157. resolve(e)
  158. },
  159. fail: function(e) {
  160. console.log('insertData failed: ' + JSON.stringify(e));
  161. reject(e)
  162. }
  163. });
  164. })
  165. }
  166. /**
  167. * 查询数据
  168. * order by xx desc/asc
  169. * group by xx
  170. */
  171. export const queryData = (tableName, where, suffixSql = '', db_name = '') => {
  172. return new Promise((resolve, reject) => {
  173. plus.sqlite.selectSql({
  174. name: dbNameBack(db_name),
  175. sql: disponseQueryData(tableName, where) + kongStr + suffixSql,
  176. success: function(e) {
  177. console.log('queryData success!', e);
  178. resolve(sucData(e))
  179. },
  180. fail: function(e) {
  181. console.log('queryData failed: ' + JSON.stringify(e));
  182. reject(failData(e.code, e.message))
  183. }
  184. });
  185. })
  186. }
  187. /**
  188. * 查询数据page
  189. * order by xx desc/asc
  190. * group by xx
  191. */
  192. export const queryDataPage = (tableName, where = {}, suffixSql = '', db_name = '') => {
  193. return new Promise((resolve, reject) => {
  194. queryDataCount(tableName, where).then(res => {
  195. let total = res.data
  196. let pageNo = where.pageNo || 1
  197. let pageSize = where.pageSize || 10
  198. let index = (pageNo - 1) * pageSize
  199. plus.sqlite.selectSql({
  200. name: dbNameBack(db_name),
  201. sql: disponseQueryData(tableName, where) + kongStr + suffixSql + kongStr +
  202. `limit ${index},${pageSize}`,
  203. success: function(e) {
  204. console.log('queryDataPage success!', e);
  205. resolve(sucData(e, total))
  206. },
  207. fail: function(e) {
  208. console.log('queryDataPage failed: ' + JSON.stringify(e));
  209. reject(failData(e.code, e.message))
  210. }
  211. });
  212. })
  213. })
  214. }
  215. /**
  216. * 查询数据总数
  217. */
  218. export const queryDataCount = (tableName, where, db_name = '') => {
  219. return new Promise((resolve, reject) => {
  220. plus.sqlite.selectSql({
  221. name: dbNameBack(db_name),
  222. sql: disponseQueryDataCount(tableName, where),
  223. success: function(e) {
  224. console.log('queryDataPage success!', e);
  225. resolve(sucData(e[0].total))
  226. },
  227. fail: function(e) {
  228. console.log('queryDataPage failed: ' + JSON.stringify(e));
  229. reject(failData(e.code, e.message))
  230. }
  231. });
  232. })
  233. }
  234. /**
  235. * 查询数据原味sql
  236. */
  237. export const selectSqlData = (where, db_name = '') => {
  238. return new Promise((resolve, reject) => {
  239. plus.sqlite.selectSql({
  240. name: dbNameBack(db_name),
  241. sql: where,
  242. success: function(e) {
  243. console.log('selectSqlData success!', e);
  244. resolve(sucData(e))
  245. },
  246. fail: function(e) {
  247. console.log('selectSqlData failed: ' + JSON.stringify(e));
  248. reject(failData(e.code, e.message))
  249. }
  250. });
  251. })
  252. }
  253. /**
  254. * 执行增删改等操作语句数据原味sql
  255. * 清空表数据 同时清空了自增id TRUNCATE TABLE tableName;
  256. * 删除表 DROP TABLE IF EXISTS tableName;
  257. */
  258. export const executeSqlData = (where, db_name = '') => {
  259. return new Promise((resolve, reject) => {
  260. plus.sqlite.executeSql({
  261. name: dbNameBack(db_name),
  262. sql: where,
  263. success: function(e) {
  264. console.log('executeSqlData success!', e);
  265. resolve(sucData(e))
  266. },
  267. fail: function(e) {
  268. console.log('executeSqlData failed: ' + JSON.stringify(e));
  269. reject(failData(e.code, e.message))
  270. }
  271. });
  272. })
  273. }
  274. /**
  275. * 更新数据
  276. */
  277. export const updateData = (tableName, update, where, db_name = '') => {
  278. return new Promise((resolve, reject) => {
  279. plus.sqlite.executeSql({
  280. name: dbNameBack(db_name),
  281. sql: disponseUpdateData(tableName, update, where),
  282. success: function(e) {
  283. console.log('updateData success!', e);
  284. resolve(sucData(e))
  285. },
  286. fail: function(e) {
  287. console.log('updateData failed: ' + JSON.stringify(e));
  288. reject(failData(e.code, e.message))
  289. }
  290. });
  291. })
  292. }
  293. /**
  294. * 删除数据
  295. */
  296. export const deleteData = (tableName, where, db_name = '') => {
  297. return new Promise((resolve, reject) => {
  298. plus.sqlite.executeSql({
  299. name: dbNameBack(db_name),
  300. sql: disponseDeleteData(tableName, where),
  301. success: function(e) {
  302. console.log('deleteData success!', e);
  303. resolve(sucData(e))
  304. },
  305. fail: function(e) {
  306. console.log('deleteData failed: ' + JSON.stringify(e));
  307. reject(failData(e.code, e.message))
  308. }
  309. });
  310. })
  311. }
  312. /**
  313. * 检查表是否存在
  314. */
  315. export const checkTable = (tableName, db_name = '') => {
  316. return new Promise((resolve, reject) => {
  317. plus.sqlite.selectSql({
  318. name: dbNameBack(db_name),
  319. sql: 'select name from sqlite_master where type="table" and name=' + packageStr(tableName),
  320. success: function(e) {
  321. console.log('checkTable success!', e);
  322. resolve(true)
  323. },
  324. fail: function(e) {
  325. console.log('checkTable failed: ' + JSON.stringify(e));
  326. reject(failData(e.code, e.message))
  327. }
  328. });
  329. })
  330. }
  331. /**
  332. * 包装执行事务:支持同步/异步回调
  333. * packageTransaction(()=>{
  334. insertDataLJW('fa_user', {name:'wxyqaz'})
  335. })
  336. */
  337. export const packageTransaction = async (callback, db_name = '') => {
  338. if (typeof callback !== 'function') {
  339. console.error('callback 必须是一个函数');
  340. return;
  341. }
  342. try {
  343. // 开启事务
  344. await transactionBegin(db_name);
  345. // 执行回调(支持异步)
  346. const result = await callback();
  347. // 提交事务
  348. await transactionCommit(db_name);
  349. if (objectIsEmpty(result)) {
  350. result = true
  351. }
  352. console.log('packageTransaction -- 事务提交成功', result);
  353. return result;
  354. } catch (error) {
  355. // 回滚事务
  356. await transactionRollback(db_name);
  357. console.error('事务执行失败,已回滚。错误内容:', error);
  358. // 可选:重新抛出错误供外部处理
  359. throw error;
  360. }
  361. };
  362. /**
  363. * -------------------------------------------------------------------------------------------------------------------------------------------------
  364. * * -------------------------------------------------------------------------------------------------------------------------------------------------
  365. * * -------------------------------------------------------------------------------------------------------------------------------------------------
  366. * * -------------------------------------------------------------------------------------------------------------------------------------------------
  367. * * -------------------------------------------------------------------------------------------------------------------------------------------------
  368. */
  369. const packageStr = (str)=>{
  370. return '"' + str + '"'
  371. }
  372. const transactionBegin = (db_name = '') => {
  373. return new Promise((resolve, reject) => {
  374. // 开启事务
  375. plus.sqlite.transaction({
  376. name: dbNameBack(db_name),
  377. operation: transactionBeginStr,
  378. success: function(e) {
  379. console.log('transaction begin success!', e);
  380. resolve(e)
  381. },
  382. fail: function(e) {
  383. console.log('transaction begin failed: ' + JSON.stringify(e));
  384. reject(failData(e.code, e.message))
  385. }
  386. });
  387. })
  388. }
  389. const transactionCommit = (db_name = '') => {
  390. return new Promise((resolve, reject) => {
  391. // 提交事务
  392. plus.sqlite.transaction({
  393. name: dbNameBack(db_name),
  394. operation: transactionCommitStr,
  395. success: function(e) {
  396. console.log('transaction commit success!', e);
  397. resolve(e)
  398. },
  399. fail: function(e) {
  400. console.log('transaction commit failed: ' + JSON.stringify(e));
  401. reject(failData(e.code, e.message))
  402. }
  403. });
  404. })
  405. }
  406. const transactionRollback = (db_name = '') => {
  407. return new Promise((resolve, reject) => {
  408. // 回滚事务
  409. plus.sqlite.transaction({
  410. name: dbNameBack(db_name),
  411. operation: transactionRollbackStr,
  412. success: function(e) {
  413. console.log('transaction rollback success!', e);
  414. resolve(e)
  415. },
  416. fail: function(e) {
  417. console.log('transaction rollback failed: ' + JSON.stringify(e));
  418. reject(failData(e.code, e.message))
  419. }
  420. });
  421. })
  422. }
  423. const disponseInsertData = (tableName, datas) => {
  424. if (Array.isArray(datas)) {
  425. let arr = [...datas]
  426. var sql = 'insert into ' + tableName + ' (' + Object.keys(arr[0]).join(',') + ') values '
  427. var valueSql = ''
  428. for (const map of arr) {
  429. valueSql += '('
  430. for (const key of Object.keys(map)) {
  431. const value = map[key]
  432. if (typeof value == 'string') {
  433. valueSql += '"' + value + '"' + ','
  434. } else {
  435. valueSql += value + ','
  436. }
  437. }
  438. valueSql = valueSql.substring(0, valueSql.length - 1) + '),'
  439. }
  440. sql += valueSql.substring(0, valueSql.length - 1)
  441. return sql
  442. } else {
  443. let map = {
  444. ...datas
  445. }
  446. var sql = 'insert into ' + tableName + ' (' + Object.keys(map).join(',') + ') values ('
  447. for (const key of Object.keys(map)) {
  448. const value = map[key]
  449. if (typeof value == 'string') {
  450. sql += '"' + value + '"' + ','
  451. } else {
  452. sql += value + ','
  453. }
  454. }
  455. sql = sql.substring(0, sql.length - 1) + ')'
  456. return sql
  457. }
  458. }
  459. const disponseDeleteData = (tableName, where) => {
  460. var sql = `delete from ${tableName} where `
  461. if (typeof where == 'string') {
  462. sql += where
  463. } else {
  464. let map = {
  465. ...where
  466. }
  467. var valueSql = ''
  468. for (const key of Object.keys(map)) {
  469. const value = map[key]
  470. valueSql += key + '='
  471. if (typeof value == 'string') {
  472. valueSql += '"' + value + '"' + andStr
  473. } else {
  474. valueSql += value + andStr
  475. }
  476. }
  477. valueSql = valueSql.substring(0, valueSql.length - andStr.length)
  478. sql += valueSql
  479. }
  480. return sql
  481. }
  482. const disponseUpdateData = (tableName, update, where) => {
  483. var sql = `update ${tableName} set `
  484. if (typeof update == 'string') {
  485. sql += update
  486. } else {
  487. let map = {
  488. ...update
  489. }
  490. var valueSql = ''
  491. for (const key of Object.keys(map)) {
  492. const value = map[key]
  493. valueSql += key + '='
  494. if (typeof value == 'string') {
  495. valueSql += '"' + value + '"' + douStr
  496. } else {
  497. valueSql += value + douStr
  498. }
  499. }
  500. valueSql = valueSql.substring(0, valueSql.length - douStr.length)
  501. sql += valueSql
  502. }
  503. if (!objectIsEmpty(where)) {
  504. sql += kongStr + 'where' + kongStr
  505. if (typeof where == 'string') {
  506. sql += where
  507. } else {
  508. let map = {
  509. ...where
  510. }
  511. var valueSql = ''
  512. for (const key of Object.keys(map)) {
  513. const value = map[key]
  514. valueSql += key + '='
  515. if (typeof value == 'string') {
  516. valueSql += '"' + value + '"' + andStr
  517. } else {
  518. valueSql += value + andStr
  519. }
  520. }
  521. valueSql = valueSql.substring(0, valueSql.length - andStr.length)
  522. sql += valueSql
  523. }
  524. }
  525. return sql
  526. }
  527. const disponseQueryData = (tableName, where) => {
  528. return disponseQuerySql(tableName, where)
  529. }
  530. const disponseQueryDataCount = (tableName, where) => {
  531. return disponseQuerySql(tableName, where, 'count(1) as total')
  532. }
  533. const disponseQuerySql = (tableName, where, sel = '*') => {
  534. var sql = `select ${sel} from ` + tableName
  535. if (objectIsEmpty(where)) {
  536. return sql
  537. }
  538. if (typeof where == 'string') {
  539. sql += kongStr + 'where' + kongStr + where
  540. } else {
  541. let map = {
  542. ...where
  543. }
  544. var valueSql = ''
  545. for (const key of Object.keys(map)) {
  546. if (key === 'pageNo' || key === 'pageSize') {
  547. continue
  548. }
  549. const value = map[key]
  550. valueSql += key + '='
  551. if (typeof value == 'string') {
  552. valueSql += '"' + value + '"' + andStr
  553. } else {
  554. valueSql += value + andStr
  555. }
  556. }
  557. valueSql = valueSql.substring(0, valueSql.length - andStr.length)
  558. sql += kongStr + 'where' + kongStr + valueSql
  559. }
  560. return sql
  561. }
  562. const sucData = (data, total = 0) => {
  563. return {
  564. code: 0,
  565. msg: 'ok',
  566. data: data,
  567. total: total
  568. }
  569. }
  570. const failData = (code = -1, msg = 'fail') => {
  571. return {
  572. code: -1,
  573. msg: msg
  574. }
  575. }
  576. const dbNameBack = (db_name = '') => {
  577. let name = objectIsEmpty(db_name) ? dbName : db_name
  578. if (objectIsEmpty(name)) {
  579. name = uni.getStorageSync(dbNameKey)
  580. }
  581. return name
  582. }
  583. const dbFilePathBack = (db_filePath = '') => {
  584. let filePath = objectIsEmpty(db_filePath) ? dbFilePath : db_filePath
  585. if (objectIsEmpty(filePath)) {
  586. filePath = uni.getStorageSync(dbFilePathKey)
  587. }
  588. return filePath
  589. }
  590. /**
  591. * 空判断
  592. */
  593. const objectIsEmpty = (obj) => {
  594. if (obj === undefined || obj === null) {
  595. return true
  596. }
  597. if (typeof obj === 'string') {
  598. return obj.trim().length === 0
  599. }
  600. if (Array.isArray(obj)) {
  601. return obj.length === 0
  602. }
  603. if (Object.prototype.toString.call(obj) === '[object Object]') {
  604. return Object.keys(obj).length === 0
  605. }
  606. return false
  607. }