1
|
|
|
import { db } from "./db.js" |
2
|
|
|
import tripModel from "./trip.js" |
3
|
|
|
import apiModel from "./api-key.js" |
4
|
|
|
|
5
|
|
|
|
6
|
1 |
|
const bike = { |
7
|
|
|
/** |
8
|
|
|
* All params except integers |
9
|
|
|
* are returned from DB as wrong type, |
10
|
|
|
* mostly as string values. |
11
|
|
|
* This function converts those |
12
|
|
|
* attributes to correct types |
13
|
|
|
* @param {Object} bikeObj |
14
|
|
|
* @returns the bike object with type-corrected |
15
|
|
|
* attributes |
16
|
|
|
*/ |
17
|
|
|
adjTypes: function(bikeObj) { |
18
|
38 |
|
return { |
19
|
|
|
id: bikeObj.id, |
20
|
|
|
city_id: bikeObj.city_id, |
21
|
|
|
status_id: bikeObj.status_id, |
22
|
|
|
status_descr: bikeObj.status_descr, |
23
|
|
|
charge_perc: parseFloat(bikeObj.charge_perc), |
24
|
|
|
coords: JSON.parse(bikeObj.coords), |
25
|
|
|
active: bikeObj.active === 1, |
26
|
|
|
}; |
27
|
|
|
}, |
28
|
|
|
/** |
29
|
|
|
* Returns true if the bike has an |
30
|
|
|
* ongoing trip, otherwise returns |
31
|
|
|
* false |
32
|
|
|
* @param {Number} bikeId |
33
|
|
|
* @returns {Promise<Boolean>} |
34
|
|
|
*/ |
35
|
|
|
isRented: async function(bikeId) { |
36
|
21 |
|
const result = await db.queryWithArgs(`CALL is_rented(?);`, [bikeId]); |
37
|
21 |
|
if (result[0][0]) { |
38
|
12 |
|
return true; |
39
|
|
|
} |
40
|
9 |
|
return false; |
41
|
|
|
}, |
42
|
|
|
/** |
43
|
|
|
* To be used by admin for deactivating |
44
|
|
|
* a bike. Deactivating a bike |
45
|
|
|
* changes the value of active from |
46
|
|
|
* true to false. Any ongoing trip |
47
|
|
|
* will be ended. The status_id of |
48
|
|
|
* the bike will only be |
49
|
|
|
* changed if current status is |
50
|
|
|
* rented -> in this case it will |
51
|
|
|
* be changed to 1 - available. |
52
|
|
|
* |
53
|
|
|
* Returns a object with a bike |
54
|
|
|
* object: id, city_id, status_id, |
55
|
|
|
* status_descr, charge_perc (0.00-1.00), |
56
|
|
|
* coords (array<float>) and active |
57
|
|
|
* (bool). If an ongoing trip |
58
|
|
|
* was ended, also the trip-object: |
59
|
|
|
* |
60
|
|
|
* @param {Number} bikeId |
61
|
|
|
* @returns {Promise<Object>} |
62
|
|
|
*/ |
63
|
|
|
deactivate: async function(bikeId) { |
64
|
3 |
|
const result = await db.queryWithArgs(`CALL deactivate(?);`, [bikeId]); |
65
|
|
|
// if there is a trip db query returns |
66
|
|
|
// a resultset of three elements |
67
|
3 |
|
if (result.length > 2) { |
68
|
1 |
|
return { |
69
|
|
|
bike: this.adjTypes(result[1][0]), |
70
|
|
|
trip: tripModel.adjTypes(result[0][0]) |
71
|
|
|
}; |
72
|
|
|
} |
73
|
|
|
// if there is no ongoing trip the |
74
|
|
|
// resultset from db contains two elements |
75
|
2 |
|
return { |
76
|
|
|
bike: this.adjTypes(result[0][0]) |
77
|
|
|
}; |
78
|
|
|
}, |
79
|
|
|
/** |
80
|
|
|
* Changes a bikes active attribute |
81
|
|
|
* to true and returns a bike-object: |
82
|
|
|
* id, city_id, status_id, |
83
|
|
|
* status_descr, charge_perc (0.00-1.00), |
84
|
|
|
* coords (array<float>) and active |
85
|
|
|
* (bool). |
86
|
|
|
* @param {Number} bikeId |
87
|
|
|
* @returns {Promise<Object>} |
88
|
|
|
*/ |
89
|
|
|
activate: async function(bikeId) { |
90
|
2 |
|
const result = await db.queryWithArgs(`CALL activate(?);`, [bikeId]); |
91
|
2 |
|
return this.adjTypes(result[0][0]); |
92
|
|
|
}, |
93
|
|
|
/** |
94
|
|
|
* Returns a bike object: |
95
|
|
|
* id (int), city_id (string), status_id (int), |
96
|
|
|
* status_descr (string), charge_perc (float 0.00-1.00), |
97
|
|
|
* coords (array), active (bool) |
98
|
|
|
* @param {Number} bikeId |
99
|
|
|
* @returns {Promise<Object>} |
100
|
|
|
*/ |
101
|
|
|
getOne: async function(bikeId) { |
102
|
19 |
|
const result = await db.queryWithArgs(`CALL single_bike(?);`, [bikeId]); |
103
|
|
|
|
104
|
19 |
|
return this.adjTypes(result[0][0]); |
105
|
|
|
}, |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Returns all bikes regardless |
109
|
|
|
* of status_id, including |
110
|
|
|
* inactive and unavailable ones. |
111
|
|
|
* @returns {Promise<Array>} |
112
|
|
|
*/ |
113
|
|
|
getAll: async function() { |
114
|
1 |
|
const result = await db.queryNoArgs(`CALL all_bikes();`); |
115
|
1 |
|
return result[0].map((bikeObj) => { |
116
|
3 |
|
return this.adjTypes(bikeObj); |
117
|
|
|
}); |
118
|
|
|
}, |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Returns only available bikes in one |
122
|
|
|
* city (for ordinary users) |
123
|
|
|
* @param {String} cityId |
124
|
|
|
* @returns {Promise<Array>} |
125
|
|
|
*/ |
126
|
|
|
getAvail: async function(cityId) { |
127
|
2 |
|
const result = await db.queryWithArgs(`CALL available_bikes(?);`, [cityId]); |
128
|
2 |
|
return result[0].map((bikeObj) => { |
129
|
1 |
|
return this.adjTypes(bikeObj); |
130
|
|
|
}); |
131
|
|
|
}, |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Returns all bikes in one city (for admin) |
135
|
|
|
* @param {String} cityId |
136
|
|
|
* @returns {Promise<Array>} |
137
|
|
|
*/ |
138
|
|
|
getAllInCity: async function(cityId) { |
139
|
2 |
|
const result = await db.queryWithArgs(`CALL bikes_in_city(?);`, [cityId]); |
140
|
2 |
|
return result[0].map((bikeObj) => { |
141
|
2 |
|
return this.adjTypes(bikeObj); |
142
|
|
|
}); |
143
|
|
|
}, |
144
|
|
|
/** |
145
|
|
|
* An array with all available statuses. |
146
|
|
|
* Each status object contains id and descr |
147
|
|
|
* @returns {Promise<Array>} |
148
|
|
|
*/ |
149
|
|
|
statuses: async function() { |
150
|
1 |
|
const result = await db.queryNoArgs(`CALL bike_statuses();`); |
151
|
1 |
|
return result[0]; |
152
|
|
|
}, |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Updates status_id of a bike, |
156
|
|
|
* returns the updated bike-object: |
157
|
|
|
* id, city_id, status_id, status_descr, |
158
|
|
|
* charge_perc, coords, active (bool) |
159
|
|
|
* @param {Number} bikeId |
160
|
|
|
* @param {Number} statusId |
161
|
|
|
* @returns {Promise<Object>} |
162
|
|
|
*/ |
163
|
|
|
updStatus: async function(bikeId, statusId) { |
164
|
6 |
|
const result = await db.queryWithArgs(`CALL upd_bike_status(?, ?);`, [bikeId, statusId]); |
165
|
6 |
|
return this.adjTypes(result[0][0]); |
166
|
|
|
}, |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Updates the city_id of a bike, |
170
|
|
|
* returns the updated bike-object: |
171
|
|
|
* id, city_id, status_id, status_descr, |
172
|
|
|
* charge_perc, coords, active (bool) |
173
|
|
|
* @param {Number} bikeId |
174
|
|
|
* @param {String} cityId |
175
|
|
|
* @returns {Promise<Object>} |
176
|
|
|
*/ |
177
|
|
|
updCity: async function(bikeId, cityId) { |
178
|
3 |
|
const result = await db.queryWithArgs(`CALL update_bike_city(?, ?);`, [bikeId, cityId]); |
179
|
2 |
|
return this.adjTypes(result[0][0]); |
180
|
|
|
}, |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* Updates the bikes status, |
184
|
|
|
* charge percentrage and |
185
|
|
|
* coordinates. |
186
|
|
|
* Does not return anything |
187
|
|
|
* @param {Number} bikeId |
188
|
|
|
* @param {Number} bikeStatus |
189
|
|
|
* @param {Number} chargePerc |
190
|
|
|
* @param {Array} bikeCoords |
191
|
|
|
*/ |
192
|
|
|
updateBike: async function( |
193
|
|
|
bikeId, |
194
|
|
|
bikeStatus, |
195
|
|
|
chargePerc, |
196
|
|
|
bikeCoords, |
197
|
|
|
apiKey |
198
|
|
|
) { |
199
|
|
|
// this method will throw an error if the apiKey does |
200
|
|
|
// not belong to a bike |
201
|
15 |
|
apiModel.isBikeKey(apiKey); |
202
|
|
|
|
203
|
14 |
|
const endedTrip = await db.queryWithArgs(`CALL update_bike(?, ?, ?, ?);`, [bikeId, bikeStatus, chargePerc, JSON.stringify(bikeCoords)]); |
204
|
12 |
|
if (endedTrip.length > 0) { |
205
|
2 |
|
return tripModel.adjTypes(endedTrip[0][0]); |
206
|
|
|
} |
207
|
10 |
|
return undefined; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
|
211
|
|
|
} |
212
|
|
|
|
213
|
|
|
export default bike; |