forked from calzoneman/sync
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupdate.js
180 lines (159 loc) · 5.79 KB
/
update.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
var Config = require("./lib/config.js");
var Database = require("./lib/database.js");
var updates = {
"2013-08-20-utf8fix": fixDBUnicode,
"2013-08-21-banfix": fixChannelBanKey
};
var x = {};
Config.load(x, "cfg.json", function () {
var db = new Database(x.cfg);
var u = process.argv[2];
if(!(u in updates)) {
console.log("Usage: node update.js <update>");
console.log("Available updates: ");
for(var k in updates) {
console.log(" " + k);
}
process.exit(0);
}
var fn = updates[u];
fn(db);
});
/*
2013-08-20
This function iterates over tables in the database and converts the
encoding on each to UTF-8.
Furthermore, it does the following to convert channel libraries in
a way such that UTF-8 titles stored in other encodings (e.g. latin1)
are preserved as UTF-8:
1. Change the `title` column to BLOB (unencoded)
2. Change the table character set to utf8
3. Change the `title` column to VARCHAR(255) CHARACTER SET utf8
This corrects an encoding issue that was exposed when switching to
node-mysql. mysql-libmysqlclient ignored database encoding and assumed
the data was UTF-8.
*/
function fixDBUnicode(db) {
db.query("SHOW TABLES", function (err, res) {
if(err) {
console.log(err);
return;
}
var libs = [];
var waiting = res.length;
res.forEach(function (r) {
var k = Object.keys(r)[0];
if(r[k].match(/^chan_[\w-_]{1,30}_library$/)) {
libs.push(r[k]);
waiting--;
return;
} else if(r[k] == "user_playlists") {
waiting--;
return;
}
db.query("ALTER TABLE `" + r[k] + "` CONVERT TO CHARACTER SET utf8", function (err, _) {
waiting--;
if(err)
console.log("FAIL: " + r[k]);
else
console.log("Fixed " + r[k]);
});
});
var s1int = setInterval(function () {
if(waiting == 0) {
clearInterval(s1int);
waiting = libs.length + 1;
libs.forEach(function (lib) {
db.query("ALTER TABLE `"+lib+"` MODIFY title BLOB", function (err, _) {
if(err) {
console.log(err);
waiting--;
return;
}
db.query("ALTER TABLE `"+lib+"` CHARACTER SET utf8", function (err, _) {
if(err) {
console.log(err);
waiting--;
return;
}
db.query("ALTER TABLE `"+lib+"` MODIFY title VARCHAR(255) CHARACTER SET utf8", function (err, _) {
waiting--;
if(err) {
console.log(err);
return;
}
console.log("Fixed " + lib);
});
});
});
});
db.query("ALTER TABLE user_playlists MODIFY contents MEDIUMBLOB", function (err, _) {
if(err) {
console.log(err);
waiting--;
return;
}
db.query("ALTER TABLE user_playlists CHARACTER SET utf8", function (err, _) {
if(err) {
console.log(err);
waiting--;
return;
}
db.query("ALTER TABLE user_playlists MODIFY contents MEDIUMTEXT CHARACTER SET utf8", function (err, _) {
waiting--;
if(err) {
console.log(err);
return;
}
console.log("Fixed user_playlists");
});
});
});
setInterval(function () {
if(waiting == 0) {
console.log("Done");
process.exit(0);
}
}, 1000);
}
}, 1000);
});
}
/*
2013-08-21
This function iterates over channel ban tables and corrects the
PRIMARY KEY. Previously, the table was defined with PRIMARY KEY (ip),
but in reality, (ip, name) should be pairwise unique.
This corrects the issue where only one name ban can exist in the table
because of the `ip` field "*" being unique.
*/
function fixChannelBanKey(db) {
db.query("SHOW TABLES", function (err, res) {
if(err) {
console.log("SEVERE: SHOW TABLES failed");
return;
}
var count = res.length;
res.forEach(function (r) {
var k = Object.keys(r)[0];
if(!r[k].match(/^chan_[\w-_]{1,30}_bans$/)) {
count--;
return;
}
db.query("ALTER TABLE `" + r[k] + "` DROP PRIMARY KEY, ADD PRIMARY KEY (ip, name)", function (err, res) {
count--;
if(err) {
console.log("FAILED: " + r[k]);
return;
}
console.log("Fixed " + r[k]);
});
});
setInterval(function () {
if(count == 0) {
console.log("Done");
process.exit(0);
}
}, 1000);
});
}