Browse Source

[add] promised database

B Thibault 8 years ago
parent
commit
915c1ff471
4 changed files with 182 additions and 132 deletions
  1. 5 6
      srv/main.js
  2. 118 87
      srv/src/database.js
  3. 27 17
      srv/src/models/accountConfig.js
  4. 32 22
      srv/src/models/accounts.js

+ 5 - 6
srv/main.js

@@ -2,11 +2,10 @@ process.on("uncaughtException", function (err) {
     console.error('err uncaught Exception  : ', err);
 });
 
-require('./src/database.js').database.initDb((err) => {
-    if (err) {
-        console.error("FATAL: cannot init database ", err);
-    } else {
+require('./src/database.js').database.initDb()
+    .then(() => {
         var server = new (require("./src/httpServ.js").HttpServ)();
-    }
-});
+    }).catch((err) => {
+        console.error("FATAL: cannot init database ", err);
+    });
 

+ 118 - 87
srv/src/database.js

@@ -5,97 +5,119 @@ const sqlite3 = require('sqlite3'),
 const DB_PATH = __dirname +"/../database.sqlite",
     DB_VERSION = 1;
 
-function updateMetaTable(dbObj, currentVersion, cb) {
-    if (!currentVersion) {
-        console.log("creating meta table");
-        dbObj.run('CREATE TABLE IF NOT EXISTS `meta` ('
-            +"`key` STRING PRIMARY KEY NOT NULL,"
-            +"`value` STRING"
-            +');', (err) => {
-            if (err)
-                cb(err);
-            else
-                dbObj.run("INSERT OR REPLACE INTO meta(key, value) VALUES('dbVersion', 1)", cb);
-        });
-    } else if (currentVersion < DB_VERSION) {
-        dbObj.run("INSERT OR REPLACE INTO meta(key, value) VALUES('dbVersion', " +(currentVersion +1) +")", cb);
-    } else {
-        cb(null);
-    }
+function updateMetaTable(dbObj, currentVersion) {
+    return new Promise((success, reject) => {
+        if (!currentVersion) {
+            console.log("creating meta table");
+            dbObj.run('CREATE TABLE IF NOT EXISTS `meta` ('
+                +"`key` STRING PRIMARY KEY NOT NULL,"
+                +"`value` STRING"
+                +');', (err) => {
+                if (err)
+                    reject(err);
+                else
+                    dbObj.run("INSERT OR REPLACE INTO meta(key, value) VALUES('dbVersion', 1)", (err) => {
+                        if (err)
+                            reject(err);
+                        else
+                            success();
+                    });
+            });
+        } else if (currentVersion < DB_VERSION) {
+            dbObj.run("INSERT OR REPLACE INTO meta(key, value) VALUES('dbVersion', " +(currentVersion +1) +")", (err) => {
+                if (err)
+                    reject(err);
+                else
+                    success();
+            });
+        } else {
+            success();
+        }
+    });
 };
 
 function Database() {
     this.db = null;
 };
 
-Database.prototype.updateTables = function(cb, currentVersion) {
-    if (currentVersion === undefined) {
-        this.queryFirst("meta", { "key": "dbVersion" }, (err, res) => {
-            if (res) {
-                if (res["value"] < DB_VERSION) {
-                    // db to be updated
-                    this.updateAllTables([
-                        updateMetaTable,
-                        updateAccountTable,
-                        updateAccountConfigTable
-                    ], 0, res["value"], cb);
+Database.prototype.updateTables = function(currentVersion) {
+    var self = this;
+    return new Promise((success, reject) => {
+        if (currentVersion === undefined) {
+            self.queryFirst("meta", { "key": "dbVersion" }, (err, res) => {
+                if (res) {
+                    if (res["value"] < DB_VERSION) {
+                        // db to be updated
+                        self.updateAllTables([
+                            updateMetaTable,
+                            updateAccountTable,
+                            updateAccountConfigTable
+                        ], 0, res["value"], success, reject);
+                    } else {
+                        // No update found
+                        success();
+                    }
                 } else {
-                    // No update found
-                    cb(null);
+                    // Something goes wrong
+                    reject(err);
                 }
-            } else {
-                // Something goes wrong
-                cb(err);
-            }
-        });
-    } else {
-        this.updateAllTables([
-            updateMetaTable,
-            updateAccountTable,
-            updateAccountConfigTable
-        ], 0, currentVersion, cb);
-    }
+            });
+        } else {
+            self.updateAllTables([
+                updateMetaTable,
+                updateAccountTable,
+                updateAccountConfigTable
+            ], 0, currentVersion, success, reject);
+        }
+    });
 };
 
-Database.prototype.initDb = function(cb) {
+Database.prototype.initDb = function() {
     var self = this;
-    if (!self.db) {
-        self.db = new sqlite3.Database(DB_PATH, sqlite3.OPEN_READWRITE, (err) => {
-            if (err) {
-                if (err.code === "SQLITE_CANTOPEN") {
-                    self.db = new sqlite3.Database(DB_PATH, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => {
-                        if (!err) {
-                            self.updateTables(cb, 0);
-                        } else {
-                            cb(err);
-                        }
-                    });
+    return new Promise((success, promReject) => {
+        if (!self.db) {
+            self.db = new sqlite3.Database(DB_PATH, sqlite3.OPEN_READWRITE, (err) => {
+                if (err) {
+                    if (err.code === "SQLITE_CANTOPEN") {
+                        self.db = new sqlite3.Database(DB_PATH, sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE, (err) => {
+                            if (!err) {
+                                self.updateTables(0)
+                                    .then(() => { success(); })
+                                    .catch((err) => { promReject(err); });
+                            } else {
+                                promReject(err);
+                            }
+                        });
+                    } else {
+                        promReject(err);
+                    }
                 } else {
-                    cb(err);
+                    self.updateTables()
+                        .then(() => { success(); })
+                        .catch((err) => { promReject(err); });
                 }
-            } else {
-                self.updateTables(cb);
-            }
-        });
-    } else {
-        self.updateTables(cb);
-    }
+            });
+        } else {
+            self.updateTables()
+                .then(() => { success(); })
+                .catch((err) => { promReject(err); });
+        }
+    });
 };
 
-Database.prototype.updateAllTables = function(factories, i, currentVersion, cb) {
-    var self = this;
-
+Database.prototype.updateAllTables = function(factories, i, currentVersion, success, reject) {
     if (factories[i]) {
-        factories[i](self.db, currentVersion, (err) => {
-            if (!err)
-                self.updateAllTables(factories, ++i, currentVersion, cb);
-            else
-                cb(err);
-        });
+        factories[i](this.db, currentVersion)
+            .then(() => {
+                this.updateAllTables(factories, ++i, currentVersion, success, reject);
+            })
+            .catch((err) => {
+                reject(err);
+            });
     } else if (currentVersion +1 < DB_VERSION) {
-        this.updateAllTables(factories, 0, currentVersion +1, cb);
+        this.updateAllTables(factories, 0, currentVersion +1, success, reject);
     } else {
-        cb(null);
+        success();
     }
 };
 
@@ -156,32 +178,41 @@ Database.prototype.queryFirst = function(table, fields, cb) {
 Database.prototype.insert = function(table, data, cb) {
     var args = []
         ,keys = []
-        ,templateArgs = [];
+        ,templateArgs = []
+        ,self = this;
     for (var i in data) {
         keys.push('`' +i +'`');
         args.push(data[i]);
         templateArgs.push('?');
     }
 
-    this.db.run("INSERT INTO " +table +" ("+ keys.join(",") +") VALUES(" +templateArgs.join(', ') +")", args, function(err) {
-        if (err) {
-            console.error(err);
-            cb(null);
-        }
-        cb(this.lastID);
+    return new Promise((success, reject) => {
+        self.db.run("INSERT INTO " +table +" ("+ keys.join(",") +") VALUES(" +templateArgs.join(', ') +")", args, (err) => {
+            if (err) {
+                console.error(err);
+                reject();
+            } else {
+                success(this.lastID);
+            }
+        });
     });
 };
 
-Database.prototype.update = function(table, id, fields, cb) {
-    var args = [];
+Database.prototype.update = function(table, id, fields) {
+    var args = [],
+        self = this;
     for (var i in fields)
         args.push(fields[i]);
     args.push(id);
-    this.db.run("UPDATE " +table +" SET `" +Object.keys(fields).join("`=?,`") +"`=? WHERE id=?", args, (err) => {
-        if (err) {
-            console.error(err);
-        }
-        cb();
+    return new Promise((success, reject) => {
+        self.db.run("UPDATE " +table +" SET `" +Object.keys(fields).join("`=?,`") +"`=? WHERE id=?", args, (err) => {
+            if (err) {
+                console.error(err);
+                reject();
+            } else {
+                success();
+            }
+        });
     });
 };
 

+ 27 - 17
srv/src/models/accountConfig.js

@@ -118,14 +118,17 @@ AccountConfigManager.prototype.save = function(account, cb) {
         // insert and save id
         var data = account.toDb();
         data.id = null;
-        db.database.insert(TABLE_NAME, data, (newId) => {
+        db.database.insert(TABLE_NAME, data).then((newId) => {
             account.id = newId;
             account.dirty = false;
             if (cb) cb(account);
         });
     } else if (account.dirty) {
         // update
-        db.database.update(TABLE_NAME, account.id, account.toDb(), () => {
+        db.database.update(TABLE_NAME, account.id, account.toDb()).then(() => {
+            account.dirty = false;
+            if (cb) cb(account);
+        }).catch(() => {
             account.dirty = false;
             if (cb) cb(account);
         });
@@ -165,20 +168,27 @@ AccountConfig.prototype.fromDb = function(dbObj) {
 
 module.exports.accountConfigManager = new AccountConfigManager();
 
-module.exports.updateTable = function(dbObject, currentVersion, cb) {
-    if (!currentVersion) {
-        console.info("Creating table " +TABLE_NAME);
-        dbObject.run('CREATE TABLE IF NOT EXISTS `' +TABLE_NAME +'` ('
-            +"`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
-            +"`accountId` STRING NOT NULL,"
-            +"`serviceId` STRING,"
-            +"`deviceId` STRING,"
-            +"`config` STRING NOT NULL,"
-            +"`modified` INT NOT NULL"
-            +');CREATE INDEX accconfigbyaccount ON ' +TABLE_NAME +'(accountId); CREATE UNIQUE INDEX accconfigUniq ON ' +TABLE_NAME +'(accountId, serviceId, deviceId)', cb);
-        //TODO permanent login token array
-    } else {
-        cb(null);
-    }
+module.exports.updateTable = function(dbObject, currentVersion) {
+    return new Promise((success, reject) => {
+        if (!currentVersion) {
+            console.info("Creating table " +TABLE_NAME);
+            dbObject.run('CREATE TABLE IF NOT EXISTS `' +TABLE_NAME +'` ('
+                +"`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+                +"`accountId` STRING NOT NULL,"
+                +"`serviceId` STRING,"
+                +"`deviceId` STRING,"
+                +"`config` STRING NOT NULL,"
+                +"`modified` INT NOT NULL"
+                +');CREATE INDEX accconfigbyaccount ON ' +TABLE_NAME +'(accountId); CREATE UNIQUE INDEX accconfigUniq ON ' +TABLE_NAME +'(accountId, serviceId, deviceId)', (err) => {
+                    if (err)
+                        reject(err);
+                    else
+                        success();
+                });
+            //TODO permanent login token array
+        } else {
+            success();
+        }
+    });
 };
 

+ 32 - 22
srv/src/models/accounts.js

@@ -124,14 +124,17 @@ AccountManager.prototype.save = function(account, cb) {
         // insert and save id
         var data = account.toDb();
         data.id = null;
-        db.database.insert(TABLE_NAME, data, (newId) => {
-            account.id = newId;
-            account.dirty = false;
-            if (cb) cb(account);
-        });
+        db.database.insert(TABLE_NAME, data).then((newId) => {
+                account.id = newId;
+                account.dirty = false;
+                if (cb) cb(account);
+            });
     } else if (account.dirty) {
         // update
-        db.database.update(TABLE_NAME, account.id, account.toDb(), () => {
+        db.database.update(TABLE_NAME, account.id, account.toDb()).then(() => {
+            account.dirty = false;
+            if (cb) cb(account);
+        }).catch(() => {
             account.dirty = false;
             if (cb) cb(account);
         });
@@ -142,21 +145,28 @@ AccountManager.prototype.save = function(account, cb) {
 
 module.exports.accountManager = new AccountManager();
 
-module.exports.updateTable = function(dbObject, currentVersion, cb) {
-    if (!currentVersion) {
-        console.info("Creating table " +TABLE_NAME);
-        dbObject.run('CREATE TABLE IF NOT EXISTS `' +TABLE_NAME +'` ('
-            +"`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
-            +"`authGoogleUserId` STRING UNIQUE,"
-            +"`authFacebookUserId` STRING UNIQUE,"
-            +"`authSlackUserEmailAndTeam` STRING UNIQUE,"
-            +"`certificates` STRING,"
-            +"`cguReadAndAccepted` BOOLEAN NOT NULL DEFAULT FALSE,"
-            +"`services` STRING NOT NULL"
-            +')', cb);
-        //TODO permanent login token array
-    } else {
-        cb(null);
-    }
+module.exports.updateTable = function(dbObject, currentVersion) {
+    return new Promise((success, reject) => {
+        if (!currentVersion) {
+            console.info("Creating table " +TABLE_NAME);
+            dbObject.run('CREATE TABLE IF NOT EXISTS `' +TABLE_NAME +'` ('
+                +"`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
+                +"`authGoogleUserId` STRING UNIQUE,"
+                +"`authFacebookUserId` STRING UNIQUE,"
+                +"`authSlackUserEmailAndTeam` STRING UNIQUE,"
+                +"`certificates` STRING,"
+                +"`cguReadAndAccepted` BOOLEAN NOT NULL DEFAULT FALSE,"
+                +"`services` STRING NOT NULL"
+                +')', (err) => {
+                    if (err)
+                        reject(err);
+                    else
+                        success();
+                });
+            //TODO permanent login token array
+        } else {
+            success();
+        }
+    });
 };