Skip to content

Commit 2815551

Browse files
committed
WIP
1 parent ae00828 commit 2815551

File tree

21 files changed

+171
-63
lines changed

21 files changed

+171
-63
lines changed

versioned_docs/version-3.x/_components/ZModelVsPSL.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ interface ZModelVsPSLProps {
77

88
const ZModelVsPSL: FC<ZModelVsPSLProps> = ({ children }) => {
99
return (
10-
<Admonition type="info" title="🔋 ZModel vs PSL">
10+
<Admonition type="info" title="🔋 ZModel vs Prisma Schema">
1111
{children}
1212
</Admonition>
1313
);

versioned_docs/version-3.x/migration/_category_.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,3 @@ position: 4
22
label: Migration
33
collapsible: true
44
collapsed: true
5-
link:
6-
type: generated-index
7-
title: Migration
File renamed without changes.

versioned_docs/version-3.x/modeling/_category_.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,3 @@ position: 2
22
label: Data Modeling
33
collapsible: true
44
collapsed: true
5-
link:
6-
type: generated-index
7-
title: Data Modeling
File renamed without changes.

versioned_docs/version-3.x/modeling/multi-file.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,40 @@ sidebar_position: 11
33
description: Breaking down complex schemas into multiple files
44
---
55

6+
import ZModelVsPSL from '../_components/ZModelVsPSL';
7+
68
# Multi-file Schema
79

10+
<ZModelVsPSL>
11+
Prisma uses an implicit approach that simply merges all schema files in a folder. ZModel uses explicit `import` syntax for better clarity and flexibility.
12+
</ZModelVsPSL>
13+
14+
When your schema grows large, you can break them down to smaller files and stitch them together using the `import` statement.
15+
16+
```zmodel title="zenstack/user.zmodel"
17+
import './post'
18+
19+
model User {
20+
id Int @id
21+
posts Post[]
22+
}
23+
```
24+
25+
```zmodel title="zenstack/post.zmodel"
26+
import './user'
27+
28+
model Post {
29+
id Int @id
30+
content String
31+
author User @relation(fields: [authorId], references: [id])
32+
authorId Int
33+
}
34+
```
35+
36+
```zmodel title="zenstack/schema.zmodel"
37+
import './user'
38+
import './post'
39+
```
840

41+
After type-checking, these files are merged into a single schema AST before passed to the downstream tools.
942

versioned_docs/version-3.x/modeling/plugin.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,36 @@ sidebar_position: 11
33
description: ZenStack plugins
44
---
55

6+
import ZModelVsPSL from '../_components/ZModelVsPSL';
7+
68
# Plugin
79

10+
<ZModelVsPSL>
11+
ZenStack's "plugin" concept replaces PSL's "generator".
12+
</ZModelVsPSL>
13+
14+
Plugin is a powerful mechanism that allows you to extend ZenStack at the schema, CLI, and runtime levels. This section only focuses on how to add plugins to your ZModel. Please refer to the [Plugin Development](../reference/plugin-dev.md) section for more details on how to develop plugins.
15+
16+
## Adding plugins to ZModel
17+
18+
Let's take a look at the following example:
19+
20+
```zmodel
21+
plugin myPlugin {
22+
provider = 'my-zenstack-plugin'
23+
output = './generated'
24+
}
25+
```
26+
27+
A plugin declaration involves three parts:
28+
29+
1. A unique name
30+
2. A `provider` field that specifies where to load the plugin from. It can be a built-in plugin (like `@core/prisma` here), a local folder, or an npm package.
31+
3. Plugin-specific configuration options, such as `output` in this case.
32+
33+
A plugin can have the following effects to ZModel:
34+
35+
- It can contribute custom attributes that you can use to annotate models and fields.
36+
- It can contribute code generation logic that's executed when you run the `zenstack generate` command.
37+
38+
Plugins can also contribute to the ORM runtime behavior, and we'll leave it to the [ORM](../orm/plugins/) part to explain it in detail.

versioned_docs/version-3.x/modeling/polymorphism.md

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ When modeling non-trivial applications, the need of an "Object-Oriented" kind of
1717
- Something **IS-A** more abstract type of thing.
1818
- Something **HAS-A/HAS-many** a more abstract type of thing(s).
1919

20-
Imagine we're modeling a content library system where users own different types of content: posts, videos, images, etc. They share some common traits like name, creation date, owner, etc., but have different specific fields.
20+
Imagine we're modeling a content library system where users own different types of content: posts, images, videos, etc. They share some common traits like name, creation date, owner, etc., but have different specific fields.
2121

2222
It may be tempting to use mixins to share the common fields, however it's not an ideal solution because:
2323

@@ -32,3 +32,91 @@ There are [two main ways](https://www.prisma.io/docs/orm/prisma-schema/data-mode
3232
:::
3333

3434
## Modeling polymorphism
35+
36+
Modeling polymorphism in ZModel is similar to designing an OOP class hierarchy - you introduce a base model and then extend it with concrete ones.
37+
38+
Here's how it looks for our content library example:
39+
40+
```zmodel
41+
model User {
42+
id Int @id
43+
contents Content[]
44+
}
45+
46+
model Content {
47+
id Int @id
48+
name String
49+
createdAt DateTime @default(now())
50+
owner User @relation(fields: [ownerId], references: [id])
51+
ownerId Int
52+
// highlight-next-line
53+
type String
54+
55+
// highlight-next-line
56+
@@delegate(type)
57+
}
58+
59+
model Post extends Content {
60+
content String
61+
}
62+
63+
model Image extends Content {
64+
data Bytes
65+
}
66+
67+
model Video extends Content {
68+
url String
69+
}
70+
```
71+
72+
```mermaid
73+
erDiagram
74+
User {
75+
id Int PK
76+
}
77+
Content {
78+
id Int PK
79+
name String
80+
createdAt Date
81+
ownerId Int FK
82+
type String
83+
}
84+
User ||--o{ Content: owns
85+
Post {
86+
id Int PK
87+
content String
88+
}
89+
Post ||--|| Content: delegates
90+
Image {
91+
id Int PK
92+
data Bytes
93+
}
94+
Image ||--|| Content: delegates
95+
Video {
96+
id Int PK
97+
url String
98+
}
99+
Video ||--|| Content: delegates
100+
```
101+
102+
There are two special things about polymorphic base model:
103+
104+
1. It must have a "discriminator" field that stores the concrete model type that it should "delegate" to. In the example above, the `type` field serves this purpose. It can be named anything you like, but must be of `String` or enum type.
105+
2. It must have a `@@delegate` attribute. The attribute serves two purposes: it indicates that the model is a base model, and it designates the discriminator field with its parameter.
106+
107+
You can also have a deep hierarchy involving multiple level of base models. Just need to make sure each base model has its own discriminator field and `@@delegate` attribute. Extending from multiple base models directly is not supported.
108+
109+
## Migration behavior
110+
111+
The migration engine takes care of mapping both the base model and the concrete ones to tables, and creates one-to-one relations between the base and each of its derivations.
112+
113+
To simplify query and conserve space, the base and the concrete are assumed to share the same id values (this is guaranteed by the ORM when creating the records), and consequently, the concrete model's id field is also reused as the foreign key to the base model. So, for a `Post` record with id `1`, the base `Content` record also has id `1`.
114+
115+
## ORM behavior
116+
117+
The ORM hides the delegate complexities and provides a simple polymorphic view to the developers:
118+
119+
1. Creating a concrete model record automatically creates the base model record with the same id and proper discriminator field.
120+
2. Querying with the base model will return entities with concrete model fields.
121+
122+
We'll revisit the topic in details in the [ORM](../orm/) part.
File renamed without changes.

versioned_docs/version-3.x/orm/_category_.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,3 @@ position: 3
22
label: ORM
33
collapsible: true
44
collapsed: true
5-
link:
6-
type: generated-index
7-
title: ORM

0 commit comments

Comments
 (0)