]> jfr.im git - irc/rizon/acid.git/blob - vizon/src/main/java/net/rizon/acid/plugins/vizon/db/VizonDatabase.java
4b4f5c9ce4ebf58da118c9c086f22530e67b34b1
[irc/rizon/acid.git] / vizon / src / main / java / net / rizon / acid / plugins / vizon / db / VizonDatabase.java
1 /*
2 * Copyright (c) 2017, orillion <orillion@rizon.net>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26 package net.rizon.acid.plugins.vizon.db;
27
28 import java.sql.PreparedStatement;
29 import java.sql.ResultSet;
30 import java.sql.SQLException;
31 import java.sql.Statement;
32 import java.sql.Timestamp;
33 import java.time.LocalDateTime;
34 import java.util.ArrayList;
35 import java.util.Collection;
36 import java.util.List;
37 import net.rizon.acid.plugins.vizon.Bet;
38 import net.rizon.acid.plugins.vizon.RequestStatus;
39 import net.rizon.acid.plugins.vizon.VizonBet;
40 import net.rizon.acid.sql.SQL;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 /**
45 *
46 * @author orillion <orillion@rizon.net>
47 */
48 public class VizonDatabase
49 {
50 private static final Logger logger = LoggerFactory.getLogger(VizonDatabase.class);
51 private final SQL vizonSql;
52
53 public VizonDatabase(SQL vizonSql)
54 {
55 this.vizonSql = vizonSql;
56 }
57
58 /**
59 * Finds a drawing by its id.
60 *
61 * @param id Id of the drawing.
62 *
63 * @return {@link VizonDrawing} or null if not found.
64 */
65 public VizonDrawing getDrawingById(int id)
66 {
67 try
68 {
69 PreparedStatement statement = vizonSql.prepare("SELECT * FROM vizon_drawings "
70 + "WHERE id = ?");
71
72 statement.setInt(1, id);
73
74 ResultSet rs = vizonSql.executeQuery(statement);
75
76 if (rs.next())
77 {
78 return VizonDrawing.fromResultSet(rs);
79 }
80
81 return null;
82 }
83 catch (SQLException ex)
84 {
85 logger.warn("Unable to get next drawing in Vizon Database", ex);
86 return null;
87 }
88 }
89
90 /**
91 * Finds the drawing closest to the specified date.
92 *
93 * @param date Date to look up.
94 *
95 * @return {@link VizonDrawing} or null if none can be found.
96 */
97 public VizonDrawing getDrawingByDate(LocalDateTime date)
98 {
99 if (date == null)
100 {
101 return null;
102 }
103
104 try
105 {
106 PreparedStatement statement = vizonSql.prepare("SELECT * FROM vizon_drawings "
107 + "ORDER BY ABS(TIMESTAMPDIFF(second, drawing_date, ?) "
108 + "LIMIT 1");
109
110 statement.setTimestamp(1, Timestamp.valueOf(date));
111
112 ResultSet rs = vizonSql.executeQuery(statement);
113
114 if (rs.next())
115 {
116 return VizonDrawing.fromResultSet(rs);
117 }
118
119 return null;
120 }
121 catch (SQLException ex)
122 {
123 logger.warn("Unable to get next drawing in Vizon Database", ex);
124 return null;
125 }
126 }
127
128 public VizonDrawing getLatestDrawing()
129 {
130 try
131 {
132 PreparedStatement statement = vizonSql.prepare("SELECT * FROM vizon_drawings "
133 + "ORDER BY id DESC "
134 + "LIMIT 1");
135
136 ResultSet rs = vizonSql.executeQuery(statement);
137
138 if (rs.next())
139 {
140 return VizonDrawing.fromResultSet(rs);
141 }
142
143 return null;
144 }
145 catch (SQLException ex)
146 {
147 logger.warn("Unable to get next drawing in Vizon Database", ex);
148 return null;
149 }
150 }
151
152 /**
153 * Gets the next drawing that's scheduled to take place.
154 *
155 * @return {@link VizonDrawing} or null if nothing is scheduled.
156 */
157 public VizonDrawing getNextDrawing()
158 {
159 try
160 {
161 PreparedStatement statement = vizonSql.prepare("SELECT * FROM vizon_drawings "
162 + "WHERE drawing_date >= NOW() "
163 + "ORDER BY drawing_date DESC "
164 + "LIMIT 1");
165
166 ResultSet rs = vizonSql.executeQuery(statement);
167
168 if (rs.next())
169 {
170 return VizonDrawing.fromResultSet(rs);
171 }
172
173 return null;
174 }
175 catch (SQLException ex)
176 {
177 logger.warn("Unable to get next drawing in Vizon Database", ex);
178 return null;
179 }
180 }
181
182 public VizonUser findUserById(int id)
183 {
184 try
185 {
186 PreparedStatement statement = vizonSql.prepare("SELECT * FROM vizon_users "
187 + "WHERE id = ?");
188
189 statement.setInt(1, id);
190
191 ResultSet rs = vizonSql.executeQuery(statement);
192
193 if (rs.next())
194 {
195 return VizonUser.fromResultSet(rs);
196 }
197
198 return null;
199 }
200 catch (SQLException ex)
201 {
202 logger.warn("Unable to find user by id in Vizon Database", ex);
203 return null;
204 }
205 }
206
207 public VizonUser findUser(String nick)
208 {
209 if (nick == null)
210 {
211 return null;
212 }
213
214 try
215 {
216 PreparedStatement statement = vizonSql.prepare("SELECT * FROM vizon_users WHERE nick = ?");
217 statement.setString(1, nick);
218
219 ResultSet rs = vizonSql.executeQuery(statement);
220
221 if (rs.next())
222 {
223 return VizonUser.fromResultSet(rs);
224 }
225
226 return null;
227 }
228 catch (SQLException ex)
229 {
230 logger.warn("Unable to select or create user in Vizon Database", ex);
231 return null;
232 }
233 }
234
235 /**
236 * Finds or creates a user. A user's id and nick are both unique in the
237 * database.
238 *
239 * @param nick Nick of the user. (Case insensitive)
240 *
241 * @return {@link VizonUser} or null if an error occurred.
242 */
243 public VizonUser findOrCreateUser(String nick)
244 {
245 if (nick == null)
246 {
247 return null;
248 }
249
250 try
251 {
252 PreparedStatement statement = vizonSql.prepare("SELECT * FROM vizon_users WHERE nick = ?");
253 statement.setString(1, nick);
254
255 ResultSet rs = vizonSql.executeQuery(statement);
256
257 if (rs.next())
258 {
259 return VizonUser.fromResultSet(rs);
260 }
261
262 statement = vizonSql.prepare("INSERT INTO vizon_users (nick) VALUES(?)");
263 statement.setString(1, nick);
264
265 int result = vizonSql.executeUpdateBlocking(statement);
266
267 if (result != 1)
268 {
269 // Unable to insert new user.
270 return null;
271 }
272
273 statement = vizonSql.prepare("SELECT * FROM vizon_users WHERE nick = ?");
274 statement.setString(1, nick);
275
276 rs = vizonSql.executeQuery(statement);
277
278 if (rs.next())
279 {
280 return VizonUser.fromResultSet(rs);
281 }
282
283 return null;
284 }
285 catch (SQLException ex)
286 {
287 logger.warn("Unable to select or create user in Vizon Database", ex);
288 return null;
289 }
290 }
291
292 public VizonRequest findVhostRequestByUserId(int userId)
293 {
294 try
295 {
296 PreparedStatement statement = vizonSql.prepare("SELECT vizon_requests.*, vizon_users.nick FROM vizon_requests "
297 + "INNER JOIN vizon_users "
298 + "ON vizon_users.id = vizon_requests.user_id "
299 + "WHERE user_id = ? "
300 + "AND status = ?");
301 statement.setInt(1, userId);
302 statement.setInt(2, RequestStatus.PENDING);
303
304 ResultSet rs = vizonSql.executeQuery(statement);
305
306 if (rs.next())
307 {
308 return VizonRequest.fromResultSet(rs);
309 }
310
311 return null;
312 }
313 catch (SQLException ex)
314 {
315 logger.warn("Unable to find vhost request for nick", ex);
316 return null;
317 }
318 }
319
320 public VizonRequest findVhostRequest(String nick)
321 {
322 if (nick == null)
323 {
324 return null;
325 }
326
327 try
328 {
329 PreparedStatement statement = vizonSql.prepare("SELECT vizon_requests.*, vizon_users.nick FROM vizon_requests"
330 + "INNER JOIN vizon_users "
331 + "ON vizon_users.id = vizon_requests.user_id"
332 + "WHERE vizon_users.nick = ?");
333 statement.setString(1, nick);
334
335 ResultSet rs = vizonSql.executeQuery(statement);
336
337 if (rs.next())
338 {
339 return VizonRequest.fromResultSet(rs);
340 }
341
342 return null;
343 }
344 catch (SQLException ex)
345 {
346 logger.warn("Unable to find vhost request for nick", ex);
347 return null;
348 }
349 }
350
351 public Collection<VizonRequest> findPendingVhostRequests()
352 {
353 try
354 {
355 PreparedStatement statement = vizonSql.prepare("SELECT vizon_requests.*, vizon_users.nick FROM vizon_requests "
356 + "INNER JOIN vizon_users "
357 + "ON vizon_users.id = vizon_requests.user_id "
358 + "WHERE vizon_requests.status = ?");
359 statement.setInt(1, RequestStatus.PENDING);
360
361 ResultSet rs = vizonSql.executeQuery(statement);
362
363 List<VizonRequest> requests = new ArrayList<>();
364
365 while (rs.next())
366 {
367 VizonRequest request = VizonRequest.fromResultSet(rs);
368
369 if (request != null)
370 {
371 requests.add(request);
372 }
373 }
374
375 return requests;
376 }
377 catch (SQLException ex)
378 {
379 logger.warn("Unable to find vhost request for nick", ex);
380 return null;
381 }
382 }
383
384 public boolean insertRequest(VizonRequest request)
385 {
386 if (request == null)
387 {
388 return false;
389 }
390
391 try
392 {
393 PreparedStatement statement = vizonSql.prepare("INSERT INTO vizon_requests "
394 + "(user_id, vhost, status, reason, oper) "
395 + "VALUES (?, ?, ?, ?, ?)");
396 statement.setInt(1, request.getUserId());
397 statement.setString(2, request.getVhost());
398 statement.setInt(3, request.getStatus());
399 statement.setString(4, request.getReason());
400 statement.setString(5, request.getOper());
401
402 int result = vizonSql.executeUpdateBlocking(statement);
403
404 return result > 0;
405 }
406 catch (SQLException ex)
407 {
408 logger.warn("Unable to insert vhost request", ex);
409 return false;
410 }
411 }
412
413 public boolean updateRequest(VizonRequest request)
414 {
415 if (request == null)
416 {
417 return false;
418 }
419
420 try
421 {
422 PreparedStatement statement = vizonSql.prepare("UPDATE vizon_requests "
423 + "SET vhost = ?, "
424 + "status = ?, "
425 + "reason = ?, "
426 + "oper = ? "
427 + "WHERE id = ?");
428 statement.setString(1, request.getVhost());
429 statement.setInt(2, request.getStatus());
430 statement.setString(3, request.getReason());
431 statement.setString(4, request.getOper());
432 statement.setInt(5, request.getId());
433
434 int result = vizonSql.executeUpdateBlocking(statement);
435
436 return true;
437 }
438 catch (SQLException ex)
439 {
440 logger.warn("Unable to insert vhost request", ex);
441 return false;
442 }
443 }
444
445 public boolean updateUser(VizonUser user)
446 {
447 if (user == null)
448 {
449 return false;
450 }
451
452 try
453 {
454 PreparedStatement statement = vizonSql.prepare("UPDATE vizon_users "
455 + "SET vhost = ?, "
456 + "eligible = ?, "
457 + "bold = ?, "
458 + "obtained = ?, "
459 + "obtained_id = ?, "
460 + "multiplier = ?, "
461 + "jackpot = ?, "
462 + "permanent = ?, "
463 + "days = ? "
464 + "WHERE id = ?");
465
466 statement.setString(1, user.getVhost());
467 statement.setBoolean(2, user.isEligible());
468 statement.setBoolean(3, user.isBold());
469 statement.setTimestamp(4, Timestamp.valueOf(user.getObtained()));
470 statement.setInt(5, user.getObtainedId());
471 statement.setInt(6, user.getMultiplier());
472 statement.setBoolean(7, user.isJackpot());
473 statement.setBoolean(8, user.isPermanent());
474 statement.setInt(9, user.getDays());
475 statement.setInt(10, user.getId());
476
477 int updated = vizonSql.executeUpdateBlocking(statement);
478
479 return updated > 0;
480 }
481 catch (SQLException ex)
482 {
483 logger.warn("Unable to select bet for user and drawing in Vizon Database", ex);
484 return false;
485 }
486 }
487
488 public boolean updateDrawing(VizonDrawing drawing)
489 {
490 if (drawing == null)
491 {
492 return false;
493 }
494
495 try
496 {
497 PreparedStatement statement = vizonSql.prepare("UPDATE vizon_drawings "
498 + "SET first = ?, "
499 + "second = ?, "
500 + "third = ?, "
501 + "fourth = ?, "
502 + "fifth = ?, "
503 + "sixth = ? "
504 + "WHERE id = ?");
505
506 statement.setInt(1, drawing.getDraws().get(0));
507 statement.setInt(2, drawing.getDraws().get(1));
508 statement.setInt(3, drawing.getDraws().get(2));
509 statement.setInt(4, drawing.getDraws().get(3));
510 statement.setInt(5, drawing.getDraws().get(4));
511 statement.setInt(6, drawing.getDraws().get(5));
512 statement.setInt(7, drawing.getId());
513
514 int updated = vizonSql.executeUpdateBlocking(statement);
515
516 return updated > 0;
517 }
518 catch (SQLException ex)
519 {
520 logger.warn("Unable to select bet for user and drawing in Vizon Database", ex);
521 return false;
522 }
523 }
524
525 /**
526 * Attempts to find a {@link VizonBet} of the user for the specified
527 * drawing.
528 *
529 * @param user User to find for.
530 * @param drawing Drawing to find for.
531 *
532 * @return {@link VizonBet} or null if none can be found.
533 */
534 public VizonBet findBetForUserAndDrawing(VizonUser user, VizonDrawing drawing)
535 {
536 if (user == null || drawing == null)
537 {
538 return null;
539 }
540
541 try
542 {
543 PreparedStatement statement = vizonSql.prepare("SELECT * FROM vizon_bets WHERE vizon_users_id = ? AND vizon_drawings_id = ?");
544 statement.setInt(1, user.getId());
545 statement.setInt(2, drawing.getId());
546
547 ResultSet rs = vizonSql.executeQuery(statement);
548
549 if (rs.next())
550 {
551 return VizonBet.fromResultSet(rs);
552 }
553
554 return null;
555 }
556 catch (SQLException ex)
557 {
558 logger.warn("Unable to select bet for user and drawing in Vizon Database", ex);
559 return null;
560 }
561 }
562
563 public List<VizonBet> findBetsForUser(VizonUser user)
564 {
565 return null;
566 }
567
568 public List<VizonBet> findBetsForDrawing(VizonDrawing drawing)
569 {
570 List<VizonBet> bets = new ArrayList<>();
571
572 if (drawing == null)
573 {
574 return bets;
575 }
576
577 try
578 {
579 PreparedStatement statement = vizonSql.prepare("SELECT * FROM vizon_bets WHERE vizon_drawings_id = ?");
580 statement.setInt(1, drawing.getId());
581
582 ResultSet rs = vizonSql.executeQuery(statement);
583
584 while (rs.next())
585 {
586 VizonBet bet = VizonBet.fromResultSet(rs);
587
588 if (bet == null)
589 {
590 continue;
591 }
592
593 bets.add(bet);
594 }
595 }
596 catch (SQLException ex)
597 {
598 logger.warn("Unable to select bets for drawing in Vizon Database", ex);
599 }
600
601 return bets;
602 }
603
604 /**
605 * Creates a new bet for the user for the specified drawing.
606 *
607 * @param user User to place the bet for.
608 * @param drawing Drawing to place the bet in.
609 * @param bet Bet to place.
610 *
611 * @return True if successful, false otherwise.
612 */
613 public boolean createBetForUser(VizonUser user, VizonDrawing drawing, Bet bet)
614 {
615 if (user == null || drawing == null || bet == null)
616 {
617 return false;
618 }
619
620 try
621 {
622 PreparedStatement statement = vizonSql.prepare("INSERT INTO vizon_bets "
623 + "(vizon_users_id, vizon_drawings_id, first, second, third, fourth, fifth, sixth) "
624 + "VALUES(?, ?, ?, ?, ?, ?, ?, ?)");
625
626 statement.setInt(1, user.getId());
627 statement.setInt(2, drawing.getId());
628 statement.setInt(3, bet.getFirst());
629 statement.setInt(4, bet.getSecond());
630 statement.setInt(5, bet.getThird());
631 statement.setInt(6, bet.getFourth());
632 statement.setInt(7, bet.getFifth());
633 statement.setInt(8, bet.getSixth());
634
635 int inserted = vizonSql.executeUpdateBlocking(statement);
636
637 return inserted > 0;
638 }
639 catch (SQLException ex)
640 {
641 logger.warn("Error while inserting bet for user in Vizon Database", ex);
642 return false;
643 }
644 }
645
646 /**
647 * Finds a scheduled drawing that has not been run yet (i.e. First == null)
648 *
649 * @return {@link VizonDrawing} or null if no unrun drawings exist
650 */
651 public VizonDrawing findEarliestUnrunDrawing()
652 {
653 try
654 {
655 PreparedStatement statement = vizonSql.prepare("SELECT * FROM vizon_drawings "
656 + "WHERE first IS NULL "
657 + "ORDER BY drawing_date "
658 + "LIMIT 1");
659
660 ResultSet rs = vizonSql.executeQuery(statement);
661
662 if (!rs.next())
663 {
664 return null;
665 }
666
667 return VizonDrawing.fromResultSet(rs);
668 }
669 catch (SQLException ex)
670 {
671 logger.warn("Error while trying to find earliest drawing in Vizon Database", ex);
672 return null;
673 }
674 }
675
676 public VizonDrawing createDrawing(LocalDateTime date)
677 {
678 try
679 {
680 PreparedStatement statement = vizonSql.prepare("INSERT INTO vizon_drawings "
681 + "(drawing_date) "
682 + "VALUES(?)",
683 Statement.RETURN_GENERATED_KEYS);
684
685 statement.setTimestamp(1, Timestamp.valueOf(date));
686
687 int inserted = vizonSql.executeUpdateBlocking(statement);
688
689 ResultSet rs = statement.getGeneratedKeys();
690
691 if (rs == null || !rs.next())
692 {
693 return null;
694 }
695
696 int id = rs.getInt(1);
697
698 statement = vizonSql.prepare("SELECT * FROM vizon_drawings "
699 + "WHERE id = ?");
700
701 statement.setInt(1, id);
702
703 rs = vizonSql.executeQuery(statement);
704
705 if (rs == null || !rs.next())
706 {
707 return null;
708 }
709
710 return VizonDrawing.fromResultSet(rs);
711 }
712 catch (SQLException ex)
713 {
714 logger.warn("Error while trying to create drawing in Vizon Database", ex);
715 return null;
716 }
717 }
718
719 public List<VizonUser> findAllUsers()
720 {
721 List<VizonUser> users = new ArrayList<>();
722
723 try
724 {
725 PreparedStatement statement = vizonSql.prepare("SELECT * FROM vizon_users");
726
727 ResultSet rs = vizonSql.executeQuery(statement);
728
729 while (rs.next())
730 {
731 VizonUser user = VizonUser.fromResultSet(rs);
732
733 if (user == null)
734 {
735 continue;
736 }
737
738 users.add(user);
739 }
740 }
741 catch (SQLException ex)
742 {
743 logger.warn("Error while trying to get all users in Vizon Database", ex);
744 }
745
746 return users;
747 }
748
749 public int expireVhosts()
750 {
751 try
752 {
753 PreparedStatement statement = vizonSql.prepare("UPDATE vizon_users "
754 + "SET vhost = null, "
755 + "eligible = 0, "
756 + "obtained = null, "
757 + "obtained_id = -1, "
758 + "multiplier = 0, "
759 + "permanent = 0, "
760 + "days = 0, "
761 + "bold = 0 "
762 + "WHERE permanent = 0 "
763 + "AND DATE_ADD(obtained, INTERVAL days DAY) < NOW()");
764
765 return vizonSql.executeUpdateBlocking(statement);
766
767 }
768 catch (SQLException ex)
769 {
770 logger.warn("Error in SQL statement to expire vhosts", ex);
771 return 0;
772 }
773 }
774 }