-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathenciv-info.js
196 lines (174 loc) · 6.32 KB
/
enciv-info.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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
"use strict";
const Iota=require('iota')();
const cloneDeep = require('lodash/cloneDeep');
const MongoModels=require('mongo-models');
const showShallowDiff = require('./showShallowDiff');
// Iota uses logger
const log4js=require('log4js');
if(!global.logger) {
global.logger=log4js.getLogger("node");
log4js.configure({
appenders: { err: { type: 'stderr' } },
categories: { default: { appenders: ['err'], level: 'DEBUG' } }
});
}
var encivInfo={_ids: {}}
function encivQuery(query,options) {
return new Promise(async (ok, ko) => {
try {
var data=await Iota.find(query,options);
if (!data || !data.length) return ok([])
return ok(data);
}
catch (error) {
console.error("encivQuery caught error", error);
return ko(error);
}
})
}
function encivQueryAll(query) {
var options={skip: 0, limit: 1000}
var data = [];
return new Promise(async (ok, ko) => {
while (1) {
try {
var newData = await encivQuery(query,options);
data = data.concat(newData);
if (newData.length < options.limit) {
return ok(data);
}
options.skip+=options.limit;
}
catch (error) {
console.error("encivQueryAll caught error", error);
return ko(error)
}
}
})
}
function createOneInTable(iota,table){
return new Promise(async (ok,ko)=>{
try {
var doc=await Iota.create(iota);
encivInfo[table][doc._id]=doc;
encivInfo._ids[table].push(doc._id.toString()); // object properties are always strings
return ok(doc);
}
catch(err){
console.error("create viewer caught error:", err);
return ko(err);
}
})
}
encivInfo.createOneInTable=createOneInTable;
function updateOne(query,update){
if(query._id && typeof query._id==="string") query._id=Iota.ObjectID(query._id);
return new Promise(async (ok,ko)=>{
try {
var result=await Iota.updateOne(query,update);
if(!(result.matchedCount===1 && result.modifiedCount===1))
console.error("encivInfo.updateOne did nothing", query, update)
return ok();
}
catch(err){
console.error("encivInfo updateOne caught error", err);
return ko(err);
}
})
}
encivInfo.updateOne=updateOne;
function replaceOne(query,update){
if(query._id && typeof query._id==="string") query._id=Iota.ObjectID(query._id);
return new Promise(async (ok,ko)=>{
try {
var result=await Iota.replaceOne(query,update);
if(!(result && result.length===1))
console.error("encivInfo.replaceOne returned", result, query, update)
return ok();
}
catch(err){
console.error("encivInfo replaceOne caught error", err);
return ko(err);
}
})
}
encivInfo.replaceOne=replaceOne;
function updateOrCreateIota(query,overWriter){
return new Promise(async (ok,ko)=>{
var viewers=await Iota.find(query);
if(viewers.length==0){ // create the new race
var newViewer=cloneDeep(viewer);
overWriter(newViewer);
try {
var viewerObj=await Iota.create(newViewer);
return ;
}
catch(err){
console.error("create viewer caught error:", err);
ko(err);
}
ok(newViewer);
}else if(viewers.length){ // update the race
if(viewers.length>1) console.error("found multiple viewers with the same path, updating the first one", viewers);
var viewerObj=cloneDeep(viewers[0]);
mergeWithVerbose(viewerObj,viewer);
overWriteViewerInfo(viewerObj)
await Iota.findOneAndReplace({_id: viewerObj._id},viewerObj)
ok(viewerObj)
}
})
}
const maxInList=10000; // the max in a mongo query is really limited by the size of the entire query doc, but that's 16M
function into_Db_add_Table_of_docs_matching_Query_with_List_segments_applied_by_InListifer(db,table, query, list, inListifier) { // inListifier: (q,list)=>q.bp_stage=list but list and inListifier might be undefined
let begin = 0;
return new Promise(async (ok, ko) => {
try {
while (true) {
var q = cloneDeep(query);
var inList=list && list.slice(begin,begin+maxInList) || [];
inListifier && inListifier(q, inList);
var docs = await encivQueryAll(q);
table = encivTableify(db, table, docs);
if((begin+=maxInList)>(list && list.length || 0))
return ok(table);
}
}
catch (err) {
console.error("gatherAll caught error", err);
ko(err);
}
})
}
function encivTableify(db,table, docs) {
if(!db[table]) db[table]={};
docs.forEach(doc => {
if (!db[table][doc._id]) {
db[table][doc._id] = doc;
} else {
if(!showShallowDiff(db[table][doc._id], doc))
console.info("encivTableify _id already present no differences found",doc._id)
}
})
db._ids[table]=Object.keys(db[table]);
return table;
}
function init(YYYY_MM_DD="2020-01-01"){
return new Promise(async (ok,ko)=>{
try{
await Iota.connectInit();
await into_Db_add_Table_of_docs_matching_Query_with_List_segments_applied_by_InListifer(encivInfo,'viewers',{"bp_info.stage_id": {$exists: true}, "bp_info.election_date": {$gte: YYYY_MM_DD}});
await into_Db_add_Table_of_docs_matching_Query_with_List_segments_applied_by_InListifer(encivInfo,'recorders',{"bp_info.candidate_stage_result_id": {$exists: true}, "bp_info.election_date": {$gte: YYYY_MM_DD}});
await into_Db_add_Table_of_docs_matching_Query_with_List_segments_applied_by_InListifer(encivInfo,'participants',{"component.participant.bp_info.election_date": {$gte: YYYY_MM_DD}});
return ok();
}
catch(err){
ko(err);
}
})
}
function disconnect(){
MongoModels.disconnect();
}
encivInfo.init=init;
encivInfo.disconnect=disconnect;
module.exports=encivInfo;