Migrate to sequelize v5
diff --git a/.travis.yml b/.travis.yml
index 2fcb0df..da14dc2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,7 +5,6 @@
 node_js:
   - 'stable'
   - '8'
-  - '6'
 
 install: yarn install
 cache:
@@ -17,7 +16,10 @@
   include:
   - stage: Produce Coverage
     node_js: node
-    script: jest --coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage
+    script: jest --coverage --forceExit && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage
+
+before_install:
+  - mysql -e 'CREATE DATABASE casbin;'
 
 services:
   - mysql
diff --git a/README.md b/README.md
index 862e921..b7ccd5a 100644
--- a/README.md
+++ b/README.md
@@ -35,20 +35,18 @@
 
 async function myFunction() {
     // Initialize a Sequelize adapter and use it in a Node-Casbin enforcer:
-    // The adapter will use the MySQL database named "casbin".
-    // If it doesn't exist, the adapter will create it automatically.
-    const a = await SequelizeAdapter.newAdapter('mysql://root:123@localhost:3306/'); // Your connection string. 
-
-    // Or you can use an existing DB "abc" like this:
-    // The adapter will use the table named "casbin_rule".
-    // If it doesn't exist, the adapter will create it automatically.
-    // const a = await SequelizeAdapter.newAdapter('mysql://root:123@localhost:3306/abc', true);
+    // The adapter can not automatically create database.
+    // But the adapter will automatically and use the table named "casbin_rule".    
+    // ORM should not create databases automatically.  
+    const a = await SequelizeAdapter.newAdapter({
+        username: 'root',
+        password: '',
+        database: 'casbin',
+        dialect: 'mysql'
+    });
 
     const e = await casbin.newEnforcer('examples/rbac_model.conf', a);
 
-    // Load the policy from DB.
-    await e.loadPolicy();
-
     // Check the permission.
     e.enforce('alice', 'data1', 'read');
 
diff --git a/package.json b/package.json
index caa6891..6ade9f3 100644
--- a/package.json
+++ b/package.json
@@ -10,29 +10,27 @@
     "build": "rimraf lib && tsc",
     "lint": "tslint \"src/**/*.ts\"",
     "fix": "tslint \"src/**/*.ts\" --fix",
-    "test": "jest"
+    "test": "jest --forceExit"
   },
   "devDependencies": {
-    "@types/jest": "^23.3.1",
-    "@types/lodash": "^4.14.113",
+    "@types/jest": "^24.0.15",
     "@types/node": "^10.5.3",
-    "@types/sequelize": "^4.27.24",
+    "@types/sequelize": "^4.28.3",
     "coveralls": "^3.0.2",
     "husky": "^0.14.3",
-    "jest": "^24.1.0",
+    "jest": "^24.8.0",
     "lint-staged": "^7.2.0",
     "mysql2": "^1.6.1",
     "rimraf": "^2.6.2",
-    "ts-jest": "22.4.6",
+    "ts-jest": "^24.0.2",
     "tslint": "^5.11.0",
     "typescript": "^3.3.3"
   },
   "dependencies": {
-    "casbin": "^2.0.0",
-    "lodash": "^4.17.10",
+    "casbin": "^3.0.1",
     "reflect-metadata": "^0.1.12",
-    "sequelize": "^4.42.0",
-    "sequelize-typescript": "^0.6.7"
+    "sequelize": "^5.8.10",
+    "sequelize-typescript": "^1.0.0-beta.3"
   },
   "files": [
     "lib",
diff --git a/src/adapter.ts b/src/adapter.ts
index 1063c64..a86f110 100644
--- a/src/adapter.ts
+++ b/src/adapter.ts
@@ -13,77 +13,35 @@
 // limitations under the License.
 
 import {Adapter, Helper, Model} from 'casbin';
-import {Sequelize, ISequelizeUriConfig} from 'sequelize-typescript';
+import {Sequelize, SequelizeOptions} from 'sequelize-typescript';
 import {CasbinRule} from './casbinRule';
 
-function ModelFactory(model: typeof CasbinRule) {
-    return class extends model {
-    };
-}
-
 /**
  * SequelizeAdapter represents the Sequelize adapter for policy storage.
  */
 export class SequelizeAdapter implements Adapter {
-    private connStr: string;
-    private dbSpecified: boolean;
-
+    private option: SequelizeOptions;
     private sequelize: Sequelize;
-    private static modelMap: Map<Sequelize, typeof CasbinRule> = new Map();
 
-    constructor(connStr: string, dbSpecified: boolean) {
-        this.connStr = connStr;
-        this.dbSpecified = dbSpecified;
+    constructor(option: SequelizeOptions) {
+        this.option = option;
     }
 
     /**
      * newAdapter is the constructor.
-     * dbSpecified is an optional boolean parameter. The default value is false.
-     * It's up to whether you have specified an existing DB in connStr.
-     * If dbSpecified == true, you need to make sure the DB in connStr exists.
-     * If dbSpecified == false, the adapter will automatically create a DB named 'casbin'.
+     * @param option sequelize connection option
      */
-    public static async newAdapter(connStr: string, dbSpecified: boolean = false) {
-        const a = new SequelizeAdapter(connStr, dbSpecified);
+    public static async newAdapter(option: SequelizeOptions) {
+        const a = new SequelizeAdapter(option);
         await a.open();
 
         return a;
     }
 
-    private async createDatabase() {
-        const uriConfig: ISequelizeUriConfig = {
-            url: this.connStr,
-            logging: false,
-            pool: {max: 5, min: 0, idle: 10000}
-        };
-        const sequelize = new Sequelize(uriConfig);
-        await sequelize.authenticate();
-
-        await sequelize.query('CREATE DATABASE IF NOT EXISTS casbin');
-
-        await sequelize.close();
-    }
-
     private async open() {
-        let url = this.connStr;
-        if (!this.dbSpecified) {
-            url = this.connStr + 'casbin';
-            await this.createDatabase();
-        }
-
-        const uriConfig: ISequelizeUriConfig = {
-            url,
-            logging: false,
-            pool: {max: 5, min: 0, idle: 10000}
-        };
-
-        this.sequelize = new Sequelize(uriConfig);
+        this.sequelize = new Sequelize(this.option);
         await this.sequelize.authenticate();
-
-        const Rule = ModelFactory(CasbinRule);
-        SequelizeAdapter.modelMap.set(this.sequelize, Rule);
-        this.sequelize.addModels([Rule]);
-
+        this.sequelize.addModels([CasbinRule]);
         await this.createTable();
     }
 
@@ -91,17 +49,12 @@
         await this.sequelize.close();
     }
 
-    private getCasbinRuleModel(): typeof CasbinRule {
-        const model = SequelizeAdapter.modelMap.get(this.sequelize);
-        return !model ? CasbinRule : model;
-    }
-
     private async createTable() {
-        await this.getCasbinRuleModel().sync();
+        await this.sequelize.sync();
     }
 
     private async dropTable() {
-        await this.getCasbinRuleModel().destroy({where: {}, truncate: true});
+        await this.sequelize.getRepository(CasbinRule).destroy({where: {}, truncate: true});
     }
 
     private loadPolicyLine(line: CasbinRule, model: Model) {
@@ -113,7 +66,7 @@
      * loadPolicy loads all policy rules from the storage.
      */
     public async loadPolicy(model: Model) {
-        const lines = await this.getCasbinRuleModel().findAll();
+        const lines = await this.sequelize.getRepository(CasbinRule).findAll();
 
         for (const line of lines) {
             this.loadPolicyLine(line, model);
@@ -121,8 +74,7 @@
     }
 
     private savePolicyLine(ptype: string, rule: string[]): CasbinRule {
-        const Rule = this.getCasbinRuleModel();
-        const line = new Rule();
+        const line = new CasbinRule();
 
         line.ptype = ptype;
         if (rule.length > 0) {
@@ -154,8 +106,7 @@
         await this.dropTable();
         await this.createTable();
 
-        let astMap = model.model.get('p');
-        // @ts-ignore
+        let astMap = model.model.get('p')!;
         for (const [ptype, ast] of astMap) {
             for (const rule of ast.policy) {
                 const line = this.savePolicyLine(ptype, rule);
@@ -163,8 +114,7 @@
             }
         }
 
-        astMap = model.model.get('g');
-        // @ts-ignore
+        astMap = model.model.get('g')!;
         for (const [ptype, ast] of astMap) {
             for (const rule of ast.policy) {
                 const line = this.savePolicyLine(ptype, rule);
@@ -189,15 +139,15 @@
     public async removePolicy(sec: string, ptype: string, rule: string[]) {
         const line = this.savePolicyLine(ptype, rule);
         const where = {};
-        Object.keys(line.dataValues)
+
+        Object.keys(line.get({plain: true}))
             .filter(key => key !== 'id')
             .forEach(key => {
                 // @ts-ignore
                 where[key] = line[key];
             });
 
-        // @ts-ignore
-        await this.getCasbinRuleModel().destroy({where});
+        await this.sequelize.getRepository(CasbinRule).destroy({where});
     }
 
     /**
diff --git a/src/casbinRule.ts b/src/casbinRule.ts
index c516cf6..3b76d8c 100644
--- a/src/casbinRule.ts
+++ b/src/casbinRule.ts
@@ -14,7 +14,7 @@
 
 import {Table, Column, Model} from 'sequelize-typescript';
 
-@Table({tableName: 'casbin_rule'})
+@Table({tableName: 'casbin_rule', timestamps: false})
 export class CasbinRule extends Model<CasbinRule> {
     @Column
     public ptype: string;
diff --git a/test/adapter.test.ts b/test/adapter.test.ts
index ed15fc6..e6c847d 100644
--- a/test/adapter.test.ts
+++ b/test/adapter.test.ts
@@ -23,7 +23,13 @@
 }
 
 test('TestAdapter', async () => {
-    const a = await SequelizeAdapter.newAdapter('mysql://root:@localhost:3306/');
+    const a = await SequelizeAdapter.newAdapter({
+        username: 'root',
+        password: '',
+        database: 'casbin',
+        dialect: 'mysql'
+    });
+
     try {
         // Because the DB is empty at first,
         // so we need to load the policy from the file adapter (.CSV) first.