File lib/sqlDAO.js added (mode: 100644) (index 0000000..ad211b8) |
|
1 |
|
const sq3 = require("sqlite3"); |
|
2 |
|
|
|
3 |
|
let DAO = class { |
|
4 |
|
|
|
5 |
|
constructor() { |
|
6 |
|
this.stmts = {}; |
|
7 |
|
}; |
|
8 |
|
|
|
9 |
|
reportErr(e) { |
|
10 |
|
console.error(typeof this.dao, e); |
|
11 |
|
}; |
|
12 |
|
|
|
13 |
|
prepare(database, sql) { |
|
14 |
|
let stmt = database.prepare(sql); |
|
15 |
|
stmt.dao = this; |
|
16 |
|
return stmt; |
|
17 |
|
}; |
|
18 |
|
|
|
19 |
|
insert(dObj) { |
|
20 |
|
this.dataObj = dObj; |
|
21 |
|
if (this.stmts.insert) { |
|
22 |
|
this.stmts.insert.run(dObj, this.errInsert); |
|
23 |
|
} else { |
|
24 |
|
this.reportErr({ error: "No INSERT statement?" }); |
|
25 |
|
} |
|
26 |
|
}; |
|
27 |
|
errInsert(e) { |
|
28 |
|
if (e) { |
|
29 |
|
switch (e.errno) { |
|
30 |
|
case 19: |
|
31 |
|
if (this.dao.stmts.update) { |
|
32 |
|
console.error("I would do an update here: ", this.dao.dataObj); |
|
33 |
|
} else { |
|
34 |
|
// In general, ignore the conflict: |
|
35 |
|
} |
|
36 |
|
break; |
|
37 |
|
default: |
|
38 |
|
this.dao.reportErr(e); |
|
39 |
|
break; |
|
40 |
|
} |
|
41 |
|
} |
|
42 |
|
}; |
|
43 |
|
|
|
44 |
|
update(dObj) { |
|
45 |
|
this.dataObj = dObj; |
|
46 |
|
if (this.stmts.update) { |
|
47 |
|
this.stmts.update.run(dObj, this.errUpdate); |
|
48 |
|
} else { |
|
49 |
|
this.reportErr({ error: "No UPDATE statement?" }); |
|
50 |
|
} |
|
51 |
|
}; |
|
52 |
|
errUpdate(e) { |
|
53 |
|
if (e) { |
|
54 |
|
switch (e.errno) { |
|
55 |
|
default: |
|
56 |
|
this.dao.reportErr(e); |
|
57 |
|
break; |
|
58 |
|
} |
|
59 |
|
} |
|
60 |
|
}; |
|
61 |
|
}; |
|
62 |
|
|
|
63 |
|
module.exports = { |
|
64 |
|
DAO: DAO, |
|
65 |
|
|
|
66 |
|
connect(opts) { |
|
67 |
|
sq3.verbose(); |
|
68 |
|
let database = new sq3.Database("eviction-data.sq3", (err) => { |
|
69 |
|
if (err) { |
|
70 |
|
throw err; |
|
71 |
|
} |
|
72 |
|
}); |
|
73 |
|
opts && "function" === typeof opts.connectCallback && opts.connectCallback(database); |
|
74 |
|
}, |
|
75 |
|
|
|
76 |
|
disconnect(db) { |
|
77 |
|
db.close(); |
|
78 |
|
}, |
|
79 |
|
|
|
80 |
|
DocketCtlr: class extends DAO { |
|
81 |
|
constructor (database) { |
|
82 |
|
super(); |
|
83 |
|
this.stmts.insert = this.prepare( |
|
84 |
|
database, |
|
85 |
|
"INSERT INTO docket (precinct, place, dateTime, URL) \ |
|
86 |
|
VALUES ($pct, $plc, $dt, $url)" |
|
87 |
|
); |
|
88 |
|
}; |
|
89 |
|
|
|
90 |
|
}, |
|
91 |
|
DocketCaseCtlr: class extends DAO { |
|
92 |
|
constructor(database) { |
|
93 |
|
super(); |
|
94 |
|
this.stmts.insert = this.prepare( |
|
95 |
|
database, |
|
96 |
|
"INSERT INTO docketedCases (precinct, place, dateTIme, casenumber, claim) VALUES ($pct, $plc, $dt, $cnum, $claim)" |
|
97 |
|
); |
|
98 |
|
}; |
|
99 |
|
}, |
|
100 |
|
CaseCtlr: class extends DAO { |
|
101 |
|
constructor(database) { |
|
102 |
|
super(); |
|
103 |
|
this.stmts.insert = this.prepare( |
|
104 |
|
database, |
|
105 |
|
"INSERT INTO cases (casenumber, caseURL) VALUES ($cnum, $curl)" |
|
106 |
|
); |
|
107 |
|
}; |
|
108 |
|
}, |
|
109 |
|
PartyCtlr: class extends DAO { |
|
110 |
|
constructor(database) { |
|
111 |
|
super(); |
|
112 |
|
this.stmts.insert = this.prepare( |
|
113 |
|
database, |
|
114 |
|
"INSERT INTO party (casenumber, role, name) VALUES ($cnum, $role, $name)" |
|
115 |
|
); |
|
116 |
|
}; |
|
117 |
|
}, |
|
118 |
|
EventCtlr: class extends DAO { |
|
119 |
|
constructor(database) { |
|
120 |
|
super(); |
|
121 |
|
this.stmts.insert = this.prepare( |
|
122 |
|
database, |
|
123 |
|
"INSERT INTO events (casenumber, description, dateAdded) VALUES ($cnum, $desc, $date)" |
|
124 |
|
); |
|
125 |
|
}; |
|
126 |
|
} |
|
127 |
|
}; |
|
128 |
|
|
File xferData.js added (mode: 100644) (index 0000000..27eddf8) |
|
1 |
|
const sqDAO = require("./lib/sqlDAO"); |
|
2 |
|
const msDAO = require("./lib/msDAO"); |
|
3 |
|
|
|
4 |
|
class xferCtlr { |
|
5 |
|
constructor(props) { |
|
6 |
|
Object.assign(this, props); |
|
7 |
|
}; |
|
8 |
|
|
|
9 |
|
xferPromise(sqD, msD) { |
|
10 |
|
return new Promise(async (resFN, rejFN) => { |
|
11 |
|
sqD.each( |
|
12 |
|
"SELECT COUNT(*) num FROM "+this.tableName, |
|
13 |
|
(err, row) => { |
|
14 |
|
if (err) { |
|
15 |
|
rejFN(err); |
|
16 |
|
} else { |
|
17 |
|
console.log(this.tableName, "SOURCE rows: ", row); |
|
18 |
|
} |
|
19 |
|
} |
|
20 |
|
); |
|
21 |
|
|
|
22 |
|
msD.batch("DELETE FROM "+this.tableName) |
|
23 |
|
.then(result => { |
|
24 |
|
let oneRow = (sel, ins, num) => { |
|
25 |
|
sel.get((err, row) => { |
|
26 |
|
if (err) { |
|
27 |
|
rejFN(err); |
|
28 |
|
} else { |
|
29 |
|
if (row) { |
|
30 |
|
ins.execute(row) |
|
31 |
|
.then(() => { |
|
32 |
|
oneRow(sel, ins, num+1); |
|
33 |
|
}) |
|
34 |
|
.catch(e => { |
|
35 |
|
sel.finalize(); |
|
36 |
|
ins.unprepare() |
|
37 |
|
.finally(() => { rejFN(e); }) |
|
38 |
|
; |
|
39 |
|
}) |
|
40 |
|
; |
|
41 |
|
} else { |
|
42 |
|
sel.finalize(); |
|
43 |
|
ins.unprepare() |
|
44 |
|
.catch(e => { rejFN(e); }); |
|
45 |
|
resFN({ tbl: this.tableName, msg: "Finished.", num: num }); |
|
46 |
|
} |
|
47 |
|
} |
|
48 |
|
}); |
|
49 |
|
}; |
|
50 |
|
|
|
51 |
|
let selStmt = sqD.prepare(this.sqlRowSEL); |
|
52 |
|
let insStmt = new msD.PreparedStatement(); |
|
53 |
|
this.insBind(msD, insStmt); |
|
54 |
|
insStmt.prepare(this.sqlRowINS) |
|
55 |
|
.then(() => { |
|
56 |
|
oneRow(selStmt, insStmt, 0); |
|
57 |
|
}) |
|
58 |
|
.catch(err => { selStmt.finalize(); rejFN(err); }) |
|
59 |
|
; |
|
60 |
|
}) |
|
61 |
|
.catch(e => { |
|
62 |
|
rejFN(e); |
|
63 |
|
}) |
|
64 |
|
; |
|
65 |
|
}); |
|
66 |
|
}; |
|
67 |
|
}; |
|
68 |
|
|
|
69 |
|
|
|
70 |
|
opts.connectCallback = (sqDB) => { |
|
71 |
|
// Now get the msSQL connection: |
|
72 |
|
let opts = require("./creds")["MS"]; |
|
73 |
|
opts.connectCallback = (msDB) => { |
|
74 |
|
let casesCtlr = new xferCtlr({ |
|
75 |
|
tableName: "CASES", |
|
76 |
|
sqlRowSEL: "SELECT casenumber cnum, case_URL curl, filed_date fdt, case_status cstat FROM CASES", |
|
77 |
|
sqlRowINS: "INSERT INTO CASES (casenumber, case_URL, filed_date, case_status) VALUES (@cnum, @curl, @fdt, @cstat)", |
|
78 |
|
insBind: (db, stmt) => { |
|
79 |
|
stmt.input("cnum", db.NVarChar); |
|
80 |
|
stmt.input("curl", db.NVarChar); |
|
81 |
|
stmt.input("fdt", db.NVarChar); |
|
82 |
|
stmt.input("cstat", db.NVarChar); |
|
83 |
|
} |
|
84 |
|
}); |
|
85 |
|
let docketsCtlr = new xferCtlr({ |
|
86 |
|
tableName: "DOCKET", |
|
87 |
|
sqlRowSEL: "SELECT precinct pct, place plc, docket_dateTime ddt, URL url FROM DOCKET", |
|
88 |
|
sqlRowINS: "INSERT INTO DOCKET (precinct, place, docket_dateTime, URL) VALUES (@pct, @plc, @ddt, @url)", |
|
89 |
|
insBind: (db, stmt) => { |
|
90 |
|
stmt.input("pct", db.Int); |
|
91 |
|
stmt.input("plc", db.Int); |
|
92 |
|
stmt.input("ddt", db.NVarChar); |
|
93 |
|
stmt.input("url", db.NVarChar); |
|
94 |
|
} |
|
95 |
|
}); |
|
96 |
|
let dcCtlr = new xferCtlr({ |
|
97 |
|
tableName: "DOCKETEDCASES", |
|
98 |
|
sqlRowSEL: "SELECT precinct pct, place plc, docket_dateTime ddt, casenumber cnum, claim clm FROM DOCKETEDCASES", |
|
99 |
|
sqlRowINS: "INSERT INTO DOCKETEDCASES (precinct, place, docket_dateTime, casenumber, claim) VALUES (@pct, @plc, @ddt, @cnum, @clm)", |
|
100 |
|
insBind: (db, stmt) => { |
|
101 |
|
stmt.input("pct", db.Int); |
|
102 |
|
stmt.input("plc", db.Int); |
|
103 |
|
stmt.input("ddt", db.NVarChar); |
|
104 |
|
stmt.input("cnum", db.NVarChar); |
|
105 |
|
stmt.input("clm", db.NVarChar); |
|
106 |
|
} |
|
107 |
|
}); |
|
108 |
|
let partyCtlr = new xferCtlr({ |
|
109 |
|
tableName: "PARTY", |
|
110 |
|
sqlRowSEL: "SELECT casenumber cnum, party_role pr, party_name pn, party_address pa FROM PARTY", |
|
111 |
|
sqlRowINS: "INSERT INTO PARTY (casenumber, party_role, party_name, party_address) VALUES (@cnum, @pr, @pn, @pa)", |
|
112 |
|
insBind: (db, stmt) => { |
|
113 |
|
stmt.input("pr", db.NVarChar); |
|
114 |
|
stmt.input("pn", db.NVarChar); |
|
115 |
|
stmt.input("pa", db.NVarChar); |
|
116 |
|
stmt.input("cnum", db.NVarChar); |
|
117 |
|
} |
|
118 |
|
}); |
|
119 |
|
let eventsCtlr = new xferCtlr({ |
|
120 |
|
tableName: "EVENTS", |
|
121 |
|
sqlRowSEL: "SELECT casenumber cnum, eventDescription ed, dateAdded da FROM EVENTS", |
|
122 |
|
sqlRowINS: "INSERT INTO EVENTS (casenumber, eventDescription, dateAdded) VALUES (@cnum, @ed, @da)", |
|
123 |
|
insBind: (db, stmt) => { |
|
124 |
|
stmt.input("cnum", db.NVarChar); |
|
125 |
|
stmt.input("ed", db.NVarChar); |
|
126 |
|
stmt.input("da", db.NVarChar); |
|
127 |
|
} |
|
128 |
|
}); |
|
129 |
|
|
|
130 |
|
Promise.all([ |
|
131 |
|
casesCtlr.xferPromise(sqDB, msDB).catch(e => { console.log("CTLR CALLBACK: ", e); }), |
|
132 |
|
docketsCtlr.xferPromise(sqDB, msDB).catch(e => { console.log("CTLR CALLBACK: ", e); }), |
|
133 |
|
dcCtlr.xferPromise(sqDB, msDB).catch(e => { console.log("CTLR CALLBACK: ", e); }), |
|
134 |
|
partyCtlr.xferPromise(sqDB, msDB).catch(e => { console.log("CTLR CALLBACK: ", e); }), |
|
135 |
|
eventsCtlr.xferPromise(sqDB, msDB).catch(e => { console.log("CTLR CALLBACK: ", e); }), |
|
136 |
|
]) |
|
137 |
|
.then(resArr => { resArr.forEach(val => { val && console.log(val); }); }) |
|
138 |
|
.catch(e => { console.log("ALL CALLBACK: ", e); }) |
|
139 |
|
.finally(() => { |
|
140 |
|
msDAO.disconnect(msDB); |
|
141 |
|
sqDAO.disconnect(sqDB); |
|
142 |
|
}) |
|
143 |
|
; |
|
144 |
|
}; |
|
145 |
|
|
|
146 |
|
msDAO.connect(opts); |
|
147 |
|
}; |
|
148 |
|
|
|
149 |
|
let opts = require("./creds")["SQLITE3"]; |
|
150 |
|
sqDAO.connect(opts); |