├── .DS_Store
├── .gitattributes
├── README.md
├── memorySQL.uml
├── memorySQL.umlcd
├── memorySQLUML.png
└── src
├── MainDriver.java
└── com
└── memorysql
└── model
├── Column.java
├── Database.java
├── Row.java
├── SQL.java
├── Table.java
├── Type.java
├── constraint
├── Constraint.java
├── IntegerConstraint.java
├── IsRequiredConstraint.java
└── StringConstrain.java
└── operator
├── EqualsOperator.java
├── NotEqualsOperator.java
└── Operator.java
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepanshujain92/MemorySQL/3e2643fa62ab4befd59bfa0e6dbb041a32019e57/.DS_Store
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MemorySQL
2 | Machine Coding | Object Oriented Design for SQL in Memory
3 | 
4 |
--------------------------------------------------------------------------------
/memorySQL.uml:
--------------------------------------------------------------------------------
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 | java
83 | return object.getClass().equals(Integer.class) && (int)(object) <=1024 && (int)(object) >=-1024;
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | java
101 | if(object == null || object == "")
102 | return false;
103 | return true;
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 | java
121 | return object.getClass().equals(String.class) && object.toString().length() <=20;
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | java
138 | this.name = "equals";
139 | this.sign = "=";
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 | java
149 | return (filterValue.equals(value)|| filterValue == value);
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 | java
171 | this.name = "not equals";
172 | this.sign = "!=";
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 | java
182 | return !(filterValue.equals(value)|| filterValue == value);
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 |
232 |
233 |
234 |
235 |
236 |
237 |
238 | java
239 | this.name = dbName;
240 | this.tables = new HashMap<String, Table>();
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 | java
249 | if (!dbMap.containsKey(dbName)) {
250 | dbMap.put(dbName, new Database(dbName));
251 | }
252 | return dbMap.get(dbName);
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 | java
261 | tables.put(tableName, new Table(tableName));
262 | return tables.get(tableName);
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 | java
271 | return tables.get(tableName);
272 |
273 |
274 |
275 |
276 |
277 |
278 | java
279 | tables.remove(tableName);
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 | java
327 | this.values = values;
328 | this.rowId = rowId;
329 |
330 |
331 |
332 |
333 |
334 |
335 | java
336 | return "Row [rowId=" + rowId + ", values=" + values + "]";
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 | java
361 | this.db = db;
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 | java
380 | List<Row> results = new ArrayList<Row>();
381 | Set<Entry<Integer, Row>> data = db.getTable(tableName).getRows().entrySet();
382 | for (Map.Entry<Integer, Row> entry : data) {
383 | if (op.applyOp(entry.getValue().getValues().get(columnname), value))
384 | results.add(entry.getValue());
385 | }
386 | return results;
387 |
388 |
389 |
390 |
391 |
392 |
393 | java
394 | String[] splitedQuery = insertQuery.toLowerCase().split("\\s");
395 | String[] values = parseValues(splitedQuery[3]);
396 | Table table = db.getTable(splitedQuery[2]);
397 | if (table == null) {
398 | System.out.print("Table not found");
399 | return;
400 | }
401 | Set<String> columns = table.getColumns().keySet();
402 |
403 | if (values.length != columns.size()) {
404 | System.out.print("Values length invalid");
405 | return;
406 | }
407 | LinkedHashMap<String, Object> record = new LinkedHashMap<String, Object>();
408 |
409 | var wrapper = new Object() {
410 | int ordinal = 0;
411 | };
412 | columns.forEach(col -> insert(table, record, col, values[wrapper.ordinal++]));
413 |
414 | table.insert(record);
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 | java
427 | if (table.getColumns().get(col).type == Type.INTEGER)
428 | record.put(col, Integer.valueOf(value));
429 | else
430 | record.put(col, value);
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 | java
442 | return splitedQuery.replaceAll("values", "").replaceAll("\"", "").replaceAll("\\)", "").replaceAll("\"", "")
443 | .replaceAll("\\(", "").replaceAll(";", "").split(",");
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 | java
509 | this.tableName = tableName;
510 | this.rows = new HashMap<>();
511 | this.columns = new LinkedHashMap<>();
512 | this.autoId = 0;
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 | java
521 | Integer id = this.getAutoId();
522 | Set<String> colNames = columns.keySet();
523 | for(String columnName: colNames) {
524 | columns.get(columnName).validate(values.get(columnName));
525 | }
526 |
527 | Row row = new Row(id, values);
528 | rows.put(id, row);
529 |
530 | return true;
531 |
532 |
533 |
534 |
535 |
536 |
537 | java
538 | rows.remove(rowId);
539 |
540 |
541 |
542 | java
543 | System.out.print(rows);
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 | java
553 | if(columns.containsKey(columnName)) {
554 | System.out.print("Column Already Exist");
555 | return null;
556 | }
557 | Column column = new Column(columnName, type);
558 | columns.put(columnName, column);
559 | return column;
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 | java
615 | this.name = name;
616 | this.type = type;
617 | this.cons = new HashSet<>();
618 |
619 |
620 |
621 |
622 | java
623 | cons.add(con);
624 |
625 |
626 |
627 |
628 | java
629 | Iterator<Constraint> it = cons.iterator();
630 | while (it.hasNext()) {
631 | if (!it.next().validate(value)) {
632 | throw new RuntimeException("Constraint violation");
633 | }
634 | }
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 | Problem: Design an in-memory database using object-oriented principles.
681 |
682 |
683 |
684 |
685 |
686 |
687 | java
688 | Database database = Database.getInstance("company");
689 | SQL sql = new SQL(database);
690 | Table employee = database.createTable("employee");
691 | Column id = employee.createColumn("id", Type.INTEGER);
692 | id.addCons(new IntegerConstraint());
693 |
694 | Column username = employee.createColumn("username", Type.STRING);
695 | username.addCons(new StringConstrain());
696 | username.addCons(new IsRequiredConstraint());
697 |
698 | Column password = employee.createColumn("password", Type.STRING);
699 | password.addCons(new StringConstrain());
700 |
701 | Column salary= employee.createColumn("salary", Type.INTEGER);
702 | sql.insert("INSERT INTO EMPLOYEE values(101,\"Deepanshu\",\"password\",1100);");
703 | sql.insert("INSERT INTO EMPLOYEE values(101,\"Deepanshu\",\"\");");
704 |
705 | database.getTable("employee").printAllRecords();
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 | java
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 | java
820 | return currentDatabase;
821 |
822 |
823 |
824 |
825 |
826 |
827 | java
828 | Database.currentDatabase = currentDatabase;
829 | getInstance(Database.currentDatabase);
830 |
831 |
832 |
833 |
834 | java
835 | return values;
836 |
837 |
838 |
839 |
840 | java
841 | this.values = values;
842 |
843 |
844 |
845 |
846 | java
847 | return columns;
848 |
849 |
850 |
851 |
852 |
853 |
854 | java
855 | synchronized (autoId) {
856 | return autoId++;
857 | }
858 |
859 |
860 |
861 |
862 |
863 |
864 | java
865 | this.autoId = autoId;
866 |
867 |
868 |
869 |
870 | java
871 | return type;
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
--------------------------------------------------------------------------------
/memorySQL.umlcd:
--------------------------------------------------------------------------------
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 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 |
693 |
694 |
695 |
696 |
697 |
698 |
699 |
700 |
701 |
702 |
703 |
704 |
705 |
706 |
707 |
708 |
709 |
710 |
711 |
712 |
713 |
714 |
715 |
716 |
717 |
718 |
719 |
720 |
721 |
722 |
723 |
724 |
725 |
726 |
727 |
728 |
729 |
730 |
731 |
732 |
733 |
734 |
735 |
736 |
737 |
738 |
739 |
740 |
741 |
742 |
743 |
744 |
745 |
746 |
747 |
748 |
749 |
750 |
751 |
752 |
753 |
754 |
755 |
756 |
757 |
758 |
759 |
760 |
761 |
762 |
763 |
764 |
765 |
766 |
767 |
768 |
769 |
770 |
771 |
772 |
773 |
774 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
782 |
783 |
784 |
785 |
786 |
787 |
788 |
789 |
790 |
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 |
849 |
850 |
851 |
852 |
853 |
854 |
855 |
856 |
857 |
858 |
859 |
860 |
861 |
862 |
863 |
864 |
865 |
866 |
867 |
868 |
869 |
870 |
871 |
872 |
873 |
874 |
875 |
876 |
877 |
878 |
879 |
880 |
881 |
882 |
883 |
884 |
885 |
886 |
887 |
888 |
889 |
890 |
891 |
892 |
893 |
894 |
895 |
896 |
897 |
898 |
899 |
900 |
901 |
902 |
903 |
904 |
905 |
906 |
907 |
908 |
909 |
910 |
911 |
912 |
913 |
914 |
915 |
916 |
917 |
918 |
919 |
920 |
921 |
922 |
923 |
924 |
925 |
926 |
927 |
928 |
929 |
930 |
931 |
932 |
933 |
934 |
935 |
936 |
937 |
938 |
939 |
940 |
941 |
942 |
943 |
944 |
945 |
946 |
947 |
948 |
949 |
950 |
951 |
952 |
953 |
954 |
955 |
956 |
957 |
958 |
959 |
960 |
961 |
962 |
963 |
964 |
965 |
966 |
967 |
968 |
969 |
970 |
971 |
972 |
973 |
974 |
975 |
976 |
977 |
978 |
979 |
980 |
981 |
982 |
983 |
984 |
985 |
986 |
987 |
988 |
989 |
990 |
991 |
992 |
993 |
994 |
995 |
996 |
997 |
998 |
999 |
1000 |
1001 |
1002 |
1003 |
1004 |
1005 |
1006 |
1007 |
1008 |
1009 |
1010 |
1011 |
1012 |
1013 |
1014 |
1015 |
1016 |
1017 |
1018 |
1019 |
1020 |
1021 |
1022 |
1023 |
1024 |
1025 |
1026 |
1027 |
1028 |
1029 |
1030 |
1031 |
1032 |
1033 |
1034 |
1035 |
1036 |
1037 |
1038 |
1039 |
1040 |
1041 |
1042 |
1043 |
1044 |
1045 |
1046 |
1047 |
1048 |
1049 |
1050 |
1051 |
1052 |
1053 |
1054 |
1055 |
1056 |
1057 |
1058 |
1059 |
1060 |
1061 |
1062 |
1063 |
1064 |
1065 |
1066 |
1067 |
1068 |
1069 |
1070 |
1071 |
1072 |
1073 |
1074 |
1075 |
1076 |
1077 |
1078 |
1079 |
1080 |
1081 |
1082 |
1083 |
1084 |
1085 |
1086 |
1087 |
1088 |
1089 |
--------------------------------------------------------------------------------
/memorySQLUML.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/deepanshujain92/MemorySQL/3e2643fa62ab4befd59bfa0e6dbb041a32019e57/memorySQLUML.png
--------------------------------------------------------------------------------
/src/MainDriver.java:
--------------------------------------------------------------------------------
1 |
2 |
3 | import java.util.*;
4 |
5 | import com.memorysql.model.*;
6 | import com.memorysql.model.constraint.*;
7 | import com.memorysql.model.operator.EqualsOperator;
8 | /*
9 | * Problem: Design an in-memory database using object-oriented principles.
10 | */
11 |
12 | public class MainDriver {
13 | public static void main(String[] args) {
14 | Database database = Database.getInstance("company");
15 | SQL sql = new SQL(database);
16 | Table employee = database.createTable("employee");
17 | Column id = employee.createColumn("id", Type.INTEGER);
18 | id.addCons(new IntegerConstraint());
19 |
20 | Column username = employee.createColumn("username", Type.STRING);
21 | username.addCons(new StringConstrain());
22 | username.addCons(new IsRequiredConstraint());
23 |
24 | Column password = employee.createColumn("password", Type.STRING);
25 | password.addCons(new StringConstrain());
26 |
27 | Column salary= employee.createColumn("salary", Type.INTEGER);
28 | sql.insert("INSERT INTO EMPLOYEE values(101,\"Deepanshu\",\"password\",1100);");
29 | sql.insert("INSERT INTO EMPLOYEE values(101,\"Deepanshu\",\"\");");
30 |
31 | database.getTable("employee").printAllRecords();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/Column.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model;
2 |
3 | import java.util.HashSet;
4 | import java.util.Iterator;
5 | import java.util.Set;
6 |
7 | import com.memorysql.model.constraint.Constraint;
8 |
9 | public class Column {
10 | Type type;
11 | private String name;
12 | private Set cons;
13 | public Column(String name, Type type) {
14 | this.name = name;
15 | this.type = type;
16 | this.cons = new HashSet<>();
17 | }
18 |
19 | public Type getType() {
20 | return type;
21 | }
22 |
23 | public String getName() {
24 | return name;
25 | }
26 |
27 | public Set getCons() {
28 | return cons;
29 | }
30 |
31 | public void setCons(Set cons) {
32 | this.cons = cons;
33 | }
34 |
35 | public void addCons(Constraint con) {
36 | cons.add(con);
37 | }
38 |
39 | public void validate(Object value) {
40 | Iterator it = cons.iterator();
41 | while (it.hasNext()) {
42 | if (!it.next().validate(value)) {
43 | throw new RuntimeException("Constraint violation");
44 | }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/Database.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model;
2 |
3 |
4 | import java.util.*;
5 | import java.util.concurrent.ConcurrentHashMap;
6 |
7 | public class Database {
8 | private static String currentDatabase;
9 | public static String getCurrentDatabase() {
10 | return currentDatabase;
11 | }
12 |
13 | public static void setCurrentDatabase(String currentDatabase) {
14 | Database.currentDatabase = currentDatabase;
15 | getInstance(Database.currentDatabase);
16 | }
17 |
18 | private String name;
19 | private static Map dbMap = new ConcurrentHashMap<>();
20 |
21 | private Database(String dbName) {
22 | this.name = dbName;
23 | this.tables = new HashMap();
24 | }
25 |
26 | public static Database getInstance(String dbName) {
27 | if (!dbMap.containsKey(dbName)) {
28 | dbMap.put(dbName, new Database(dbName));
29 | }
30 | return dbMap.get(dbName);
31 | }
32 |
33 | public String getName() {
34 | return name;
35 | }
36 |
37 | private Map tables;
38 |
39 | public Table createTable(String tableName) {
40 | tables.put(tableName, new Table(tableName));
41 | return tables.get(tableName);
42 | }
43 |
44 | public Table getTable(String tableName) {
45 | return tables.get(tableName);
46 | }
47 |
48 | public void deleteTable(String tableName) {
49 | tables.remove(tableName);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/Row.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model;
2 |
3 | import java.util.*;
4 |
5 | public class Row {
6 |
7 | public Row(Integer rowId, LinkedHashMap values) {
8 | this.values = values;
9 | this.rowId = rowId;
10 | }
11 |
12 | private Integer rowId;
13 |
14 | public Integer getRowId() {
15 | return rowId;
16 | }
17 |
18 | public void setRowId(Integer rowId) {
19 | this.rowId = rowId;
20 | }
21 |
22 | public Map getValues() {
23 | return values;
24 | }
25 |
26 | public void setValues(LinkedHashMap values) {
27 | this.values = values;
28 | }
29 |
30 | private LinkedHashMap values;
31 |
32 |
33 |
34 | @Override
35 | public String toString() {
36 | return "Row [rowId=" + rowId + ", values=" + values + "]";
37 | }
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/SQL.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model;
2 |
3 | import java.util.ArrayList;
4 | import java.util.LinkedHashMap;
5 | import java.util.List;
6 | import java.util.Map;
7 | import java.util.Set;
8 | import java.util.Map.Entry;
9 |
10 | import com.memorysql.model.operator.Operator;
11 |
12 | /*In-memory SQL-like Database
13 | Problem Statement
14 |
15 | The objective is to design and implement an in-memory SQL-like database, which should support the following set of operations / functionality:
16 |
17 | It should be possible to create or delete tables in a database.
18 | A table definition comprises columns which have types. They can also have constraints
19 | The supported column types are string and int.
20 | The string type can have a maximum length of 20 characters.
21 | The int type can have a minimum value of -1024 and a maximum value of 1024.
22 | Support for mandatory fields (tagging a column as required)
23 | It should be possible to insert records in a table.
24 | It should be possible to print all records in a table.
25 | It should be possible to filter and display records whose column values match a given value.
26 |
27 |
28 | // Table => {Employee}
29 | // Columns = {Integer ID, String name, String department, Integer salary}
30 | // Map
31 | // 1 -> {1,Deepanshu,Engineering,10000}
32 | // filter=> {Deepanshu, =, name, Employee}
33 | // map.data.filter(emp->emp(index).filter(deepanshu))
34 | * */
35 |
36 | public class SQL {
37 | Database db;
38 | public SQL(Database db){
39 | this.db = db;
40 | }
41 | public List Query(String tableName, Object value, String columnname, String columnsToSelect, Operator op) {
42 | List results = new ArrayList();
43 | Set> data = db.getTable(tableName).getRows().entrySet();
44 | for (Map.Entry entry : data) {
45 | if (op.applyOp(entry.getValue().getValues().get(columnname), value))
46 | results.add(entry.getValue());
47 | }
48 | return results;
49 | }
50 |
51 | // INSERT INTO EMPLOYEE values("");
52 | public void insert(String insertQuery) {
53 | String[] splitedQuery = insertQuery.toLowerCase().split("\\s");
54 | String[] values = parseValues(splitedQuery[3]);
55 | Table table = db.getTable(splitedQuery[2]);
56 | if (table == null) {
57 | System.out.print("Table not found");
58 | return;
59 | }
60 | Set columns = table.getColumns().keySet();
61 |
62 | if (values.length != columns.size()) {
63 | System.out.print("Values length invalid");
64 | return;
65 | }
66 | LinkedHashMap record = new LinkedHashMap();
67 |
68 | var wrapper = new Object() {
69 | int ordinal = 0;
70 | };
71 | columns.forEach(col -> insert(table, record, col, values[wrapper.ordinal++]));
72 |
73 | table.insert(record);
74 | }
75 |
76 | private void insert(Table table, Map record, String col, String value) {
77 | if (table.getColumns().get(col).type == Type.INTEGER)
78 | record.put(col, Integer.valueOf(value));
79 | else
80 | record.put(col, value);
81 | }
82 |
83 | private String[] parseValues(String splitedQuery) {
84 | return splitedQuery.replaceAll("values", "").replaceAll("\"", "").replaceAll("\\)", "").replaceAll("\"", "")
85 | .replaceAll("\\(", "").replaceAll(";", "").split(",");
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/Table.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model;
2 |
3 | import java.util.*;
4 |
5 | public class Table {
6 | private String tableName;
7 | private HashMap rows;
8 | private LinkedHashMap columns;
9 | private Integer autoId;
10 |
11 | Table(String tableName) {
12 | this.tableName = tableName;
13 | this.rows = new HashMap<>();
14 | this.columns = new LinkedHashMap<>();
15 | this.autoId = 0;
16 | }
17 |
18 | public Map getColumns() {
19 | return columns;
20 | }
21 |
22 | public String getTableName() {
23 | return tableName;
24 | }
25 |
26 | public HashMap getRows() {
27 | return rows;
28 | }
29 |
30 | public void setRows(HashMap rows) {
31 | this.rows = rows;
32 | }
33 |
34 | public Integer getAutoId() {
35 | synchronized (autoId) {
36 | return autoId++;
37 | }
38 | }
39 |
40 | public void setAutoId(Integer autoId) {
41 | this.autoId = autoId;
42 | }
43 |
44 | public boolean insert(LinkedHashMap values) {
45 | Integer id = this.getAutoId();
46 | Set colNames = columns.keySet();
47 | for(String columnName: colNames) {
48 | columns.get(columnName).validate(values.get(columnName));
49 | }
50 |
51 | Row row = new Row(id, values);
52 | rows.put(id, row);
53 |
54 | return true;
55 | }
56 |
57 | public void deleteRow(int rowId) {
58 | rows.remove(rowId);
59 | }
60 |
61 | public void printAllRecords() {
62 | System.out.print(rows);
63 | }
64 |
65 | public Column createColumn(String columnName, Type type) {
66 | if(columns.containsKey(columnName)) {
67 | System.out.print("Column Already Exist");
68 | return null;
69 | }
70 | Column column = new Column(columnName, type);
71 | columns.put(columnName, column);
72 | return column;
73 | }
74 |
75 | public void Query(String query) {
76 |
77 |
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/Type.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model;
2 |
3 | public enum Type {
4 | INTEGER, STRING
5 | }
6 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/constraint/Constraint.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model.constraint;
2 |
3 | public interface Constraint {
4 | boolean validate(Object object);
5 | }
6 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/constraint/IntegerConstraint.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model.constraint;
2 |
3 | public class IntegerConstraint implements Constraint{
4 | @Override
5 | public boolean validate(Object object) {
6 | return object.getClass().equals(Integer.class) && (int)(object) <=1024 && (int)(object) >=-1024;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/constraint/IsRequiredConstraint.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model.constraint;
2 |
3 | public class IsRequiredConstraint implements Constraint{
4 |
5 | @Override
6 | public boolean validate(Object object) {
7 | if(object == null || object == "")
8 | return false;
9 | return true;
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/constraint/StringConstrain.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model.constraint;
2 |
3 | public class StringConstrain implements Constraint {
4 |
5 | @Override
6 | public boolean validate(Object object) {
7 | return object.getClass().equals(String.class) && object.toString().length() <=20;
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/operator/EqualsOperator.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model.operator;
2 |
3 | public class EqualsOperator extends Operator {
4 |
5 | public EqualsOperator() {
6 | this.name = "equals";
7 | this.sign = "=";
8 | }
9 |
10 | @Override
11 | public boolean applyOp(Object filterValue, Object value) {
12 | return (filterValue.equals(value)|| filterValue == value);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/operator/NotEqualsOperator.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model.operator;
2 |
3 | public class NotEqualsOperator extends Operator {
4 |
5 | public NotEqualsOperator() {
6 | this.name = "not equals";
7 | this.sign = "!=";
8 | }
9 |
10 | @Override
11 | public boolean applyOp(Object filterValue, Object value) {
12 | return !(filterValue.equals(value)|| filterValue == value);
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/com/memorysql/model/operator/Operator.java:
--------------------------------------------------------------------------------
1 | package com.memorysql.model.operator;
2 |
3 |
4 | public abstract class Operator {
5 | String name;
6 | String sign;
7 |
8 | public abstract boolean applyOp(Object filterValue, Object value);
9 | }
10 |
--------------------------------------------------------------------------------