oktopios-orm 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.
- oktopios_orm-0.1.0/LICENSE +21 -0
- oktopios_orm-0.1.0/PKG-INFO +113 -0
- oktopios_orm-0.1.0/README.md +77 -0
- oktopios_orm-0.1.0/oktopios_orm/__init__.py +2 -0
- oktopios_orm-0.1.0/oktopios_orm/orm.okp +179 -0
- oktopios_orm-0.1.0/oktopios_orm.egg-info/PKG-INFO +113 -0
- oktopios_orm-0.1.0/oktopios_orm.egg-info/SOURCES.txt +10 -0
- oktopios_orm-0.1.0/oktopios_orm.egg-info/dependency_links.txt +1 -0
- oktopios_orm-0.1.0/oktopios_orm.egg-info/requires.txt +1 -0
- oktopios_orm-0.1.0/oktopios_orm.egg-info/top_level.txt +1 -0
- oktopios_orm-0.1.0/pyproject.toml +24 -0
- oktopios_orm-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Mouanwiya Ali Soule
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: oktopios-orm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: ORM pour le langage Oktopios â modeles decores, migrations, query-builder (facon Doctrine / Django ORM)
|
|
5
|
+
Author: Mouanwiya Ali Soule
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2025 Mouanwiya Ali Soule
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/ALISOULEMOUANWIYA/oktopios-orm
|
|
29
|
+
Project-URL: Language, https://pypi.org/project/oktopios/
|
|
30
|
+
Keywords: oktopios,orm,database,sqlite,migrations,okp
|
|
31
|
+
Requires-Python: >=3.8
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
License-File: LICENSE
|
|
34
|
+
Requires-Dist: oktopios>=0.7.0
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# oktopios-orm đđïž
|
|
38
|
+
|
|
39
|
+
ORM pour le langage **[Oktopios](https://pypi.org/project/oktopios/)** â dans
|
|
40
|
+
l'esprit de **Doctrine** (Symfony) et de l'**ORM de Django** : modÚles déclarés
|
|
41
|
+
par décorateurs, migrations automatiques, dépÎt générique et query-builder.
|
|
42
|
+
|
|
43
|
+
DeuxiÚme couche de l'écosystÚme :
|
|
44
|
+
**langage `oktopios` â `oktopios-orm` â `oktopios-framework`**.
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install oktopios-orm
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Cela installe aussi le langage `oktopios` (dépendance). Comme Django a besoin de
|
|
53
|
+
Python et Doctrine de PHP, `oktopios-orm` a besoin de l'interpréteur `oktopios`.
|
|
54
|
+
|
|
55
|
+
## Utilisation
|
|
56
|
+
|
|
57
|
+
Dans un fichier `.okp` :
|
|
58
|
+
|
|
59
|
+
```okp
|
|
60
|
+
use "oktopios_orm/orm.okp" // résolu depuis le paquet installé
|
|
61
|
+
inject Type
|
|
62
|
+
|
|
63
|
+
@Entity("articles")
|
|
64
|
+
class Article {
|
|
65
|
+
@Id
|
|
66
|
+
var id: int
|
|
67
|
+
@Column("titre")
|
|
68
|
+
var title: string
|
|
69
|
+
var vues: int
|
|
70
|
+
fun __construct(title: string, vues: int) {
|
|
71
|
+
this.title = title
|
|
72
|
+
this.vues = vues
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
var schema = new Schema()
|
|
77
|
+
var sample = new Article("", 0)
|
|
78
|
+
schema.migrate("blog.db", sample) // CREATE TABLE articles (id INTEGER PRIMARY KEY, titre TEXT, vues INTEGER)
|
|
79
|
+
|
|
80
|
+
var repo = new Repo("blog.db", sample)
|
|
81
|
+
var a = new Article("Bonjour", 100)
|
|
82
|
+
Type.set(a, "id", 1)
|
|
83
|
+
repo.save(a)
|
|
84
|
+
|
|
85
|
+
for (x in repo.all()) { print(x.title) }
|
|
86
|
+
|
|
87
|
+
var q = new Query("blog.db", "articles")
|
|
88
|
+
print(q.select("id, titre, vues").where("vues", ">", 50).orderBy("vues", "DESC").get())
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Exécuter : `okp examples/blog.okp`
|
|
92
|
+
|
|
93
|
+
## Contenu (`oktopios_orm/orm.okp`)
|
|
94
|
+
|
|
95
|
+
- **`Schema`** â migrations : gĂ©nĂšre le schĂ©ma SQL depuis les modĂšles dĂ©corĂ©s
|
|
96
|
+
(`@Entity`, `@Id`, `@Column`) ; mapping des types (`intâINTEGER`, `stringâTEXT`,
|
|
97
|
+
`floatâREAL`, `boolâINTEGER`).
|
|
98
|
+
- **`Repo`** â dĂ©pĂŽt gĂ©nĂ©rique : `save`, `all`, `findBy`, `remove`, hydratation
|
|
99
|
+
ligne â objet typĂ© (par rĂ©flexion).
|
|
100
|
+
- **`Query`** â constructeur de requĂȘtes fluide : `select().where().orderBy().get()`,
|
|
101
|
+
paramétré (anti-injection).
|
|
102
|
+
|
|
103
|
+
## Décorateurs reconnus
|
|
104
|
+
|
|
105
|
+
| Décorateur | Cible | Effet |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| `@Entity("table")` | classe | nom de la table |
|
|
108
|
+
| `@Column("colonne")` | champ | nom de la colonne |
|
|
109
|
+
| `@Id` | champ | clé primaire |
|
|
110
|
+
|
|
111
|
+
## Licence
|
|
112
|
+
|
|
113
|
+
MIT © Mouanwiya Ali Soule
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# oktopios-orm đđïž
|
|
2
|
+
|
|
3
|
+
ORM pour le langage **[Oktopios](https://pypi.org/project/oktopios/)** â dans
|
|
4
|
+
l'esprit de **Doctrine** (Symfony) et de l'**ORM de Django** : modÚles déclarés
|
|
5
|
+
par décorateurs, migrations automatiques, dépÎt générique et query-builder.
|
|
6
|
+
|
|
7
|
+
DeuxiÚme couche de l'écosystÚme :
|
|
8
|
+
**langage `oktopios` â `oktopios-orm` â `oktopios-framework`**.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install oktopios-orm
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Cela installe aussi le langage `oktopios` (dépendance). Comme Django a besoin de
|
|
17
|
+
Python et Doctrine de PHP, `oktopios-orm` a besoin de l'interpréteur `oktopios`.
|
|
18
|
+
|
|
19
|
+
## Utilisation
|
|
20
|
+
|
|
21
|
+
Dans un fichier `.okp` :
|
|
22
|
+
|
|
23
|
+
```okp
|
|
24
|
+
use "oktopios_orm/orm.okp" // résolu depuis le paquet installé
|
|
25
|
+
inject Type
|
|
26
|
+
|
|
27
|
+
@Entity("articles")
|
|
28
|
+
class Article {
|
|
29
|
+
@Id
|
|
30
|
+
var id: int
|
|
31
|
+
@Column("titre")
|
|
32
|
+
var title: string
|
|
33
|
+
var vues: int
|
|
34
|
+
fun __construct(title: string, vues: int) {
|
|
35
|
+
this.title = title
|
|
36
|
+
this.vues = vues
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
var schema = new Schema()
|
|
41
|
+
var sample = new Article("", 0)
|
|
42
|
+
schema.migrate("blog.db", sample) // CREATE TABLE articles (id INTEGER PRIMARY KEY, titre TEXT, vues INTEGER)
|
|
43
|
+
|
|
44
|
+
var repo = new Repo("blog.db", sample)
|
|
45
|
+
var a = new Article("Bonjour", 100)
|
|
46
|
+
Type.set(a, "id", 1)
|
|
47
|
+
repo.save(a)
|
|
48
|
+
|
|
49
|
+
for (x in repo.all()) { print(x.title) }
|
|
50
|
+
|
|
51
|
+
var q = new Query("blog.db", "articles")
|
|
52
|
+
print(q.select("id, titre, vues").where("vues", ">", 50).orderBy("vues", "DESC").get())
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Exécuter : `okp examples/blog.okp`
|
|
56
|
+
|
|
57
|
+
## Contenu (`oktopios_orm/orm.okp`)
|
|
58
|
+
|
|
59
|
+
- **`Schema`** â migrations : gĂ©nĂšre le schĂ©ma SQL depuis les modĂšles dĂ©corĂ©s
|
|
60
|
+
(`@Entity`, `@Id`, `@Column`) ; mapping des types (`intâINTEGER`, `stringâTEXT`,
|
|
61
|
+
`floatâREAL`, `boolâINTEGER`).
|
|
62
|
+
- **`Repo`** â dĂ©pĂŽt gĂ©nĂ©rique : `save`, `all`, `findBy`, `remove`, hydratation
|
|
63
|
+
ligne â objet typĂ© (par rĂ©flexion).
|
|
64
|
+
- **`Query`** â constructeur de requĂȘtes fluide : `select().where().orderBy().get()`,
|
|
65
|
+
paramétré (anti-injection).
|
|
66
|
+
|
|
67
|
+
## Décorateurs reconnus
|
|
68
|
+
|
|
69
|
+
| Décorateur | Cible | Effet |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| `@Entity("table")` | classe | nom de la table |
|
|
72
|
+
| `@Column("colonne")` | champ | nom de la colonne |
|
|
73
|
+
| `@Id` | champ | clé primaire |
|
|
74
|
+
|
|
75
|
+
## Licence
|
|
76
|
+
|
|
77
|
+
MIT © Mouanwiya Ali Soule
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// =====================================================================
|
|
2
|
+
// oktopios-framework â Couche ORM
|
|
3
|
+
// Ăcrit EN Oktopios, s'appuie sur la rĂ©flexion et les dĂ©corateurs du
|
|
4
|
+
// langage (>= 0.6.0). Chargé via : use "framework/orm.okp"
|
|
5
|
+
//
|
|
6
|
+
// - Schema : migrations (génÚre le schéma SQL depuis les modÚles décorés)
|
|
7
|
+
// - Repo : dépÎt générique (save / all / findBy / remove + hydratation)
|
|
8
|
+
// - Query : constructeur de requĂȘtes fluide
|
|
9
|
+
//
|
|
10
|
+
// Décorateurs reconnus :
|
|
11
|
+
// @Entity("table") (classe) -> nom de table
|
|
12
|
+
// @Column("colonne") (champ) -> nom de colonne
|
|
13
|
+
// @Id (champ) -> clé primaire
|
|
14
|
+
// =====================================================================
|
|
15
|
+
inject Type
|
|
16
|
+
inject DataImport
|
|
17
|
+
|
|
18
|
+
// ---------------------------------------------------------------------
|
|
19
|
+
// Schema â gĂ©nĂ©ration de schĂ©ma / migrations
|
|
20
|
+
// ---------------------------------------------------------------------
|
|
21
|
+
class Schema {
|
|
22
|
+
fun sqlType(t: string): string {
|
|
23
|
+
if (t == "int") { return "INTEGER" }
|
|
24
|
+
if (t == "float") { return "REAL" }
|
|
25
|
+
if (t == "bool") { return "INTEGER" }
|
|
26
|
+
return "TEXT"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
fun tableName(entity: any): string {
|
|
30
|
+
var e = Type.annotation(entity, "Entity")
|
|
31
|
+
if (e != null) { return e[0] }
|
|
32
|
+
return Type.className(entity)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
fun columnName(entity: any, champ: string): string {
|
|
36
|
+
var c = Type.fieldAnnotation(entity, champ, "Column")
|
|
37
|
+
if (c != null) { return c[0] }
|
|
38
|
+
return champ
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fun idField(entity: any): string {
|
|
42
|
+
for (f in Type.fields(entity)) {
|
|
43
|
+
if (Type.fieldAnnotation(entity, f, "Id") != null) { return f }
|
|
44
|
+
}
|
|
45
|
+
return "id"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
fun createTableSQL(entity: any): string {
|
|
49
|
+
var defs = ""
|
|
50
|
+
for (f in Type.fields(entity)) {
|
|
51
|
+
if (defs != "") { defs = defs + ", " }
|
|
52
|
+
var ligne = this.columnName(entity, f) + " " + this.sqlType(Type.fieldType(entity, f))
|
|
53
|
+
if (Type.fieldAnnotation(entity, f, "Id") != null) {
|
|
54
|
+
ligne = ligne + " PRIMARY KEY"
|
|
55
|
+
}
|
|
56
|
+
defs = defs + ligne
|
|
57
|
+
}
|
|
58
|
+
return "CREATE TABLE IF NOT EXISTS " + this.tableName(entity) + " (" + defs + ")"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Crée la table dans la base à partir d'un exemple d'entité (modÚle décoré)
|
|
62
|
+
fun migrate(db: string, entity: any): string {
|
|
63
|
+
var sql = this.createTableSQL(entity)
|
|
64
|
+
DataImport.execSQL(db, sql, [])
|
|
65
|
+
return sql
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// ---------------------------------------------------------------------
|
|
70
|
+
// Repo â dĂ©pĂŽt de donnĂ©es gĂ©nĂ©rique pour un modĂšle
|
|
71
|
+
// ---------------------------------------------------------------------
|
|
72
|
+
class Repo {
|
|
73
|
+
var db: string
|
|
74
|
+
var table: string
|
|
75
|
+
var model: string
|
|
76
|
+
var schema: Schema
|
|
77
|
+
|
|
78
|
+
// `sample` : une instance du modÚle, utilisée pour lire les métadonnées
|
|
79
|
+
fun __construct(db: string, sample: any) {
|
|
80
|
+
this.db = db
|
|
81
|
+
this.schema = new Schema()
|
|
82
|
+
this.table = this.schema.tableName(sample)
|
|
83
|
+
this.model = Type.className(sample)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
fun save(entity: any): int {
|
|
87
|
+
var colonnes = ""
|
|
88
|
+
var marques = ""
|
|
89
|
+
var valeurs = []
|
|
90
|
+
for (f in Type.fields(entity)) {
|
|
91
|
+
if (colonnes != "") {
|
|
92
|
+
colonnes = colonnes + ", "
|
|
93
|
+
marques = marques + ", "
|
|
94
|
+
}
|
|
95
|
+
colonnes = colonnes + this.schema.columnName(entity, f)
|
|
96
|
+
marques = marques + "?"
|
|
97
|
+
valeurs = valeurs + [Type.get(entity, f)]
|
|
98
|
+
}
|
|
99
|
+
var sql = "INSERT INTO " + this.table + " (" + colonnes + ") VALUES (" + marques + ")"
|
|
100
|
+
return DataImport.execSQL(this.db, sql, valeurs)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Transforme les lignes SQL (colonnes) en instances du modĂšle (champs)
|
|
104
|
+
fun hydrate(lignes: any): any {
|
|
105
|
+
var objets = []
|
|
106
|
+
for (ligne in lignes) {
|
|
107
|
+
var obj = Type.create(this.model)
|
|
108
|
+
for (f in Type.fields(obj)) {
|
|
109
|
+
var col = this.schema.columnName(obj, f)
|
|
110
|
+
Type.set(obj, f, ligne[col])
|
|
111
|
+
}
|
|
112
|
+
objets = objets + [obj]
|
|
113
|
+
}
|
|
114
|
+
return objets
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
fun all(): any {
|
|
118
|
+
return this.hydrate(DataImport.execSQL(this.db, "SELECT * FROM " + this.table, []))
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
fun findBy(colonne: string, valeur: any): any {
|
|
122
|
+
var sql = "SELECT * FROM " + this.table + " WHERE " + colonne + " = ?"
|
|
123
|
+
return this.hydrate(DataImport.execSQL(this.db, sql, [valeur]))
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
fun remove(colonne: string, valeur: any): int {
|
|
127
|
+
var sql = "DELETE FROM " + this.table + " WHERE " + colonne + " = ?"
|
|
128
|
+
return DataImport.execSQL(this.db, sql, [valeur])
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ---------------------------------------------------------------------
|
|
133
|
+
// Query â constructeur de requĂȘtes fluide
|
|
134
|
+
// ---------------------------------------------------------------------
|
|
135
|
+
class Query {
|
|
136
|
+
var db: string
|
|
137
|
+
var table: string
|
|
138
|
+
var champs: string
|
|
139
|
+
var conds: string
|
|
140
|
+
var params: any
|
|
141
|
+
var ordre: string
|
|
142
|
+
|
|
143
|
+
fun __construct(db: string, table: string) {
|
|
144
|
+
this.db = db
|
|
145
|
+
this.table = table
|
|
146
|
+
this.champs = "*"
|
|
147
|
+
this.conds = ""
|
|
148
|
+
this.params = []
|
|
149
|
+
this.ordre = ""
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
fun select(champs: string): Query {
|
|
153
|
+
this.champs = champs
|
|
154
|
+
return this
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
fun where(colonne: string, op: string, valeur: any): Query {
|
|
158
|
+
if (this.conds != "") { this.conds = this.conds + " AND " }
|
|
159
|
+
this.conds = this.conds + colonne + " " + op + " ?"
|
|
160
|
+
this.params = this.params + [valeur]
|
|
161
|
+
return this
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
fun orderBy(colonne: string, sens: string): Query {
|
|
165
|
+
this.ordre = " ORDER BY " + colonne + " " + sens
|
|
166
|
+
return this
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
fun sql(): string {
|
|
170
|
+
var s = "SELECT " + this.champs + " FROM " + this.table
|
|
171
|
+
if (this.conds != "") { s = s + " WHERE " + this.conds }
|
|
172
|
+
s = s + this.ordre
|
|
173
|
+
return s
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
fun get(): any {
|
|
177
|
+
return DataImport.execSQL(this.db, this.sql(), this.params)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: oktopios-orm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: ORM pour le langage Oktopios â modeles decores, migrations, query-builder (facon Doctrine / Django ORM)
|
|
5
|
+
Author: Mouanwiya Ali Soule
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2025 Mouanwiya Ali Soule
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/ALISOULEMOUANWIYA/oktopios-orm
|
|
29
|
+
Project-URL: Language, https://pypi.org/project/oktopios/
|
|
30
|
+
Keywords: oktopios,orm,database,sqlite,migrations,okp
|
|
31
|
+
Requires-Python: >=3.8
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
License-File: LICENSE
|
|
34
|
+
Requires-Dist: oktopios>=0.7.0
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# oktopios-orm đđïž
|
|
38
|
+
|
|
39
|
+
ORM pour le langage **[Oktopios](https://pypi.org/project/oktopios/)** â dans
|
|
40
|
+
l'esprit de **Doctrine** (Symfony) et de l'**ORM de Django** : modÚles déclarés
|
|
41
|
+
par décorateurs, migrations automatiques, dépÎt générique et query-builder.
|
|
42
|
+
|
|
43
|
+
DeuxiÚme couche de l'écosystÚme :
|
|
44
|
+
**langage `oktopios` â `oktopios-orm` â `oktopios-framework`**.
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install oktopios-orm
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Cela installe aussi le langage `oktopios` (dépendance). Comme Django a besoin de
|
|
53
|
+
Python et Doctrine de PHP, `oktopios-orm` a besoin de l'interpréteur `oktopios`.
|
|
54
|
+
|
|
55
|
+
## Utilisation
|
|
56
|
+
|
|
57
|
+
Dans un fichier `.okp` :
|
|
58
|
+
|
|
59
|
+
```okp
|
|
60
|
+
use "oktopios_orm/orm.okp" // résolu depuis le paquet installé
|
|
61
|
+
inject Type
|
|
62
|
+
|
|
63
|
+
@Entity("articles")
|
|
64
|
+
class Article {
|
|
65
|
+
@Id
|
|
66
|
+
var id: int
|
|
67
|
+
@Column("titre")
|
|
68
|
+
var title: string
|
|
69
|
+
var vues: int
|
|
70
|
+
fun __construct(title: string, vues: int) {
|
|
71
|
+
this.title = title
|
|
72
|
+
this.vues = vues
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
var schema = new Schema()
|
|
77
|
+
var sample = new Article("", 0)
|
|
78
|
+
schema.migrate("blog.db", sample) // CREATE TABLE articles (id INTEGER PRIMARY KEY, titre TEXT, vues INTEGER)
|
|
79
|
+
|
|
80
|
+
var repo = new Repo("blog.db", sample)
|
|
81
|
+
var a = new Article("Bonjour", 100)
|
|
82
|
+
Type.set(a, "id", 1)
|
|
83
|
+
repo.save(a)
|
|
84
|
+
|
|
85
|
+
for (x in repo.all()) { print(x.title) }
|
|
86
|
+
|
|
87
|
+
var q = new Query("blog.db", "articles")
|
|
88
|
+
print(q.select("id, titre, vues").where("vues", ">", 50).orderBy("vues", "DESC").get())
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Exécuter : `okp examples/blog.okp`
|
|
92
|
+
|
|
93
|
+
## Contenu (`oktopios_orm/orm.okp`)
|
|
94
|
+
|
|
95
|
+
- **`Schema`** â migrations : gĂ©nĂšre le schĂ©ma SQL depuis les modĂšles dĂ©corĂ©s
|
|
96
|
+
(`@Entity`, `@Id`, `@Column`) ; mapping des types (`intâINTEGER`, `stringâTEXT`,
|
|
97
|
+
`floatâREAL`, `boolâINTEGER`).
|
|
98
|
+
- **`Repo`** â dĂ©pĂŽt gĂ©nĂ©rique : `save`, `all`, `findBy`, `remove`, hydratation
|
|
99
|
+
ligne â objet typĂ© (par rĂ©flexion).
|
|
100
|
+
- **`Query`** â constructeur de requĂȘtes fluide : `select().where().orderBy().get()`,
|
|
101
|
+
paramétré (anti-injection).
|
|
102
|
+
|
|
103
|
+
## Décorateurs reconnus
|
|
104
|
+
|
|
105
|
+
| Décorateur | Cible | Effet |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| `@Entity("table")` | classe | nom de la table |
|
|
108
|
+
| `@Column("colonne")` | champ | nom de la colonne |
|
|
109
|
+
| `@Id` | champ | clé primaire |
|
|
110
|
+
|
|
111
|
+
## Licence
|
|
112
|
+
|
|
113
|
+
MIT © Mouanwiya Ali Soule
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
oktopios_orm/__init__.py
|
|
5
|
+
oktopios_orm/orm.okp
|
|
6
|
+
oktopios_orm.egg-info/PKG-INFO
|
|
7
|
+
oktopios_orm.egg-info/SOURCES.txt
|
|
8
|
+
oktopios_orm.egg-info/dependency_links.txt
|
|
9
|
+
oktopios_orm.egg-info/requires.txt
|
|
10
|
+
oktopios_orm.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oktopios>=0.7.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
oktopios_orm
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "oktopios-orm"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "ORM pour le langage Oktopios â modeles decores, migrations, query-builder (facon Doctrine / Django ORM)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { file = "LICENSE" }
|
|
11
|
+
requires-python = ">=3.8"
|
|
12
|
+
authors = [{ name = "Mouanwiya Ali Soule" }]
|
|
13
|
+
keywords = ["oktopios", "orm", "database", "sqlite", "migrations", "okp"]
|
|
14
|
+
dependencies = ["oktopios>=0.7.0"]
|
|
15
|
+
|
|
16
|
+
[project.urls]
|
|
17
|
+
Homepage = "https://github.com/ALISOULEMOUANWIYA/oktopios-orm"
|
|
18
|
+
Language = "https://pypi.org/project/oktopios/"
|
|
19
|
+
|
|
20
|
+
[tool.setuptools.packages.find]
|
|
21
|
+
include = ["oktopios_orm*"]
|
|
22
|
+
|
|
23
|
+
[tool.setuptools.package-data]
|
|
24
|
+
"oktopios_orm" = ["*.okp"]
|