Skip to content

Commit 0124ac9

Browse files
author
lichengyin
committed
support auto update
1 parent a3879e0 commit 0124ac9

File tree

4 files changed

+82
-100
lines changed

4 files changed

+82
-100
lines changed

.eslintrc

+1-31
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,3 @@
11
{
2-
"parser": "babel-eslint",
3-
"env": {
4-
"node": true,
5-
"mocha": true,
6-
"es6": true // es6 envoriment
7-
},
8-
"rules": {
9-
"strict": [0],
10-
"eqeqeq": 2,
11-
"quotes": [2, "single", {"allowTemplateLiterals": true}],
12-
"no-underscore-dangle": 0,
13-
"eol-last": 0,
14-
"camelcase": 0,
15-
"no-loop-func": 0,
16-
"no-trailing-spaces": 0,
17-
"consistent-return": 0,
18-
"new-cap": 0,
19-
"no-shadow": 0,
20-
"semi": 0,
21-
"no-process-exit": 0,
22-
"no-empty": 0,
23-
"yoda": 0,
24-
"no-const-assign": "warn", // more rule
25-
"no-new-func": 0,
26-
"no-labels": 0,
27-
"no-this-before-super": "warn", // more rule
28-
"no-undef": "warn", // more rule
29-
"no-unreachable": "warn", // more rule
30-
"no-unused-vars": "warn", // more rule
31-
"valid-typeof": "warn" // more rule
32-
}
2+
"extends": "eslint-config-think"
333
}

index.js

+55-48
Original file line numberDiff line numberDiff line change
@@ -5,75 +5,82 @@ const gc = require('think-gc');
55
const initSessionData = Symbol('think-session-mysql-init');
66

77
/*
8-
DROP TABLE IF EXISTS `think_session`;
9-
CREATE TABLE `think_session` (
10-
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
11-
`cookie` varchar(255) NOT NULL DEFAULT '',
12-
`data` text,
13-
`expire` bigint(11) NOT NULL,
14-
PRIMARY KEY (`id`),
15-
UNIQUE KEY `cookie` (`cookie`),
16-
KEY `expire` (`expire`)
17-
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
8+
CREATE TABLE `think_session` (
9+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
10+
`cookie` varchar(255) NOT NULL DEFAULT '',
11+
`data` text,
12+
`expire` bigint(11) NOT NULL DEFAULT '0',
13+
`maxage` int(11) NOT NULL DEFAULT '0',
14+
PRIMARY KEY (`id`),
15+
UNIQUE KEY `cookie` (`cookie`),
16+
KEY `expire` (`expire`)
17+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1818
*/
1919

2020
/**
2121
* use mysql to store session
2222
*
2323
*/
2424
class MysqlSession {
25-
constructor(options = {}, ctx) {
25+
constructor(options = {}, ctx, cookieOptions) {
2626
assert(options.cookie, '.cookie required');
27-
const modelConfig = think.config('model');
28-
const useModel = modelConfig[modelConfig.type];
29-
if (useModel.handle.name.toLowerCase().indexOf('mysql') > -1) {
30-
this.options = Object.assign({}, useModel, options);
31-
}else{
32-
this.options = options;
33-
}
34-
this.mysql = mysql.getInstance(this.options);
27+
this.options = options;
28+
this.cookieOptions = cookieOptions;
29+
this.mysql = mysql.getInstance(helper.omit(options, 'cookie'));
3530
this.ctx = ctx;
3631
this.data = {};
3732
this.tableName = (this.options.prefix || '') + 'session';
33+
this.status = 0;
34+
this.maxAge = this.options.maxAge || 0;
35+
this.expire = 0;
3836
this.gcType = `session_mysql`;
3937
gc(this, this.options.gcInterval);
4038
}
4139

42-
4340
[initSessionData]() {
4441
if (this.initPromise) {
4542
return this.initPromise;
4643
}
4744
if (this.options.fresh || this.status === -1) {
48-
return this.initPromise = Promise.resolve();
45+
this.initPromise = Promise.resolve();
46+
return this.initPromise;
4947
}
5048

5149
// flush session when request finish
5250
this.ctx.res.once('finish', () => {
5351
this.flush();
5452
});
55-
53+
5654
this.initPromise = this.mysql.query({
5755
sql: `SELECT * FROM ${this.tableName} WHERE cookie = ? `,
5856
values: [this.options.cookie]
5957
}).then(row => {
60-
if(row.length === 0) return;
61-
//session data is expired
62-
if(row[0].expire < Date.now()){
58+
if (row.length === 0) return;
59+
// session data is expired
60+
if (row[0].expire < Date.now()) {
6361
return this.delete();
6462
}
65-
let content = row[0].data;
66-
content = JSON.parse(content);
67-
if (helper.isEmpty(content)) return;
68-
this.data = content;
69-
}).catch(
70-
err => console.log(err)
71-
);
72-
73-
63+
const content = row[0].data;
64+
this.data = JSON.parse(content) || {};
65+
if (row[0].maxAge) {
66+
this.maxAge = row[0].maxAge;
67+
}
68+
this.expire = row[0].expire;
69+
this.autoUpdate();
70+
});
7471
return this.initPromise;
7572
}
76-
73+
autoUpdate() {
74+
if (this.maxAge && this.expire) {
75+
const rate = (this.expire - Date.now()) / this.maxAge;
76+
if (rate < this.cookieOptions.autoUpdateRate) {
77+
this.status = 1;
78+
this.cookieOptions.maxAge = this.maxAge;
79+
// update cookie maxAge
80+
this.ctx.cookie(this.cookieOptions.name, this.options.cookie, this.cookieOptions);
81+
}
82+
}
83+
}
7784
get(name) {
7885
return this[initSessionData]().then(() => {
7986
if (this.options.autoUpdate) {
@@ -86,9 +93,9 @@ class MysqlSession {
8693
set(name, value) {
8794
return this[initSessionData]().then(() => {
8895
this.status = 1;
89-
if(value === null){
96+
if (value === null) {
9097
delete this.data[name];
91-
}else{
98+
} else {
9299
this.data[name] = value;
93100
}
94101
});
@@ -107,25 +114,25 @@ class MysqlSession {
107114
this.mysql.execute({
108115
sql: `DELETE FROM ${this.tableName} WHERE cookie=?`,
109116
values: [this.options.cookie]
110-
})
117+
});
111118
} else if (this.status === 1) {
112119
this.status = 0;
113120
// insert or update data
114-
const maxAge = Date.now() + helper.ms(this.options.maxAge || 0);
115-
let fields = [this.options.cookie, JSON.stringify(this.data), maxAge];
121+
const expire = Date.now() + this.maxAge;
122+
const fields = [this.options.cookie, JSON.stringify(this.data), expire, this.maxAge];
116123
this.mysql.execute({
117-
sql: `INSERT INTO ${this.tableName} (cookie, data, expire) VALUES(?, ?, ?)
118-
ON DUPLICATE KEY UPDATE data=?, expire=?`,
119-
values: [...fields, fields[1], fields[2]]
120-
})
124+
sql: `INSERT INTO ${this.tableName} (cookie, data, expire, maxage) VALUES(?, ?, ?, ?)
125+
ON DUPLICATE KEY UPDATE data=?, expire=?, maxage=?`,
126+
values: [...fields, fields[1], fields[2], fields[3]]
127+
});
121128
}
122129
return Promise.resolve();
123130
}
124131

125-
gc(){
126-
this.mysql.execute({
127-
sql: `DELETE FROM ${this.tableName} WHERE expire < ROUND(UNIX_TIMESTAMP(CURTIME(4)) * 1000)`,
128-
})
132+
gc() {
133+
return this.mysql.execute({
134+
sql: `DELETE FROM ${this.tableName} WHERE expire < ${Date.now()}`
135+
});
129136
}
130137
}
131138
module.exports = MysqlSession;

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"email": "[email protected]"
88
},
99
"scripts": {
10+
"lint": "eslint --fix index.js",
1011
"test": "eslint index.js && nyc ava test/index.js ",
1112
"coverage": "nyc report --reporter=html"
1213
},
@@ -30,9 +31,9 @@
3031
"devDependencies": {
3132
"ava": "^0.18.2",
3233
"babel-core": "^6.22.1",
33-
"babel-eslint": "^7.1.1",
3434
"coveralls": "^2.12.0",
35-
"eslint": "2.8.0",
35+
"eslint": "^5.5.0",
36+
"eslint-config-think": "^1.0.2",
3637
"mkdirp": "^0.5.1",
3738
"mock-require": "^2.0.1",
3839
"nyc": "^7.0.0",

test/index.js

+23-19
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
const sessionMysql = require('../index');
2+
import test from "ava";
23

4+
test('init', t => {
5+
t.is(1, 1)
6+
})
37

4-
try {
5-
const options = {
6-
host: '127.0.0.1',
7-
user: 'root',
8-
password: 'Hello@123',
9-
maxAge: 10000,
10-
database:'think_test',
11-
tableName: 'think_session',
12-
cookie: '34588519-1a3b-4ecc-9dec-9932810c1bb9',
13-
fresh: false,
14-
prefix:'think'
15-
};
16-
let instance = new sessionMysql(options,{})
17-
instance.get('userId').then((res) => {
18-
console.log(res)
19-
})
20-
} catch (e) {
21-
console.log(e);
22-
}
8+
// try {
9+
// const options = {
10+
// host: '127.0.0.1',
11+
// user: 'root',
12+
// password: 'Hello@123',
13+
// maxAge: 10000,
14+
// database:'think_test',
15+
// tableName: 'think_session',
16+
// cookie: '34588519-1a3b-4ecc-9dec-9932810c1bb9',
17+
// fresh: false,
18+
// prefix:'think'
19+
// };
20+
// let instance = new sessionMysql(options,{})
21+
// instance.get('userId').then((res) => {
22+
// console.log(res)
23+
// })
24+
// } catch (e) {
25+
// console.log(e);
26+
// }

0 commit comments

Comments
 (0)