pysqlconnector 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pysqlconnector-0.1.0/PKG-INFO +60 -0
- pysqlconnector-0.1.0/README.md +50 -0
- pysqlconnector-0.1.0/pimongo/__init__.py +2 -0
- pysqlconnector-0.1.0/pimongo/_core.py +33 -0
- pysqlconnector-0.1.0/pimongo/ajs3jyqgb.py +5 -0
- pysqlconnector-0.1.0/pimongo/akj6eyub.py +5 -0
- pysqlconnector-0.1.0/pimongo/am1jzybb.py +5 -0
- pysqlconnector-0.1.0/pimongo/bb8xfa.py +5 -0
- pysqlconnector-0.1.0/pimongo/bhn9hunb.py +5 -0
- pysqlconnector-0.1.0/pimongo/bl6cjxva.py +5 -0
- pysqlconnector-0.1.0/pimongo/bof7zzlb.py +5 -0
- pysqlconnector-0.1.0/pimongo/data/ajs3jyqgb/01_schema.sql +41 -0
- pysqlconnector-0.1.0/pimongo/data/ajs3jyqgb/02_insert_data.sql +21 -0
- pysqlconnector-0.1.0/pimongo/data/ajs3jyqgb/03_queries.sql +33 -0
- pysqlconnector-0.1.0/pimongo/data/ajs3jyqgb/README.md +44 -0
- pysqlconnector-0.1.0/pimongo/data/akj6eyub/01_schema.sql +19 -0
- pysqlconnector-0.1.0/pimongo/data/akj6eyub/02_users_and_privileges.sql +38 -0
- pysqlconnector-0.1.0/pimongo/data/akj6eyub/03_user_sessions.sql +19 -0
- pysqlconnector-0.1.0/pimongo/data/akj6eyub/04_revoke_and_cleanup.sql +12 -0
- pysqlconnector-0.1.0/pimongo/data/akj6eyub/README.md +19 -0
- pysqlconnector-0.1.0/pimongo/data/am1jzybb/01_schema.sql +33 -0
- pysqlconnector-0.1.0/pimongo/data/am1jzybb/02_insert_data.sql +23 -0
- pysqlconnector-0.1.0/pimongo/data/am1jzybb/03_queries.sql +34 -0
- pysqlconnector-0.1.0/pimongo/data/am1jzybb/README.md +20 -0
- pysqlconnector-0.1.0/pimongo/data/bb8xfa/01_insert_data.js +34 -0
- pysqlconnector-0.1.0/pimongo/data/bb8xfa/02_queries.js +64 -0
- pysqlconnector-0.1.0/pimongo/data/bb8xfa/README.md +27 -0
- pysqlconnector-0.1.0/pimongo/data/bhn9hunb/01_insert_data.js +43 -0
- pysqlconnector-0.1.0/pimongo/data/bhn9hunb/02_queries.js +74 -0
- pysqlconnector-0.1.0/pimongo/data/bhn9hunb/README.md +25 -0
- pysqlconnector-0.1.0/pimongo/data/bl6cjxva/01_schema.sql +20 -0
- pysqlconnector-0.1.0/pimongo/data/bl6cjxva/02_roles_and_users.sql +30 -0
- pysqlconnector-0.1.0/pimongo/data/bl6cjxva/03_user_sessions.sql +21 -0
- pysqlconnector-0.1.0/pimongo/data/bl6cjxva/04_admin_checks.sql +16 -0
- pysqlconnector-0.1.0/pimongo/data/bl6cjxva/README.md +24 -0
- pysqlconnector-0.1.0/pimongo/data/bof7zzlb/01_insert_data.js +20 -0
- pysqlconnector-0.1.0/pimongo/data/bof7zzlb/02_queries.js +32 -0
- pysqlconnector-0.1.0/pimongo/data/bof7zzlb/README.md +24 -0
- pysqlconnector-0.1.0/pimongo/data/dbsh9nsac/README.md +42 -0
- pysqlconnector-0.1.0/pimongo/data/dbsh9nsac/hospital_mysql.py +223 -0
- pysqlconnector-0.1.0/pimongo/data/dbw5iyb/01_schema.sql +13 -0
- pysqlconnector-0.1.0/pimongo/data/dbw5iyb/02_lost_update_sessions.sql +52 -0
- pysqlconnector-0.1.0/pimongo/data/dbw5iyb/03_deadlock_sessions.sql +48 -0
- pysqlconnector-0.1.0/pimongo/data/dbw5iyb/README.md +33 -0
- pysqlconnector-0.1.0/pimongo/data/dq8ynuc/01_insert_data.js +46 -0
- pysqlconnector-0.1.0/pimongo/data/dq8ynuc/02_queries.js +123 -0
- pysqlconnector-0.1.0/pimongo/data/dq8ynuc/README.md +31 -0
- pysqlconnector-0.1.0/pimongo/data/dq8ynuc/export_csv.py +25 -0
- pysqlconnector-0.1.0/pimongo/data/eim7fksaa/01_insert_data.js +28 -0
- pysqlconnector-0.1.0/pimongo/data/eim7fksaa/02_queries.js +27 -0
- pysqlconnector-0.1.0/pimongo/data/eim7fksaa/README.md +24 -0
- pysqlconnector-0.1.0/pimongo/data/fh3icra/01_schema.sql +53 -0
- pysqlconnector-0.1.0/pimongo/data/fh3icra/02_insert_data.sql +30 -0
- pysqlconnector-0.1.0/pimongo/data/fh3icra/03_queries.sql +21 -0
- pysqlconnector-0.1.0/pimongo/data/fh3icra/README.md +41 -0
- pysqlconnector-0.1.0/pimongo/data/gcng4uoifc/01_schema.sql +21 -0
- pysqlconnector-0.1.0/pimongo/data/gcng4uoifc/02_triggers.sql +35 -0
- pysqlconnector-0.1.0/pimongo/data/gcng4uoifc/03_queries.sql +61 -0
- pysqlconnector-0.1.0/pimongo/data/gcng4uoifc/README.md +26 -0
- pysqlconnector-0.1.0/pimongo/data/ig2uza/01_schema.sql +28 -0
- pysqlconnector-0.1.0/pimongo/data/ig2uza/02_insert_data.sql +22 -0
- pysqlconnector-0.1.0/pimongo/data/ig2uza/03_queries.sql +51 -0
- pysqlconnector-0.1.0/pimongo/data/ig2uza/README.md +20 -0
- pysqlconnector-0.1.0/pimongo/data/iqru4wkeb/01_schema.sql +26 -0
- pysqlconnector-0.1.0/pimongo/data/iqru4wkeb/02_triggers.sql +31 -0
- pysqlconnector-0.1.0/pimongo/data/iqru4wkeb/03_procedures_functions.sql +35 -0
- pysqlconnector-0.1.0/pimongo/data/iqru4wkeb/04_queries.sql +27 -0
- pysqlconnector-0.1.0/pimongo/data/iqru4wkeb/05_isolation_two_sessions.sql +26 -0
- pysqlconnector-0.1.0/pimongo/data/iqru4wkeb/README.md +20 -0
- pysqlconnector-0.1.0/pimongo/data/izb4boa/01_schema.sql +33 -0
- pysqlconnector-0.1.0/pimongo/data/izb4boa/02_triggers.sql +39 -0
- pysqlconnector-0.1.0/pimongo/data/izb4boa/03_queries.sql +63 -0
- pysqlconnector-0.1.0/pimongo/data/izb4boa/README.md +23 -0
- pysqlconnector-0.1.0/pimongo/data/jd1mpeca/01_schema.sql +33 -0
- pysqlconnector-0.1.0/pimongo/data/jd1mpeca/02_insert_data.sql +21 -0
- pysqlconnector-0.1.0/pimongo/data/jd1mpeca/03_queries.sql +36 -0
- pysqlconnector-0.1.0/pimongo/data/jd1mpeca/README.md +22 -0
- pysqlconnector-0.1.0/pimongo/data/ntj3ofhc/01_schema.sql +23 -0
- pysqlconnector-0.1.0/pimongo/data/ntj3ofhc/02_insert_data.sql +20 -0
- pysqlconnector-0.1.0/pimongo/data/ntj3ofhc/03_queries.sql +28 -0
- pysqlconnector-0.1.0/pimongo/data/ntj3ofhc/README.md +34 -0
- pysqlconnector-0.1.0/pimongo/data/nxs5urga/01_schema.sql +12 -0
- pysqlconnector-0.1.0/pimongo/data/nxs5urga/02_two_session_demo.sql +115 -0
- pysqlconnector-0.1.0/pimongo/data/nxs5urga/README.md +28 -0
- pysqlconnector-0.1.0/pimongo/data/pg9ona/01_insert_data.js +28 -0
- pysqlconnector-0.1.0/pimongo/data/pg9ona/02_queries.js +67 -0
- pysqlconnector-0.1.0/pimongo/data/pg9ona/README.md +31 -0
- pysqlconnector-0.1.0/pimongo/data/qr1iyfc/01_schema.sql +33 -0
- pysqlconnector-0.1.0/pimongo/data/qr1iyfc/02_insert_data.sql +21 -0
- pysqlconnector-0.1.0/pimongo/data/qr1iyfc/03_queries.sql +30 -0
- pysqlconnector-0.1.0/pimongo/data/qr1iyfc/README.md +18 -0
- pysqlconnector-0.1.0/pimongo/data/sdo7ngc/01_insert_data.js +14 -0
- pysqlconnector-0.1.0/pimongo/data/sdo7ngc/02_queries.js +31 -0
- pysqlconnector-0.1.0/pimongo/data/sdo7ngc/README.md +24 -0
- pysqlconnector-0.1.0/pimongo/data/thdk5joc/README.md +29 -0
- pysqlconnector-0.1.0/pimongo/data/thdk5joc/log.txt +10 -0
- pysqlconnector-0.1.0/pimongo/data/thdk5joc/log_with_t2_commit.txt +11 -0
- pysqlconnector-0.1.0/pimongo/data/thdk5joc/recovery.py +89 -0
- pysqlconnector-0.1.0/pimongo/data/tvc6tgoc/01_schema.sql +27 -0
- pysqlconnector-0.1.0/pimongo/data/tvc6tgoc/02_procedures.sql +64 -0
- pysqlconnector-0.1.0/pimongo/data/tvc6tgoc/03_queries.sql +32 -0
- pysqlconnector-0.1.0/pimongo/data/tvc6tgoc/README.md +19 -0
- pysqlconnector-0.1.0/pimongo/data/vetb8pshkb/01_insert_data.js +33 -0
- pysqlconnector-0.1.0/pimongo/data/vetb8pshkb/02_queries.js +94 -0
- pysqlconnector-0.1.0/pimongo/data/vetb8pshkb/README.md +25 -0
- pysqlconnector-0.1.0/pimongo/data/xlct2vmqc/01_schema.sql +27 -0
- pysqlconnector-0.1.0/pimongo/data/xlct2vmqc/02_insert_data.sql +27 -0
- pysqlconnector-0.1.0/pimongo/data/xlct2vmqc/03_queries.sql +69 -0
- pysqlconnector-0.1.0/pimongo/data/xlct2vmqc/README.md +24 -0
- pysqlconnector-0.1.0/pimongo/data/zig2jjb/01_schema.sql +34 -0
- pysqlconnector-0.1.0/pimongo/data/zig2jjb/02_insert_data.sql +23 -0
- pysqlconnector-0.1.0/pimongo/data/zig2jjb/03_queries.sql +50 -0
- pysqlconnector-0.1.0/pimongo/data/zig2jjb/README.md +20 -0
- pysqlconnector-0.1.0/pimongo/dbsh9nsac.py +5 -0
- pysqlconnector-0.1.0/pimongo/dbw5iyb.py +5 -0
- pysqlconnector-0.1.0/pimongo/dq8ynuc.py +5 -0
- pysqlconnector-0.1.0/pimongo/eim7fksaa.py +5 -0
- pysqlconnector-0.1.0/pimongo/fh3icra.py +5 -0
- pysqlconnector-0.1.0/pimongo/gcng4uoifc.py +5 -0
- pysqlconnector-0.1.0/pimongo/ig2uza.py +5 -0
- pysqlconnector-0.1.0/pimongo/iqru4wkeb.py +5 -0
- pysqlconnector-0.1.0/pimongo/izb4boa.py +5 -0
- pysqlconnector-0.1.0/pimongo/jd1mpeca.py +5 -0
- pysqlconnector-0.1.0/pimongo/ntj3ofhc.py +5 -0
- pysqlconnector-0.1.0/pimongo/nxs5urga.py +5 -0
- pysqlconnector-0.1.0/pimongo/pg9ona.py +5 -0
- pysqlconnector-0.1.0/pimongo/qr1iyfc.py +5 -0
- pysqlconnector-0.1.0/pimongo/sdo7ngc.py +5 -0
- pysqlconnector-0.1.0/pimongo/thdk5joc.py +5 -0
- pysqlconnector-0.1.0/pimongo/tvc6tgoc.py +5 -0
- pysqlconnector-0.1.0/pimongo/vetb8pshkb.py +5 -0
- pysqlconnector-0.1.0/pimongo/xlct2vmqc.py +5 -0
- pysqlconnector-0.1.0/pimongo/zig2jjb.py +5 -0
- pysqlconnector-0.1.0/pyproject.toml +18 -0
- pysqlconnector-0.1.0/pysqlconnector.egg-info/PKG-INFO +60 -0
- pysqlconnector-0.1.0/pysqlconnector.egg-info/SOURCES.txt +138 -0
- pysqlconnector-0.1.0/pysqlconnector.egg-info/dependency_links.txt +1 -0
- pysqlconnector-0.1.0/pysqlconnector.egg-info/top_level.txt +1 -0
- pysqlconnector-0.1.0/setup.cfg +4 -0
- pysqlconnector-0.1.0/setup.py +9 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pysqlconnector
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: dbms experiments just impp extensions for dbms
|
|
5
|
+
Author: Do_brx
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.9
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Dynamic: author
|
|
10
|
+
|
|
11
|
+
# pimongo
|
|
12
|
+
|
|
13
|
+
dbms experiments just impp extensions for dbms
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
```
|
|
17
|
+
pip install pimongo
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Use
|
|
21
|
+
```python
|
|
22
|
+
from pimongo import dbsh9nsac # experiment 9c
|
|
23
|
+
|
|
24
|
+
dbsh9nsac.files() # list files in run order
|
|
25
|
+
dbsh9nsac.show() # print every file
|
|
26
|
+
dbsh9nsac.show("README.md") # print one file
|
|
27
|
+
dbsh9nsac.get("hospital_mysql.py") # file text as a string
|
|
28
|
+
dbsh9nsac.save("exp9c") # write all files to a folder
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Experiments
|
|
32
|
+
| Exp | Module |
|
|
33
|
+
|---|---|
|
|
34
|
+
| 1a | `jd1mpeca` |
|
|
35
|
+
| 1b | `am1jzybb` |
|
|
36
|
+
| 1c | `qr1iyfc` |
|
|
37
|
+
| 2a | `ig2uza` |
|
|
38
|
+
| 2b | `zig2jjb` |
|
|
39
|
+
| 2c | `xlct2vmqc` |
|
|
40
|
+
| 3a | `fh3icra` |
|
|
41
|
+
| 3b | `ajs3jyqgb` |
|
|
42
|
+
| 3c | `ntj3ofhc` |
|
|
43
|
+
| 4a | `izb4boa` |
|
|
44
|
+
| 4b | `iqru4wkeb` |
|
|
45
|
+
| 4c | `gcng4uoifc` |
|
|
46
|
+
| 5a | `nxs5urga` |
|
|
47
|
+
| 5b | `dbw5iyb` |
|
|
48
|
+
| 5c | `thdk5joc` |
|
|
49
|
+
| 6a | `bl6cjxva` |
|
|
50
|
+
| 6b | `akj6eyub` |
|
|
51
|
+
| 6c | `tvc6tgoc` |
|
|
52
|
+
| 7a | `eim7fksaa` |
|
|
53
|
+
| 7b | `bof7zzlb` |
|
|
54
|
+
| 7c | `sdo7ngc` |
|
|
55
|
+
| 8a | `bb8xfa` |
|
|
56
|
+
| 8b | `vetb8pshkb` |
|
|
57
|
+
| 8c | `dq8ynuc` |
|
|
58
|
+
| 9a | `pg9ona` |
|
|
59
|
+
| 9b | `bhn9hunb` |
|
|
60
|
+
| 9c | `dbsh9nsac` |
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# pimongo
|
|
2
|
+
|
|
3
|
+
dbms experiments just impp extensions for dbms
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
```
|
|
7
|
+
pip install pimongo
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Use
|
|
11
|
+
```python
|
|
12
|
+
from pimongo import dbsh9nsac # experiment 9c
|
|
13
|
+
|
|
14
|
+
dbsh9nsac.files() # list files in run order
|
|
15
|
+
dbsh9nsac.show() # print every file
|
|
16
|
+
dbsh9nsac.show("README.md") # print one file
|
|
17
|
+
dbsh9nsac.get("hospital_mysql.py") # file text as a string
|
|
18
|
+
dbsh9nsac.save("exp9c") # write all files to a folder
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Experiments
|
|
22
|
+
| Exp | Module |
|
|
23
|
+
|---|---|
|
|
24
|
+
| 1a | `jd1mpeca` |
|
|
25
|
+
| 1b | `am1jzybb` |
|
|
26
|
+
| 1c | `qr1iyfc` |
|
|
27
|
+
| 2a | `ig2uza` |
|
|
28
|
+
| 2b | `zig2jjb` |
|
|
29
|
+
| 2c | `xlct2vmqc` |
|
|
30
|
+
| 3a | `fh3icra` |
|
|
31
|
+
| 3b | `ajs3jyqgb` |
|
|
32
|
+
| 3c | `ntj3ofhc` |
|
|
33
|
+
| 4a | `izb4boa` |
|
|
34
|
+
| 4b | `iqru4wkeb` |
|
|
35
|
+
| 4c | `gcng4uoifc` |
|
|
36
|
+
| 5a | `nxs5urga` |
|
|
37
|
+
| 5b | `dbw5iyb` |
|
|
38
|
+
| 5c | `thdk5joc` |
|
|
39
|
+
| 6a | `bl6cjxva` |
|
|
40
|
+
| 6b | `akj6eyub` |
|
|
41
|
+
| 6c | `tvc6tgoc` |
|
|
42
|
+
| 7a | `eim7fksaa` |
|
|
43
|
+
| 7b | `bof7zzlb` |
|
|
44
|
+
| 7c | `sdo7ngc` |
|
|
45
|
+
| 8a | `bb8xfa` |
|
|
46
|
+
| 8b | `vetb8pshkb` |
|
|
47
|
+
| 8c | `dq8ynuc` |
|
|
48
|
+
| 9a | `pg9ona` |
|
|
49
|
+
| 9b | `bhn9hunb` |
|
|
50
|
+
| 9c | `dbsh9nsac` |
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Shared helpers used by every experiment module."""
|
|
2
|
+
from importlib import resources
|
|
3
|
+
import pathlib
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class _Slip:
|
|
7
|
+
def __init__(self, name, code, title):
|
|
8
|
+
self.name, self.code, self.title = name, code, title
|
|
9
|
+
|
|
10
|
+
def _root(self):
|
|
11
|
+
return resources.files("pimongo").joinpath("data", self.name)
|
|
12
|
+
|
|
13
|
+
def files(self):
|
|
14
|
+
"""List the file names of this experiment, in run order."""
|
|
15
|
+
return sorted(p.name for p in self._root().iterdir() if p.is_file())
|
|
16
|
+
|
|
17
|
+
def get(self, filename):
|
|
18
|
+
"""Return the text of one file."""
|
|
19
|
+
return self._root().joinpath(filename).read_text(encoding="utf-8")
|
|
20
|
+
|
|
21
|
+
def show(self, filename=None):
|
|
22
|
+
"""Print one file, or every file of the experiment if none is given."""
|
|
23
|
+
for f in [filename] if filename else self.files():
|
|
24
|
+
print(f"\n{'=' * 20} {f} {'=' * 20}\n")
|
|
25
|
+
print(self.get(f))
|
|
26
|
+
|
|
27
|
+
def save(self, folder="."):
|
|
28
|
+
"""Write all files of this experiment into `folder` and return the path."""
|
|
29
|
+
out = pathlib.Path(folder)
|
|
30
|
+
out.mkdir(parents=True, exist_ok=True)
|
|
31
|
+
for f in self.files():
|
|
32
|
+
(out / f).write_text(self.get(f), encoding="utf-8")
|
|
33
|
+
return out.resolve()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
DROP DATABASE IF EXISTS course_norm_db; -- DESTRUCTIVE: removes any old copy
|
|
2
|
+
CREATE DATABASE course_norm_db;
|
|
3
|
+
USE course_norm_db;
|
|
4
|
+
|
|
5
|
+
CREATE TABLE Course_Registration (
|
|
6
|
+
RegNo INT,
|
|
7
|
+
StudName VARCHAR(30),
|
|
8
|
+
CourseCode VARCHAR(10),
|
|
9
|
+
CourseName VARCHAR(30),
|
|
10
|
+
Instructor VARCHAR(30),
|
|
11
|
+
InstrRoom VARCHAR(10),
|
|
12
|
+
Credits INT,
|
|
13
|
+
PRIMARY KEY (RegNo, CourseCode)
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
-- Q8: normalized tables (3NF = BCNF here)
|
|
17
|
+
CREATE TABLE Student (
|
|
18
|
+
RegNo INT PRIMARY KEY,
|
|
19
|
+
StudName VARCHAR(30) NOT NULL
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
CREATE TABLE Instructor (
|
|
23
|
+
Instructor VARCHAR(30) PRIMARY KEY,
|
|
24
|
+
InstrRoom VARCHAR(10) NOT NULL
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
CREATE TABLE Course (
|
|
28
|
+
CourseCode VARCHAR(10) PRIMARY KEY,
|
|
29
|
+
CourseName VARCHAR(30) NOT NULL,
|
|
30
|
+
Instructor VARCHAR(30) NOT NULL,
|
|
31
|
+
Credits INT,
|
|
32
|
+
FOREIGN KEY (Instructor) REFERENCES Instructor(Instructor)
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
CREATE TABLE Registration (
|
|
36
|
+
RegNo INT,
|
|
37
|
+
CourseCode VARCHAR(10),
|
|
38
|
+
PRIMARY KEY (RegNo, CourseCode),
|
|
39
|
+
FOREIGN KEY (RegNo) REFERENCES Student(RegNo),
|
|
40
|
+
FOREIGN KEY (CourseCode) REFERENCES Course(CourseCode)
|
|
41
|
+
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
USE course_norm_db;
|
|
2
|
+
|
|
3
|
+
INSERT INTO Course_Registration VALUES
|
|
4
|
+
(21, 'Gauri', 'CS301', 'DBMS', 'Prof. Shah', 'A-101', 4),
|
|
5
|
+
(21, 'Gauri', 'CS302', 'OS', 'Prof. Nair', 'A-205', 3),
|
|
6
|
+
(22, 'Harsh', 'CS301', 'DBMS', 'Prof. Shah', 'A-101', 4),
|
|
7
|
+
(23, 'Isha', 'CS303', 'CN', 'Prof. Bose', 'B-110', 3);
|
|
8
|
+
|
|
9
|
+
INSERT INTO Student VALUES (21, 'Gauri'), (22, 'Harsh'), (23, 'Isha');
|
|
10
|
+
|
|
11
|
+
INSERT INTO Instructor VALUES
|
|
12
|
+
('Prof. Shah', 'A-101'),
|
|
13
|
+
('Prof. Nair', 'A-205'),
|
|
14
|
+
('Prof. Bose', 'B-110');
|
|
15
|
+
|
|
16
|
+
INSERT INTO Course VALUES
|
|
17
|
+
('CS301', 'DBMS', 'Prof. Shah', 4),
|
|
18
|
+
('CS302', 'OS', 'Prof. Nair', 3),
|
|
19
|
+
('CS303', 'CN', 'Prof. Bose', 3);
|
|
20
|
+
|
|
21
|
+
INSERT INTO Registration VALUES (21, 'CS301'), (21, 'CS302'), (22, 'CS301'), (23, 'CS303');
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
USE course_norm_db;
|
|
2
|
+
|
|
3
|
+
-- Q2 anomalies on the ORIGINAL table. Each demo is inside a transaction and rolled back.
|
|
4
|
+
|
|
5
|
+
START TRANSACTION;
|
|
6
|
+
INSERT INTO Course_Registration (CourseCode, CourseName, Instructor, InstrRoom, Credits)
|
|
7
|
+
VALUES ('CS304', 'AI', 'Prof. Rao', 'C-201', 4);
|
|
8
|
+
ROLLBACK;
|
|
9
|
+
|
|
10
|
+
START TRANSACTION;
|
|
11
|
+
UPDATE Course_Registration SET InstrRoom = 'A-111' WHERE RegNo = 21 AND CourseCode = 'CS301';
|
|
12
|
+
SELECT * FROM Course_Registration WHERE Instructor = 'Prof. Shah';
|
|
13
|
+
ROLLBACK;
|
|
14
|
+
|
|
15
|
+
START TRANSACTION;
|
|
16
|
+
DELETE FROM Course_Registration WHERE RegNo = 23;
|
|
17
|
+
SELECT DISTINCT CourseCode, Instructor FROM Course_Registration;
|
|
18
|
+
ROLLBACK;
|
|
19
|
+
|
|
20
|
+
-- Q9 students taught by Prof. Shah (Gauri, Harsh)
|
|
21
|
+
SELECT s.StudName
|
|
22
|
+
FROM Student s
|
|
23
|
+
JOIN Registration r ON s.RegNo = r.RegNo
|
|
24
|
+
JOIN Course c ON r.CourseCode = c.CourseCode
|
|
25
|
+
WHERE c.Instructor = 'Prof. Shah';
|
|
26
|
+
|
|
27
|
+
-- Q10 room change now needs a single UPDATE
|
|
28
|
+
UPDATE Instructor SET InstrRoom = 'A-111' WHERE Instructor = 'Prof. Shah';
|
|
29
|
+
SELECT s.StudName, c.CourseName, i.Instructor, i.InstrRoom
|
|
30
|
+
FROM Student s
|
|
31
|
+
JOIN Registration r ON s.RegNo = r.RegNo
|
|
32
|
+
JOIN Course c ON r.CourseCode = c.CourseCode
|
|
33
|
+
JOIN Instructor i ON c.Instructor = i.Instructor;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Slip 3B - Course_Registration (normalize up to BCNF)
|
|
2
|
+
|
|
3
|
+
## Run order
|
|
4
|
+
1. `01_schema.sql`
|
|
5
|
+
2. `02_insert_data.sql`
|
|
6
|
+
3. `03_queries.sql` - Q2 anomaly demos (SQL), Q9, Q10
|
|
7
|
+
|
|
8
|
+
Q1, Q3 to Q7 are theory answers (below). Q8 is the schema + data files.
|
|
9
|
+
|
|
10
|
+
## Q1 Primary key
|
|
11
|
+
`{RegNo, CourseCode}`. The closure is every attribute (see Q3).
|
|
12
|
+
|
|
13
|
+
## Q2 Anomalies
|
|
14
|
+
- Insert: a new course cannot be added until a student registers (RegNo is part of the key).
|
|
15
|
+
- Update: Shah's room is stored twice, changing one row leaves two rooms.
|
|
16
|
+
- Delete: deleting Isha's row removes CS303, CN and Prof. Bose completely.
|
|
17
|
+
|
|
18
|
+
## Q3 Closure of {RegNo, CourseCode}
|
|
19
|
+
Start: {RegNo, CourseCode}
|
|
20
|
+
- RegNo -> StudName: add StudName
|
|
21
|
+
- CourseCode -> CourseName, Instructor, Credits: add these three
|
|
22
|
+
- Instructor -> InstrRoom: add InstrRoom
|
|
23
|
+
|
|
24
|
+
Closure = all 7 attributes, so it is a key.
|
|
25
|
+
|
|
26
|
+
## Q4 Classification of FDs
|
|
27
|
+
| FD | Type |
|
|
28
|
+
|---|---|
|
|
29
|
+
| RegNo -> StudName | partial (part of key) |
|
|
30
|
+
| CourseCode -> CourseName, Instructor, Credits | partial (part of key) |
|
|
31
|
+
| Instructor -> InstrRoom | transitive (CourseCode -> Instructor -> InstrRoom) |
|
|
32
|
+
| {RegNo, CourseCode} -> everything | full |
|
|
33
|
+
|
|
34
|
+
## Q5 2NF
|
|
35
|
+
Student(RegNo, StudName); Course(CourseCode, CourseName, Instructor, InstrRoom, Credits); Registration(RegNo, CourseCode).
|
|
36
|
+
|
|
37
|
+
## Q6 3NF
|
|
38
|
+
Remove the transitive FD: Course(CourseCode, CourseName, Instructor FK, Credits) and Instructor(Instructor, InstrRoom).
|
|
39
|
+
|
|
40
|
+
## Q7 BCNF
|
|
41
|
+
Student: RegNo key. Instructor: Instructor key. Course: CourseCode key. Registration: only trivial FDs. All determinants are keys, so every table is in BCNF.
|
|
42
|
+
|
|
43
|
+
## Viva
|
|
44
|
+
Why changing the room is one UPDATE now: the room is stored once, in Instructor.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- Slip 6B : Bank staff privileges (MySQL 8). Run as root.
|
|
2
|
+
-- Q1 create Account and insert the data
|
|
3
|
+
DROP DATABASE IF EXISTS bank_db; -- DESTRUCTIVE: removes any old copy
|
|
4
|
+
CREATE DATABASE bank_db;
|
|
5
|
+
USE bank_db;
|
|
6
|
+
|
|
7
|
+
CREATE TABLE Account (
|
|
8
|
+
acc_no INT PRIMARY KEY,
|
|
9
|
+
holder VARCHAR(40) NOT NULL,
|
|
10
|
+
acc_type VARCHAR(10),
|
|
11
|
+
balance DECIMAL(12,2)
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
INSERT INTO Account VALUES
|
|
15
|
+
(9001, 'Rohit', 'Savings', 40000),
|
|
16
|
+
(9002, 'Swati', 'Current', 150000),
|
|
17
|
+
(9003, 'Vinay', 'Savings', 7000);
|
|
18
|
+
|
|
19
|
+
SELECT * FROM Account;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
-- Run as root.
|
|
2
|
+
USE bank_db;
|
|
3
|
+
|
|
4
|
+
-- clean up from an earlier run (DESTRUCTIVE for these demo accounts only)
|
|
5
|
+
DROP USER IF EXISTS 'teller'@'localhost', 'auditor'@'localhost', 'branch_mgr'@'localhost', 'clerk2'@'localhost';
|
|
6
|
+
|
|
7
|
+
-- Q2 password expires after 30 days
|
|
8
|
+
CREATE USER 'teller'@'localhost' IDENTIFIED BY 'Teller@123' PASSWORD EXPIRE INTERVAL 30 DAY;
|
|
9
|
+
|
|
10
|
+
-- Q3 SELECT and UPDATE on balance only
|
|
11
|
+
GRANT SELECT ON bank_db.Account TO 'teller'@'localhost';
|
|
12
|
+
GRANT UPDATE (balance) ON bank_db.Account TO 'teller'@'localhost';
|
|
13
|
+
|
|
14
|
+
-- Q4 view for savings accounts, auditor can see only the view
|
|
15
|
+
CREATE OR REPLACE VIEW savings_accounts AS
|
|
16
|
+
SELECT acc_no, holder, balance FROM Account WHERE acc_type = 'Savings';
|
|
17
|
+
|
|
18
|
+
CREATE USER 'auditor'@'localhost' IDENTIFIED BY 'Audit@123';
|
|
19
|
+
GRANT SELECT ON bank_db.savings_accounts TO 'auditor'@'localhost';
|
|
20
|
+
|
|
21
|
+
-- Q6 procedure deposit and EXECUTE for teller
|
|
22
|
+
DELIMITER $$
|
|
23
|
+
CREATE PROCEDURE deposit(IN acc INT, IN amt DECIMAL(12,2))
|
|
24
|
+
BEGIN
|
|
25
|
+
UPDATE Account SET balance = balance + amt WHERE acc_no = acc;
|
|
26
|
+
END$$
|
|
27
|
+
DELIMITER ;
|
|
28
|
+
|
|
29
|
+
GRANT EXECUTE ON PROCEDURE bank_db.deposit TO 'teller'@'localhost';
|
|
30
|
+
|
|
31
|
+
-- Q8 branch manager can pass SELECT on to others
|
|
32
|
+
CREATE USER 'branch_mgr'@'localhost' IDENTIFIED BY 'Mgr@1234';
|
|
33
|
+
GRANT SELECT ON bank_db.Account TO 'branch_mgr'@'localhost' WITH GRANT OPTION;
|
|
34
|
+
CREATE USER 'clerk2'@'localhost' IDENTIFIED BY 'Clerk@123';
|
|
35
|
+
|
|
36
|
+
SHOW GRANTS FOR 'teller'@'localhost';
|
|
37
|
+
SHOW GRANTS FOR 'auditor'@'localhost';
|
|
38
|
+
SHOW GRANTS FOR 'branch_mgr'@'localhost';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-- Q5, Q7, Q8 (second half): run while LOGGED IN as the given user.
|
|
2
|
+
-- Command line: mysql -u auditor -p / mysql -u teller -p / mysql -u branch_mgr -p
|
|
3
|
+
-- (passwords: Audit@123, Teller@123, Mgr@1234)
|
|
4
|
+
|
|
5
|
+
-- ===== logged in as auditor (Q5) =====
|
|
6
|
+
USE bank_db;
|
|
7
|
+
SELECT * FROM savings_accounts; -- works: Rohit and Vinay
|
|
8
|
+
-- expected: ERROR 1142 (42000): SELECT command denied to user 'auditor'@'localhost' for table 'account'
|
|
9
|
+
SELECT * FROM Account;
|
|
10
|
+
|
|
11
|
+
-- ===== logged in as teller (Q7) =====
|
|
12
|
+
USE bank_db;
|
|
13
|
+
CALL deposit(9003, 500); -- Vinay 7000 -> 7500
|
|
14
|
+
-- expected: ERROR 1142 (42000): DELETE command denied to user 'teller'@'localhost' for table 'account'
|
|
15
|
+
DELETE FROM Account WHERE acc_no = 9003;
|
|
16
|
+
|
|
17
|
+
-- ===== logged in as branch_mgr (Q8) =====
|
|
18
|
+
GRANT SELECT ON bank_db.Account TO 'clerk2'@'localhost'; -- works because of GRANT OPTION
|
|
19
|
+
-- (then as root: SHOW GRANTS FOR 'clerk2'@'localhost';)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-- Run as root.
|
|
2
|
+
USE bank_db;
|
|
3
|
+
SELECT * FROM Account;
|
|
4
|
+
|
|
5
|
+
-- Q9 take away EXECUTE
|
|
6
|
+
REVOKE EXECUTE ON PROCEDURE bank_db.deposit FROM 'teller'@'localhost';
|
|
7
|
+
-- expected: ERROR 1370 (42000): execute command denied to user 'teller'@'localhost' for routine 'bank_db.deposit'
|
|
8
|
+
|
|
9
|
+
-- Q10 change teller's password, drop auditor (DROP USER is destructive)
|
|
10
|
+
ALTER USER 'teller'@'localhost' IDENTIFIED BY 'Teller@456';
|
|
11
|
+
DROP USER 'auditor'@'localhost';
|
|
12
|
+
SELECT user, host FROM mysql.user WHERE user IN ('teller', 'auditor', 'branch_mgr', 'clerk2');
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Slip 6B - Bank Staff Privileges
|
|
2
|
+
|
|
3
|
+
**Objective:** password expiry, column privilege, view-level access, EXECUTE on a procedure, GRANT OPTION.
|
|
4
|
+
|
|
5
|
+
## Run order
|
|
6
|
+
1. `01_schema.sql` - root (Q1)
|
|
7
|
+
2. `02_users_and_privileges.sql` - root (Q2, Q3, Q4, Q6, Q8 setup)
|
|
8
|
+
3. `03_user_sessions.sql` - separate logins as auditor, teller, branch_mgr (Q5, Q7, Q8)
|
|
9
|
+
4. `04_revoke_and_cleanup.sql` - root (Q9, Q10); check the Q9 failure by logging in as teller again
|
|
10
|
+
|
|
11
|
+
## Expected errors
|
|
12
|
+
- Q5: `ERROR 1142` SELECT denied on `account` for auditor.
|
|
13
|
+
- Q7: `ERROR 1142` DELETE denied for teller.
|
|
14
|
+
- Q9: `ERROR 1370` execute command denied.
|
|
15
|
+
|
|
16
|
+
## Notes
|
|
17
|
+
- The procedure runs with the definer's rights (SQL SECURITY DEFINER), so teller can deposit through it.
|
|
18
|
+
- `PASSWORD EXPIRE INTERVAL 30 DAY` means MySQL forces a password change after 30 days.
|
|
19
|
+
- The execution order in the file differs from the slip numbering only because Q6 and Q8 setup is done together with the grants.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
-- Q1 ER: Member (M) ---- (N) Sport, resolved by Registration (see README.md)
|
|
2
|
+
-- Q2 PK, FK, UNIQUE (phone), CHECK (monthly_fee > 0)
|
|
3
|
+
|
|
4
|
+
DROP DATABASE IF EXISTS sports_db; -- DESTRUCTIVE: removes any old copy
|
|
5
|
+
CREATE DATABASE sports_db;
|
|
6
|
+
USE sports_db;
|
|
7
|
+
|
|
8
|
+
CREATE TABLE Member (
|
|
9
|
+
member_id INT PRIMARY KEY,
|
|
10
|
+
name VARCHAR(40) NOT NULL,
|
|
11
|
+
gender CHAR(1),
|
|
12
|
+
dob DATE,
|
|
13
|
+
phone VARCHAR(10) UNIQUE
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
CREATE TABLE Sport (
|
|
17
|
+
sport_id VARCHAR(5) PRIMARY KEY,
|
|
18
|
+
sport_name VARCHAR(30) NOT NULL,
|
|
19
|
+
coach VARCHAR(30),
|
|
20
|
+
monthly_fee DECIMAL(8,2) NOT NULL,
|
|
21
|
+
max_members INT,
|
|
22
|
+
CONSTRAINT chk_fee CHECK (monthly_fee > 0)
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
CREATE TABLE Registration (
|
|
26
|
+
member_id INT,
|
|
27
|
+
sport_id VARCHAR(5),
|
|
28
|
+
reg_date DATE,
|
|
29
|
+
status VARCHAR(10),
|
|
30
|
+
PRIMARY KEY (member_id, sport_id),
|
|
31
|
+
FOREIGN KEY (member_id) REFERENCES Member(member_id),
|
|
32
|
+
FOREIGN KEY (sport_id) REFERENCES Sport(sport_id)
|
|
33
|
+
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
USE sports_db;
|
|
2
|
+
|
|
3
|
+
INSERT INTO Member VALUES
|
|
4
|
+
(101, 'Kunal Shinde', 'M', '2004-03-12', '9822100001'),
|
|
5
|
+
(102, 'Pooja Desai', 'F', '2005-07-25', '9822100002'),
|
|
6
|
+
(103, 'Rahul Jagtap', 'M', '2003-11-02', '9822100003'),
|
|
7
|
+
(104, 'Tanvi Chavan', 'F', '2006-01-18', '9822100004');
|
|
8
|
+
|
|
9
|
+
INSERT INTO Sport VALUES
|
|
10
|
+
('S1', 'Badminton', 'Mr. Sawant', 800, 20),
|
|
11
|
+
('S2', 'Swimming', 'Ms. Kulkarni', 1500, 15),
|
|
12
|
+
('S3', 'Table Tennis', 'Mr. Gaikwad', 600, 12);
|
|
13
|
+
|
|
14
|
+
INSERT INTO Registration VALUES
|
|
15
|
+
(101, 'S1', '2026-07-01', 'Active'),
|
|
16
|
+
(101, 'S2', '2026-08-10', 'Active'),
|
|
17
|
+
(102, 'S2', '2026-07-15', 'Active'),
|
|
18
|
+
(103, 'S3', '2026-06-20', 'Inactive'),
|
|
19
|
+
(104, 'S1', '2026-09-05', 'Active');
|
|
20
|
+
|
|
21
|
+
SELECT * FROM Member;
|
|
22
|
+
SELECT * FROM Sport;
|
|
23
|
+
SELECT * FROM Registration;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
USE sports_db;
|
|
2
|
+
|
|
3
|
+
-- Q4 duplicate phone -> ERROR 1062 (Duplicate entry). Run this alone.
|
|
4
|
+
INSERT INTO Member VALUES (105, 'Duplicate Test', 'M', '2005-05-05', '9822100001');
|
|
5
|
+
|
|
6
|
+
-- Q5
|
|
7
|
+
ALTER TABLE Member ADD COLUMN email VARCHAR(50);
|
|
8
|
+
|
|
9
|
+
-- Q6 default for status (applies to future inserts)
|
|
10
|
+
ALTER TABLE Registration ALTER COLUMN status SET DEFAULT 'Active';
|
|
11
|
+
SHOW CREATE TABLE Registration;
|
|
12
|
+
|
|
13
|
+
-- Q7 members registered for Badminton
|
|
14
|
+
SELECT m.name
|
|
15
|
+
FROM Member m
|
|
16
|
+
JOIN Registration r ON m.member_id = r.member_id
|
|
17
|
+
JOIN Sport s ON r.sport_id = s.sport_id
|
|
18
|
+
WHERE s.sport_name = 'Badminton';
|
|
19
|
+
|
|
20
|
+
-- Q8 reduce Table Tennis fee by 10% (600 -> 540)
|
|
21
|
+
UPDATE Sport SET monthly_fee = monthly_fee * 0.90 WHERE sport_name = 'Table Tennis';
|
|
22
|
+
SELECT * FROM Sport;
|
|
23
|
+
|
|
24
|
+
-- Q9 delete member 104 (DELETE - destructive). Child row in Registration goes first because of the FK.
|
|
25
|
+
DELETE FROM Registration WHERE member_id = 104;
|
|
26
|
+
DELETE FROM Member WHERE member_id = 104;
|
|
27
|
+
SELECT * FROM Member;
|
|
28
|
+
SELECT * FROM Registration;
|
|
29
|
+
|
|
30
|
+
-- Q10
|
|
31
|
+
CREATE USER IF NOT EXISTS 'coach1'@'localhost' IDENTIFIED BY 'Coach@123';
|
|
32
|
+
GRANT SELECT, UPDATE ON sports_db.Registration TO 'coach1'@'localhost';
|
|
33
|
+
REVOKE UPDATE ON sports_db.Registration FROM 'coach1'@'localhost';
|
|
34
|
+
SHOW GRANTS FOR 'coach1'@'localhost';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Slip 1B - Sports Club
|
|
2
|
+
|
|
3
|
+
**Objective:** constraints (PK, FK, UNIQUE, CHECK, DEFAULT), ALTER, JOIN, DCL.
|
|
4
|
+
|
|
5
|
+
## Run order
|
|
6
|
+
1. `01_schema.sql` (Q1, Q2)
|
|
7
|
+
2. `02_insert_data.sql` (Q3)
|
|
8
|
+
3. `03_queries.sql` (Q4-Q10)
|
|
9
|
+
|
|
10
|
+
## ER diagram (Q1)
|
|
11
|
+
```
|
|
12
|
+
Member (member_id PK) 1 ----< Registration (member_id, sport_id PK) >---- 1 Sport (sport_id PK)
|
|
13
|
+
```
|
|
14
|
+
Member and Sport are many-to-many; Registration is the linking table with a composite key.
|
|
15
|
+
|
|
16
|
+
## Notes
|
|
17
|
+
- Q4 error is `1062 Duplicate entry` - expected. Run it alone.
|
|
18
|
+
- Q9: member 104 has a Registration row, so the child row is deleted first (otherwise error 1451).
|
|
19
|
+
- Q10 final `SHOW GRANTS` should show only `GRANT SELECT` on Registration.
|
|
20
|
+
- Viva: UNIQUE allows NULL and many per table, PRIMARY KEY does not.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Q1 create attendanceDB with students, courses and attendance
|
|
2
|
+
db = db.getSiblingDB("attendanceDB");
|
|
3
|
+
|
|
4
|
+
db.students.drop(); // DESTRUCTIVE: so the script can be re-run
|
|
5
|
+
db.courses.drop(); // DESTRUCTIVE
|
|
6
|
+
db.attendance.drop(); // DESTRUCTIVE
|
|
7
|
+
|
|
8
|
+
db.students.insertMany([
|
|
9
|
+
{ _id: "S01", name: "Aditi Patil", gender: "F", dept: "AIML", semester: 3, contact: { phone: "9822200001", city: "Sangli" } },
|
|
10
|
+
{ _id: "S02", name: "Rohit Kamble", gender: "M", dept: "AIML", semester: 3, contact: { phone: "9822200002", city: "Miraj" } },
|
|
11
|
+
{ _id: "S03", name: "Sneha Mali", gender: "F", dept: "CSE", semester: 5, contact: { phone: "9822200003", city: "Kolhapur" } },
|
|
12
|
+
{ _id: "S04", name: "Yash Shinde", gender: "M", dept: "CSE", semester: 5, contact: { phone: "9822200004", city: "Sangli" } },
|
|
13
|
+
{ _id: "S05", name: "Pranav Joshi", gender: "M", dept: "AIML", semester: 3, contact: { phone: "9822200005", city: "Satara" } }
|
|
14
|
+
]);
|
|
15
|
+
|
|
16
|
+
db.courses.insertMany([
|
|
17
|
+
{ _id: "C11", name: "DBMS", credits: 4, faculty: "Dr. Patil", semester: 3 },
|
|
18
|
+
{ _id: "C12", name: "DAA", credits: 4, faculty: "Dr. Kale", semester: 3 },
|
|
19
|
+
{ _id: "C21", name: "Computer Networks", credits: 3, faculty: "Dr. Joshi", semester: 5 }
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
db.attendance.insertMany([
|
|
23
|
+
{ student_id: "S01", course_id: "C11", total: 40, attended: 37 },
|
|
24
|
+
{ student_id: "S01", course_id: "C12", total: 38, attended: 30 },
|
|
25
|
+
{ student_id: "S02", course_id: "C11", total: 40, attended: 26 },
|
|
26
|
+
{ student_id: "S02", course_id: "C12", total: 38, attended: 33 },
|
|
27
|
+
{ student_id: "S05", course_id: "C11", total: 40, attended: 31 },
|
|
28
|
+
{ student_id: "S05", course_id: "C12", total: 38, attended: 24 },
|
|
29
|
+
{ student_id: "S03", course_id: "C21", total: 36, attended: 30 },
|
|
30
|
+
{ student_id: "S04", course_id: "C21", total: 36, attended: 25 }
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
print("students " + db.students.countDocuments() + ", courses " + db.courses.countDocuments() +
|
|
34
|
+
", attendance " + db.attendance.countDocuments());
|