Skip to content

Commit d33735d

Browse files
committed
Add search type
1 parent 5f9fcdc commit d33735d

File tree

35 files changed

+1352
-252
lines changed

35 files changed

+1352
-252
lines changed

Cargo.lock

Lines changed: 35 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

__tests__/sql/index.test.ts

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import 'reflect-metadata'
22

3-
import { Column, Func, Model } from '@devup-api/model'
4-
import {
5-
createRevision,
6-
createSqliteConnection,
7-
migrate,
8-
} from '@devup-sql/sqlite'
3+
import { Column, DevupModel, Func, Model } from '@devup-api/model'
4+
import { createSqliteConnection } from '@devup-sql/sqlite'
95
describe('sqlite', async () => {
106
const pool = await createSqliteConnection({
117
url: 'sqlite::memory:',
@@ -41,7 +37,7 @@ describe('sqlite', async () => {
4137
})
4238
describe('model', () => {
4339
@Model()
44-
class User {
40+
class User extends DevupModel {
4541
@Column({
4642
name: 'id',
4743
primaryKey: true,
@@ -67,20 +63,34 @@ describe('sqlite', async () => {
6763
createdAt: Date
6864
}
6965
it('test', async () => {
70-
const revisions = await loadRevisions()
71-
// create next revision from revision
72-
const nextRevisions = await createRevision(revisions)
73-
const currentRevision = await currentRevision(pool)
74-
// apply sql script
75-
const sql = getSqlFromRevision(revisions[0])
76-
await migrate(pool, nextRevisions)
66+
// get current revision
67+
const currentRevision = await pool.getCurrentRevision()
68+
// create revision
69+
const nextRevision = await pool.createRevision()
70+
// migrate to next revision
71+
await pool.migrate(nextRevision)
7772

78-
const user = new User()
79-
user.username = 'devup'
80-
await user.save()
73+
// const user = new User()
74+
// user.username = 'devup'
75+
// await user.save()
8176

82-
const user = await User.findById(1)
83-
expect(user?.username).toEqual('devup')
77+
// const user = await User.findById(1)
78+
// expect(user?.username).toEqual('devup')
79+
80+
const user = await User.findOne({
81+
filter: {},
82+
})
83+
84+
const users = await User.findAll({
85+
filter: {
86+
username: 'devup',
87+
},
88+
limit: 10,
89+
offset: 0,
90+
order: {
91+
id: 'ASC',
92+
},
93+
})
8494

8595
expect(0).toEqual(0)
8696
})

core/model/src/column.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,12 @@ pub struct DevupModelColumn {
6868
pub default: Option<DevupModelColumnDefault>,
6969
pub nullable: bool,
7070
pub primary_key: bool,
71-
pub foreign_key: Option<String>,
72-
pub unique: Option<DevupModelColumnUnique>,
73-
pub index: Option<DevupModelColumnIndex>,
71+
// multiple foreign key
72+
pub foreign_key: Option<Vec<String>>,
73+
// multiple unique
74+
pub unique: Option<Vec<DevupModelColumnUnique>>,
75+
// multiple index
76+
pub index: Option<Vec<DevupModelColumnIndex>>,
7477
pub auto_increment: bool,
7578
pub comment: Option<String>,
7679
pub dto: Option<DevupModelColumnDtoOption>,

core/model/src/utils.rs

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,25 @@ pub fn find_foreign_key_target(
1818
for field in &model.fields {
1919
if let DevupModelFieldType::Column(column) = field {
2020
if let Some(foreign_key) = &column.foreign_key {
21-
if let Some(relation) = &rel.field {
22-
if column.name != relation.clone() {
23-
continue;
21+
for foreign_key in foreign_key {
22+
if let Some(relation) = &rel.field {
23+
if column.name != relation.clone() {
24+
continue;
25+
}
26+
return Ok(FindForeignKeyTargetResult {
27+
field: column.name.clone(),
28+
foreign_key: foreign_key.clone(),
29+
});
2430
}
25-
return Ok(FindForeignKeyTargetResult {
26-
field: column.name.clone(),
27-
foreign_key: foreign_key.clone(),
28-
});
29-
}
30-
if column.name.starts_with(rel.name.as_str()) {
31-
if ret.is_some() {
32-
return Err("Multiple foreign keys found".into());
31+
if column.name.starts_with(rel.name.as_str()) {
32+
if ret.is_some() {
33+
return Err("Multiple foreign keys found".into());
34+
}
35+
ret = Some(FindForeignKeyTargetResult {
36+
field: column.name.clone(),
37+
foreign_key: foreign_key.clone(),
38+
});
3339
}
34-
ret = Some(FindForeignKeyTargetResult {
35-
field: column.name.clone(),
36-
foreign_key: foreign_key.clone(),
37-
});
3840
}
3941
}
4042
}

libs/node/model/Cargo.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
[package]
22
edition = "2024"
3-
name = "devup-api-node-model"
3+
name = "devup_api_node_model"
44
version = "0.0.0"
55

66
[lib]
77
crate-type = ["cdylib"]
88

99
[dependencies]
1010
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
11-
napi = { version = "2.12.2", default-features = false, features = ["napi5", "serde-json"] }
11+
napi = { version = "2.12.2", default-features = false, features = [
12+
"napi5",
13+
"serde-json",
14+
] }
1215
napi-derive = "2.12.2"
1316
serde = { version = "1.0.219", features = ["derive"] }
17+
serde_json = "1.0.140"
1418
model = { path = "../../../core/model" }
1519
schema = { path = "../../../core/schema" }
20+
devup_node_struct = { path = "../struct" }
1621
[build-dependencies]
1722
napi-build = "2.0.1"

libs/node/model/index.d.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,31 @@ export interface JsDevupModelColumn {
3434
export declare function Column(options?: JsDevupModelColumn | undefined | null): (...args: any[]) => any
3535
/** Model decorator */
3636
export declare function Model(name?: string | undefined | null): (...args: any[]) => any
37+
export interface JsDevupModelColumn {
38+
name: string
39+
type: JsDevupModelColumnType
40+
default: Func | string | boolean | number | null | (() => string | number | boolean | null)
41+
nullable: boolean
42+
primaryKey: boolean
43+
autoIncrement: boolean
44+
foreignKey?: unknown
45+
unique?: string | boolean | string[]
46+
index?: string | boolean | string[]
47+
comment?: string
48+
}
49+
export interface JsDevupModelColumnOptions {
50+
name?: string
51+
type?: JsDevupModelColumnType
52+
default?: Func | string | boolean | number | null | (() => string | number | boolean | null)
53+
nullable?: boolean
54+
primaryKey?: boolean
55+
autoIncrement?: boolean
56+
foreignKey?: string | string[]
57+
unique?: string | boolean | string[]
58+
index?: string | boolean | string[]
59+
comment?: string
60+
}
61+
export declare function Column(options?: JsDevupModelColumnOptions | undefined | null): (...args: any[]) => any
3762
export type JsFunc = Func
3863
export declare class Func {
3964
value: string

libs/node/model/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,10 @@ if (!nativeBinding) {
310310
throw new Error(`Failed to load native binding`)
311311
}
312312

313-
const { JsDevupModelColumnType, Column, Func, Model } = nativeBinding
313+
const { JsDevupModelColumnType, Column, Func, Model, Column } = nativeBinding
314314

315315
module.exports.JsDevupModelColumnType = JsDevupModelColumnType
316316
module.exports.Column = Column
317317
module.exports.Func = Func
318318
module.exports.Model = Model
319+
module.exports.Column = Column

libs/node/model/main.d.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
export * from './index'
2+
export class DevupModel {
3+
save(): Promise<void> {
4+
throw new Error('Method not implemented.')
5+
}
6+
7+
static findById<T, I extends InstanceType<T>>(
8+
this: T,
9+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
10+
id: number,
11+
): Promise<I> {
12+
throw new Error('Method not implemented.')
13+
}
14+
15+
static findAll<T, I extends InstanceType<T>>(
16+
this: T,
17+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
18+
options: DeepPartial<FindOptions<I>>,
19+
): Promise<I[]> {
20+
throw new Error('Method not implemented.')
21+
}
22+
23+
static findOne<T, I extends InstanceType<T>>(
24+
this: T,
25+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
26+
options: DeepPartial<FilterOptions<I>>,
27+
): Promise<I> {
28+
throw new Error('Method not implemented.')
29+
}
30+
}
31+
32+
type FilterOptions<T> = {
33+
filter: { [key in ExtractFieldKeys<T>]: T[key] }
34+
}
35+
36+
type FindOptions<T> = FilterOptions<T> & {
37+
limit: number
38+
offset: number
39+
order: { [key in ExtractFieldKeys<T>]: 'ASC' | 'DESC' }
40+
}
41+
42+
type InstanceType<T> = T extends new (...args: any[]) => infer R ? R : never
43+
type DeepPartial<T> = {
44+
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]
45+
}
46+
47+
// if T[P] is function, exclude it
48+
type ExtractFieldKeys<T> = keyof {
49+
[P in keyof T as T[P] extends (...args: any[]) => any ? never : P]: never
50+
}

libs/node/model/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "@devup-api/model",
33
"version": "0.0.0",
44
"main": "index.js",
5-
"types": "index.d.ts",
5+
"types": "main.d.ts",
66
"napi": {
77
"name": "model",
88
"triples": {}

0 commit comments

Comments
 (0)