-
Notifications
You must be signed in to change notification settings - Fork 0
/
database.js
231 lines (197 loc) · 6.1 KB
/
database.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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/* Config */
let mongoose = require('mongoose');
const username = process.env.DB_USERNAME;
const password = process.env.DB_PASSWORD;
const server = process.env.DB_SERVER;
const database = process.env.DB_NAME;
mongoose.set('useFindAndModify', false);
var Schema = mongoose.Schema;
/* Models */
//TODO These should be in a models file
const Panel = Schema({
id: { type: Number, required: true },
title: { type: String, required: true },
subtitle: { type: String, required: false },
body: { type: String, required: false },
bottomText: { type: String, required: false },
width: { type: String, required: false },
height: { type: String, required: false },
type: { type: String, required: false } //"Type" reserved
});
const Wall = mongoose.model("Wall", Schema({
title: { type: String, required: true },
icon: { type: String, required: false },
bgColor: { type: String, required: false },
iconColor: { type: String, required: false },
panelOrder: { type: [Number], required: true },
panels: [Panel]
}), "Walls");
/* DB Class */
class Database {
constructor() {
this._connect()
}
_connect() {
//var mongoDB = `mongodb://${username}:${password}@${server}/${database}`;
var mongoDB = `mongodb://${server}/${database}`;
mongoose.connect(mongoDB, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
console.log("Connected.");
}).catch(() => {
console.log("Error.");
});
var db = mongoose.connection;
//Bind connection to error event (to get notification of connection errors)
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
}
/**
* Return a list of all wall configs (without panels!)
* @return {Array} walls in a list
*/
async getWallList() {
return await Wall.find({}, { panels: 0 });
}
/**
* Get a single wall (including panels) with optional query.
* @param {String} wallId Will be used as ObjectId via findById to get the wall.
* @param {Object} query
*/
async getWall(wallId, query) {
if (!query) {
query = {};
}
let wall = await Wall.findById(wallId);
return wall;
}
/**
* Get a single panel from given wall.
*
* @param {String} wallId Will be used as ObjectId via findById to get the wall.
* @param {Integer} panelIndex Index in array
* @return {Panel} Content of single panel - see schema
*/
async getPanel(wallId, panelIndex) {
let wall = await this.getWall(wallId);
try {
let panel = wall[0].panels[panelIndex];
return panel;
} catch (e) {
//TODO review status codes and differentiate errors
return { status: 404, message: "Couldn't load panel." };
}
}
/**
* Generate a new wall based on passed in data.
*
* @param {Object} wallData Wall data to populate Wall document
*/
async createWall(wallData) {
let newWall = new Wall({
_id: mongoose.Types.ObjectId(),
title: wallData.title,
icon: wallData.icon,
iconColor: wallData.iconColor,
bgColor: wallData.bgColor,
panels: [],
panelOrder: []
});
Wall.create(newWall, function (err, success) {
if (err) {
//TODO Error #
console.log(err);
return { status: -1, message: "Couldn't add wall." };
}
else {
return success;
}
});
}
/**
* Generate a new panel based on based in data and append to specified wall.
*
* @param {String} wallId Object ID to append with new panel
* @param {Object} panelData Object with data to populate a new panel
*/
async createPanel(wallId, panelData) {
let wall = await Wall.findById(wallId, "panelOrder").exec();
panelData["id"] = Math.max(...wall.panelOrder) + 1;
let result = Wall.findOneAndUpdate(
{ _id: wallId },
{ $push: { "panels": panelData, "panelOrder": panelData["id"] } },
{ new: true }
);
return result;
}
/**
* Update a wall
* @param {String} wallId String representation of wall ID to be turned into object ID
* @param {Object} wallUpdateData JSON object of data to use to update the wall
*/
async updateWall(wallId, wallUpdateData) {
let updatedWall = {};
Object.keys(wallUpdateData).forEach((key) => {
//TODO Validation.
updatedWall[key] = wallUpdateData[key];
});
//TODO Test - might be able to just send wallId w/o conversion
let wall = await Wall.findByIdAndUpdate(wallId, updatedWall, {}, (err, result) => {
if (err) {
console.log("Error updating: ");
console.log(updatedWall);
return err;
} else {
return result;
}
});
return wall;
};
/**
* Update an existing panel based on based in data and append to specified wall.
*
* @param {String} wallId Object ID for wall containing panel to update
* @param {Object} panelData JSON object with update data for panel
*/
async updatePanel(wallId, panelIndex, panelUpdateData) {
let updatedPanel = {};
let result = Wall.findOne({ _id: wallId }).then((wall) => {
let panel = wall.panels[panelIndex];
Object.keys(panelUpdateData).forEach((key) => {
//TODO Validation.
panel[key] = panelUpdateData[key];
});
wall.save();
}).catch(err => {
console.log("lol");
console.log(err);
});
return result;
}
/**
* Delete a single panel on a particular wall.
*
* @param {String} wallId
* @param {String} panelIndex
*/
async deletePanel(wallId, panelIndex) {
return await Wall.findOne({ _id: wallId }).then((wall) => {
let panel = wall.panels.filter((panel) => { return panel.id == panelIndex });
wall.panelOrder.splice(wall.panelOrder.indexOf(panelIndex), 1);
wall.panels.pull({ _id: panel._id });
return wall.save().then(function (doc) {
if (doc) {
return "Successfully deleted panel.";
} else {
return "Couldn't delete panel... try again later!";
}
});
});
}
async deleteWall(wallId) {
let deletedWall = Wall.deleteOne({ "_id": wallId });
return deletedWall;
}
}
module.exports = new Database()