Skip to content

Commit adec2cf

Browse files
author
Loïc Knuchel
committed
write doc for AML
1 parent 9479ada commit adec2cf

19 files changed

Lines changed: 359 additions & 21 deletions

docs/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Azimutt
2+
3+
Welcome to [Azimutt](https://azimutt.app) documentation.
4+
5+
This is a *work in progress* but don't hesitate to ask for more ;)
6+
7+
Here are the written parts:
8+
9+
- [AML: Azimutt Markup Language](aml/README.md)

docs/aml/README.md

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
# AML: Azimutt Markup Language
2+
3+
**AML is a text language allowing you to define your database schema in the quickest and most intuitive way.**
4+
5+
It was built with the minimal boilerplate to be fast to write but also to limit the learning curve and possible mistakes. It's, of course, the language used in [Azimutt](https://azimutt.app) to define or extend your schema (along with other data sources like SQL code, database connection or even JSON).
6+
7+
Here is a typical example of what it looks like:
8+
9+
```aml
10+
users | store every user # AML comment
11+
id uuid pk
12+
login varchar(30) unique
13+
role user_role(guest, member, admin)=guest
14+
email varchar nullable
15+
group_id fk groups.id
16+
created timestamp=now()
17+
```
18+
19+
As you can see, almost all characters are your own content, no ceremony.
20+
21+
Now let's dig more into it and see all the features...
22+
If you want to try them live, just create a [new empty project](https://azimutt.app/projects/create) on Azimutt.
23+
24+
- [Tables](#tables)
25+
- [Columns](#columns)
26+
- [Relations](#relations)
27+
- [Comments](#comments)
28+
- [Philosophy & Conventions](#philosophy--conventions)
29+
- [Full example](#full-example)
30+
31+
## 🔖 Tables
32+
33+
Defining a table is the most common thing you will do with AML, and it's as simple as writing its name:
34+
35+
```aml
36+
my_table_name
37+
```
38+
39+
This name should be without space or dot but to allow them you can use `"`.
40+
You can prefix your table name with its schema name followed by a dot if you want, the same rules apply to it (no space or dot, or use `"`).
41+
Finally, you can add a `*` at the end of the table name to mark it as a *view* instead of a table.
42+
43+
Here is some examples of tables definitions:
44+
45+
```aml
46+
users
47+
public.users
48+
"user table"
49+
"users.sql"
50+
users_view*
51+
"demo 2"."users 2"
52+
```
53+
54+
As you can see, it's possible to define one table per line and with as little as one word, it's quite convenient to quickly write what you have in mind!
55+
56+
## 🔖 Columns
57+
58+
Tables are great, but without columns, they are a bit poor...
59+
A column can be defined as simple as its name with a 2 space indentation:
60+
61+
```aml
62+
users
63+
id
64+
```
65+
66+
Here you are, you just defined a `users` table with an `id` column 🎉
67+
It's very convenient to write very fast all the tables and columns you have in mind.
68+
As for the table and schema names, if you need space or dot inside, you can use `"` around it.
69+
70+
Of course, you may want to provide additional details on columns, here is its full structure:
71+
72+
```aml
73+
name type nullable pk index unique check fk table.column | notes # comment
74+
```
75+
76+
Every part being optional except the name. Some parts may have additional options.
77+
Let's detail them...
78+
79+
- [Column type](#column-type)
80+
- [Column modifiers](#column-modifiers)
81+
- [Column relation](#column-relation)
82+
83+
### Column type
84+
85+
There is no SQL validation for it, you can write anything you want and define meaningful types names to help understanding your schema. Of course, the same rule applies, if you need spaces or dots inside, you will need to use `"` around.
86+
87+
If the type has a *default value*, you can write it just after an `=` sign (ex: `int=0`).
88+
If the type has *enumerable values*, you can write them in parenthesis (ex: `role(guest, admin)`).
89+
90+
Here are some valid examples:
91+
92+
- `int`: one of the most basic type ^^
93+
- `"character varying"`: a type with space in it
94+
- `varchar(12)`: a type with a precision (not treated as enum if only one or two values which are integers)
95+
- `decimal(5, 2)`: another kind of precision
96+
- `varchar=y`: a default value
97+
- `state(active,disabled)`: an enum
98+
- `role(guest, admin)=guest`: an enum with a default value
99+
100+
### Column modifiers
101+
102+
As seen in the [Columns](#columns) section, a column can have several modifiers.
103+
104+
`nullable` is a simple flag, telling the column can contain `null` values. In AML, by default columns are not nullable, this is the opposite of SQL but much more convenient and quick to write, as most of your columns should not be nullable.
105+
106+
`pk` means *primary key*, use it to identify a column as a table primary key. You can use this flag in several columns to create a composite primary key.
107+
108+
`index`, `unique` and `check` have a similar behavior. You can use them as flag to express the column property, but you can also give them a name using the `=` sign (ex: `unique=user_slug`). This name will be shown in the interface but also will allow to create a constraint on several columns sharing the same constraint name.
109+
110+
For the `check` constraint, you can use this name (or label) to define the condition.
111+
112+
Here is some examples:
113+
114+
```aml
115+
users
116+
id uuid pk
117+
first_name varchar unique=name
118+
last_name varchar unique=name check="LEN(last_name) > 3"
119+
bio text nullable
120+
121+
credentials
122+
provider_id varchar pk
123+
provider_key varchar pk
124+
user_id fk users.id
125+
```
126+
127+
### Column relation
128+
129+
Some columns can reference another column, eventually using a SQL foreign key. In AML, this can be done with the `fk` keyword (shortcut for *foreign key* 😉) in the column definition or as a standalone instruction (see [Relations](#relations)).
130+
This relation means a column references another one, and thus can be used in a join clause. But it does not necessarily imply there is a real foreign key in the database schema.
131+
132+
To define a relation in the column definition, just add the `fk` keyword with a column reference after like this: `fk table.column`, or with the table schema: `fk schema.table.column`.
133+
134+
In the case of [polymorphic relations](https://devdojo.com/tnylea/understanding-polymorphic-relationships), you can define several relations starting from a column, but the additional ones should be defined using standalone instructions (see [Relations](#relations)).
135+
*For better consistency, it's recommended to only use standalone relations to define polymorphic relations even if not required by the language.*
136+
137+
For [composite relations](https://www.ibm.com/docs/en/informix-servers/14.10?topic=format-defining-composite-primary-foreign-keys) (involving several columns), they are **not supported** yet in AML or Azimutt. This is a planned evolution but no timeline has been decided as many other important features are still to come. If you need them, please reach out, so we can plan them.
138+
139+
## 🔖 Relations
140+
141+
As seen before, relations can be defined [inside the column definition](#column-relation), and it's often the most efficient way to do so. But, sometimes, is useful or needed to define them as a standalone instruction.
142+
143+
Here is how to do it:
144+
145+
```aml
146+
fk projects.owner -> users.id
147+
```
148+
149+
The standalone relation instruction should start with the `fk` keyword and then have two column references separated by a simple arrow (`->`).
150+
151+
This is useful to define multiple relations from a column (in case of polymorphic relations) or define relations between columns that are not defined in AML (useful to declare relations that were not found in SQL or database sources because they didn't have a foreign key).
152+
153+
Here is an example:
154+
155+
```aml
156+
requests
157+
id uuid
158+
kind varchar
159+
item_type varchar
160+
item_id integer
161+
162+
fk requests.item_id -> users.id
163+
fk requests.item_id -> talks.id
164+
fk requests.item_id -> logins.id
165+
```
166+
167+
## 🔖 Comments
168+
169+
Having comments on tables and relations can be a great help for people to understand how the database works. In AML you can define a *SQL comment* using the `|` symbol at the end of your table or column definition. It will be visible directly inside the interface.
170+
171+
For example:
172+
173+
```aml
174+
users | store all our users
175+
id | column to uniquely identify a user
176+
```
177+
178+
This is the only special part of AML that doesn't need `"` to contain spaces and dots.
179+
180+
There is also *AML comments* you can use to write explanations you don't want to show in the interface. They are useful to explain why you wrote what you wrote ^^. Such comments are defined with the `#` symbol and should be at the end of the line (everything after is ignored).
181+
SQL and AML comments can be combined in the same line but the AML one should **always** be after.
182+
183+
Let's see an example:
184+
185+
```aml
186+
# the user table
187+
users | store ALL users
188+
id | unique identifier # not sure if I should put `uuid` or `int`
189+
name varchar # which size?
190+
created_at timestamp=now() | never update this column
191+
```
192+
193+
## 🔖 Philosophy & Conventions
194+
195+
In order to be the fastest to write, AML have very few keywords and symbols, and they are all very short and preferred in lower case for fluid typing.
196+
Still, if you want to highlight the difference between keywords and your content (names, types, doc...), you can write AML keywords in upper case to ease reading.
197+
But it's strongly encouraged to be consistent.
198+
199+
As said in introduction, AML is built to be very intuitive and fast to learn and write.
200+
If you see possible improvements on the syntax or even features, please don't hesitate to [post an issue](https://github.com/azimuttapp/azimutt/issues), so we could improve it for everyone ❤️
201+
If you like it or want to give feedback, we will be very pleased to hear about you. Please get in touch with us on Twitter: [@azimuttapp](https://twitter.com/azimuttapp).
202+
203+
## 🔖 Full example
204+
205+
Now everything has been explained, let's write a meaningful example to give you a larger view of what it looks like to use AML as schema definition.
206+
207+
Let's define a hypothetical e-commerce shop:
208+
209+
![e-commerce schema defined using AML](e-commerce-using-aml.png)
210+
211+
```aml
212+
#
213+
# Identity domain
214+
#
215+
216+
users
217+
id uuid pk
218+
slug varchar unique | user identifier in urls
219+
role user_role(customer, staff, admin)
220+
name varchar
221+
avatar url
222+
email varchar unique
223+
email_validated timestamp nullable
224+
phone varchar unique
225+
phone_validated timestamp nullable
226+
bio text nullable
227+
company varchar nullable
228+
locale locale(en, fr)
229+
created_at timestamp
230+
updated_at timestamp
231+
last_login timestamp
232+
233+
credentials
234+
provider_id provider(google, facebook, twitter, email) pk
235+
provider_key varchar pk | user id in provider system
236+
hasher hash_method(md5, sha1, sha256)
237+
password_hash varchar
238+
password_salt varchar
239+
user_id uuid fk users.id
240+
241+
social_profiles
242+
user_id uuid fk users.id
243+
platform social_platform(facebook, twitter, instagram, slack, github)
244+
platform_user varchar
245+
created_at timestamp
246+
247+
#
248+
# Catalog domain
249+
#
250+
251+
categories
252+
id uuid pk
253+
slug varchar unique | category identifier in urls
254+
name varchar
255+
description text
256+
tags varchar[]
257+
parent_category uuid fk categories.id
258+
created_at timestamp
259+
updated_at timestamp
260+
261+
products
262+
id uuid pk
263+
category_id uuid nullable fk categories.id
264+
title varchar
265+
picture varchar
266+
summary text
267+
description text
268+
price number | in Euro
269+
discount_type discount_type(none, percent, amount)
270+
discount_value number
271+
tags varchar[]
272+
created_at timestamp
273+
updated_at timestamp
274+
275+
reviews
276+
id uuid pk
277+
user_id uuid fk users.id
278+
product_id uuid fk products.id
279+
rating int index | between 1 and 5
280+
comment text
281+
created_at timestamp
282+
283+
#
284+
# Cart domain
285+
#
286+
287+
carts
288+
id uuid pk
289+
status cart_status(active, ordered, abandonned)
290+
created_at timestamp=now
291+
created_by uuid fk users.id
292+
updated_at timestamp
293+
294+
cart_items
295+
cart_id uuid pk fk carts.id
296+
product_id uuid pk fk products.id
297+
price number
298+
quantity int check="quantity > 0" | should be > 0
299+
created_at timestamp
300+
301+
#
302+
# Order domain
303+
#
304+
305+
orders
306+
id uuid pk
307+
user_id uuid fk users.id
308+
created_at timestamp
309+
310+
order_lines
311+
id uuid pk
312+
order_id uuid fk orders.id
313+
product_id uuid fk products.id | used as reference and for re-order by copy data at order time as they should not change
314+
price number | in Euro
315+
quantity int check="quantity > 0" | should be > 0
316+
```
317+
318+
Hope you enjoyed AML, happy hacking on [Azimutt](https://azimutt.app)!

docs/aml/e-commerce-using-aml.png

95 KB
Loading

docs/embed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TODO

docs/keyboard-shortcuts.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TODO

docs/layout-settings.md

Whitespace-only changes.

docs/layouts.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TODO

docs/notes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TODO

docs/privacy.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TODO

docs/project-settings.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TODO

0 commit comments

Comments
 (0)