@@ -0,0 +1,289 @@
1+# Project:M36 in 15 Minutes
2+
3+Thank you for evaluating Project:M36, a new relational algebra engine written in Haskell. This tutorial will give you a general overview of the features of the database management system (DBMS). This tutorial assumes basic knowledge of your terminal's shell.
4+
5+## Prerequisites
6+
7+* any Linux
8+* GHC (Haskell compiler)
9+* cabal (package downloader) installed
10+
11+## Download and Install
12+
13+```bash
14+git clone https://github.com/agentm/project-m36.git
15+cabal sandbox init
16+cabal install --dependencies-only
17+cabal run tutd
18+```
19+
20+## Some Basic TutorialD
21+
22+When you run the ```tutd``` interpreter, you are interacting with an in-memory database using a dialect of the TutorialD language which is described in numerous book by Chris J. Date. It is a language specifically designed for human interaction with the relational algebra.
23+
24+Note that TutorialD is strongly-typed- no type coercions take place automatically. For example, an integer will never be interpreted as a string or vice versa.
25+
26+### Load the Canonical Chris Date Example
27+
28+```
29+TutorialD (master): :importtutd "scripts/DateExamples.tutd"
30+```
31+
32+```:importtutd``` (do not skip typing the preceding colon), loads a file which contains a script written in the TutorialD dialect used by Project:M36 and executes it to change the state of the database. In this case, the relations "s" (supplier), "p" (product), and "sp" (suppliers-products) are now loaded.
33+
34+### Execute Relational Expressions
35+
36+```
37+TutorialD (master): :showexpr s
38+┌──────────┬────────┬───────────┬───────────┐
39+│city::Text│s#::Text│sname::Text│status::Int│
40+├──────────┼────────┼───────────┼───────────┤
41+│"Paris" │"S2" │"Jones" │10 │
42+│"Paris" │"S3" │"Blake" │30 │
43+│"London" │"S1" │"Smith" │20 │
44+│"London" │"S4" │"Clark" │20 │
45+│"Athens" │"S5" │"Adams" │30 │
46+└──────────┴────────┴───────────┴───────────┘
47+```
48+
49+Use ```:showexpr``` (note the preceding colon again) followed by a TutorialD relational expression to execute the expression against the database's current state.
50+
51+A relational expression operates on the current database state (also known as "database context") and returns a relation containing the result. Note that relational expressions do not modify the state of the database.
52+
53+You will need to [learn TutorialD](docs/tutd_tutorial.markdown) to create relational expressions here, but here are a few quick, simple examples:
54+
55+#### Joins
56+
57+```
58+TutorialD (master): :showexpr s join sp
59+┌──────────┬────────┬────────┬────────┬───────────┬───────────┐
60+│city::Text│p#::Text│qty::Int│s#::Text│sname::Text│status::Int│
61+├──────────┼────────┼────────┼────────┼───────────┼───────────┤
62+│"London" │"P3" │400 │"S1" │"Smith" │20 │
63+│"London" │"P4" │300 │"S4" │"Clark" │20 │
64+│"Paris" │"P2" │200 │"S3" │"Blake" │30 │
65+│"Paris" │"P1" │300 │"S2" │"Jones" │10 │
66+│"London" │"P5" │400 │"S4" │"Clark" │20 │
67+│"London" │"P6" │100 │"S1" │"Smith" │20 │
68+│"London" │"P5" │100 │"S1" │"Smith" │20 │
69+│"Paris" │"P2" │400 │"S2" │"Jones" │10 │
70+│"London" │"P4" │200 │"S1" │"Smith" │20 │
71+│"London" │"P1" │300 │"S1" │"Smith" │20 │
72+│"London" │"P2" │200 │"S1" │"Smith" │20 │
73+└──────────┴────────┴────────┴────────┴───────────┴───────────┘
74+```
75+
76+All joins in TutorialD are similar to "NATURAL JOIN" in SQL.
77+
78+#### Restriction
79+
80+```
81+TutorialD (master): :showexpr s where status=20
82+┌──────────┬────────┬───────────┬───────────┐
83+│city::Text│s#::Text│sname::Text│status::Int│
84+├──────────┼────────┼───────────┼───────────┤
85+│"London" │"S1" │"Smith" │20 │
86+│"London" │"S4" │"Clark" │20 │
87+└──────────┴────────┴───────────┴───────────┘
88+```
89+
90+Restrictions are similar to the "WHERE" clause in SQL.
91+
92+#### Projection
93+
94+```
95+TutorialD (master): :showexpr p{color,p#,weight}
96+┌───────────┬────────┬───────────┐
97+│color::Text│p#::Text│weight::Int│
98+├───────────┼────────┼───────────┤
99+│"Red" │"P6" │19 │
100+│"Red" │"P1" │12 │
101+│"Blue" │"P5" │12 │
102+│"Green" │"P2" │17 │
103+│"Red" │"P4" │14 │
104+│"Blue" │"P3" │17 │
105+└───────────┴────────┴───────────┘
106+```
107+
108+Projection is equivalent to "SELECT <columns>" in SQL.
109+
110+#### Attribute Rename
111+
112+```
113+TutorialD (master): :showexpr s rename {city as town}
114+┌────────┬───────────┬───────────┬──────────┐
115+│s#::Text│sname::Text│status::Int│town::Text│
116+├────────┼───────────┼───────────┼──────────┤
117+│"S2" │"Jones" │10 │"Paris" │
118+│"S3" │"Blake" │30 │"Paris" │
119+│"S4" │"Clark" │20 │"London" │
120+│"S1" │"Smith" │20 │"London" │
121+│"S5" │"Adams" │30 │"Athens" │
122+└────────┴───────────┴───────────┴──────────┘
123+```
124+
125+Renaming attributes is equivalent to "SELECT city AS town..." in SQL.
126+
127+#### Relational "true" and "false"
128+
129+The relational algebra includes two fundamental named relations: "true" and "false". (Chris Date calls them "TABLE_DUM" and "TABLE_DEE" which are poor names.)
130+
131+"true" is the name of the relation with no attributes and a set of one tuple of no attributes.
132+
133+```
134+TutorialD (master): :showexpr true
135+┌┐
136+││
137+├┤
138+└┘
139+```
140+
141+"false" is the name of the relation with no attributes and an empty tuples set.
142+
143+```
144+TutorialD (master): :showexpr false
145+┌┐
146+││
147+└┘
148+```
149+
150+These relations cannot be represented in SQL databases but are fundamental to the mathematics of the relational algebra. Any relation projected against no attributes will return "true" if the relation contained any tuples or "false" otherwise.
151+
152+### Execute Database Context Expressions
153+
154+Database context expressions change the state of the database, much like "CREATE TABLE", "INSERT", "UPDATE", or "DELETE" in SQL. Database expressions in the interpreter are *not* prefixed by a colon because they are the default operation type.
155+
156+#### Create a Relation Variable
157+
158+```
159+TutorialD (master): x:=relation{name Text, age Int}{tuple{name "Steve", age 40},tuple{name "Mike", age 31}}
160+TutorialD (master): :showexpr x
161+┌────────┬──────────┐
162+│age::Int│name::Text│
163+├────────┼──────────┤
164+│40 │"Steve" │
165+│31 │"Mike" │
166+└────────┴──────────┘
167+```
168+
169+This is similar to SQL's "CREATE TABLE" operator.
170+
171+#### Insert Additional Tuples
172+
173+```
174+TutorialD (master): x:=relation{name Text, age Int}{tuple{name "Steve", age 40},tuple{name "Mike", age 31}}
175+TutorialD (master): :showexpr x
176+┌────────┬──────────┐
177+│age::Int│name::Text│
178+├────────┼──────────┤
179+│40 │"Steve" │
180+│31 │"Mike" │
181+└────────┴──────────┘
182+TutorialD (master): insert x relation{tuple{name "Bob", age 24}}
183+TutorialD (master): :showexpr x
184+┌────────┬──────────┐
185+│age::Int│name::Text│
186+├────────┼──────────┤
187+│40 │"Steve" │
188+│24 │"Bob" │
189+│31 │"Mike" │
190+└────────┴──────────┘
191+```
192+
193+Note that the relational insertion is identical to "x:=x union relation{...}".
194+
195+#### Update Tuples in a Relation Variable
196+
197+```
198+TutorialD (master): :showexpr s
199+┌──────────┬────────┬───────────┬───────────┐
200+│city::Text│s#::Text│sname::Text│status::Int│
201+├──────────┼────────┼───────────┼───────────┤
202+│"Paris" │"S2" │"Jones" │10 │
203+│"Paris" │"S3" │"Blake" │30 │
204+│"London" │"S1" │"Smith" │20 │
205+│"London" │"S4" │"Clark" │20 │
206+│"Athens" │"S5" │"Adams" │30 │
207+└──────────┴────────┴───────────┴───────────┘
208+TutorialD (master): update s where city="London" (status:=35)
209+TutorialD (master): :showexpr s
210+┌──────────┬────────┬───────────┬───────────┐
211+│city::Text│s#::Text│sname::Text│status::Int│
212+├──────────┼────────┼───────────┼───────────┤
213+│"London" │"S4" │"Clark" │35 │
214+│"London" │"S1" │"Smith" │35 │
215+│"Paris" │"S2" │"Jones" │10 │
216+│"Paris" │"S3" │"Blake" │30 │
217+│"Athens" │"S5" │"Adams" │30 │
218+└──────────┴────────┴───────────┴───────────┘
219+```
220+#### Deleting Tuples from a Relation Variable
221+
222+```
223+TutorialD (master): :showexpr s
224+┌──────────┬────────┬───────────┬───────────┐
225+│city::Text│s#::Text│sname::Text│status::Int│
226+├──────────┼────────┼───────────┼───────────┤
227+│"Paris" │"S2" │"Jones" │10 │
228+│"Paris" │"S3" │"Blake" │30 │
229+│"London" │"S1" │"Smith" │20 │
230+│"London" │"S4" │"Clark" │20 │
231+│"Athens" │"S5" │"Adams" │30 │
232+└──────────┴────────┴───────────┴───────────┘
233+TutorialD (master): delete s where sname="Adams"
234+TutorialD (master): :showexpr s
235+┌──────────┬────────┬───────────┬───────────┐
236+│city::Text│s#::Text│sname::Text│status::Int│
237+├──────────┼────────┼───────────┼───────────┤
238+│"Paris" │"S2" │"Jones" │10 │
239+│"Paris" │"S3" │"Blake" │30 │
240+│"London" │"S1" │"Smith" │20 │
241+│"London" │"S4" │"Clark" │20 │
242+└──────────┴────────┴───────────┴───────────┘
243+```
244+
245+### Execute Transaction Graph Expressions
246+
247+Unlike typical SQL DBMSs, Project:M36 maintains a graph of transactions, similar to how git stores source patches. This allows the database context to be branched (with a name), merged, and enables recalling the database context from past transactions.
248+
249+#### Committing
250+
251+```
252+TutorialD (master): :commit
253+```
254+
255+#### Rollback
256+
257+```
258+TutorialD (master): :rollback
259+```
260+
261+#### Branching
262+
263+```
264+TutorialD (master): :branch experimental
265+TutorialD (experimental): employee:=relation{name Text, salary Int}
266+TutorialD (experimental): :commit
267+```
268+
269+Note how the prompt changes to reflect the current branch's name.
270+
271+#### Jump to Branch
272+
273+```
274+TutorialD (experimental): :jumphead master
275+TutorialD (master): :showexpr employee
276+ERR: RelVarNotDefinedError "employee"
277+```
278+
279+Now we have jumped back to the master branch and we can confirm that the "employee" relation variable is not present here despite being committed. It was, in fact, committed only on the "experimental" branch.
280+
281+#### Other operations
282+
283+Of course, Project:M36 supports [aggregate operators](docs/tutd_tutorial.markdown#aggregate-queries), [value functions](docs/tutd_tutorial.markdown#extend), [database constraints](docs/tutd_tutorial.markdown#constraints) including candidate and foreign keys, and other operators not mentioned in this brief tutorial.
284+
285+## Conclusion
286+
287+The TutorialD dialect used by Project:M36 is ideal for learning about the relational algebra because it is quick to write and grammatically unambiguous.
288+
289+The TutorialD language is not, however, suitable for production use because such use would be susceptible to the same string injection attacks which plague SQL. For integration with middleware, please try the [persistent library driver](docs/persistent_library_driver.markdown) or [the native Haskell interface](docs/projectm36_client_library.markdown).