1- /* eslint-disable @typescript-eslint/no-unused-vars */
21/* eslint-disable no-console */
32import { Operator } from '@samhuk/data-filter/dist/types'
43import { SortingDirection } from '@samhuk/data-query/dist/sorting/types'
54import * as fs from 'fs'
65import path from 'path'
76import { createConsoleLogEventHandlers } from 'simple-pg-client'
8- import { createTsPgOrm } from '../..'
9- import { createDataFormatDeclaration } from '../../dataFormat'
10- import { BASE_ENTITY_FIELDS , COMMON_FIELDS } from '../../dataFormat/common'
11- import { StringDataSubType , NumberDataSubType , DataType , CreateRecordOptions } from '../../dataFormat/types'
12- import { RelationType } from '../../relations/types'
13- import { _CreateJoinTableRecordOptions } from '../../store/joinTable/types'
14- import { StoresAndJoinTableStoresDict } from '../../types'
15-
16- const USER_DFD = createDataFormatDeclaration ( {
17- name : 'user' ,
18- fields : [
19- ...BASE_ENTITY_FIELDS ,
20- COMMON_FIELDS . name50 ,
21- { name : 'email' , dataType : DataType . STRING , dataSubType : StringDataSubType . VARYING_LENGTH , maxLength : 100 } ,
22- { name : 'passwordHash' , dataType : DataType . STRING , dataSubType : StringDataSubType . FIXED_LENGTH , length : 64 } ,
23- ] ,
24- } as const )
25-
26- const ARTICLE_DFD = createDataFormatDeclaration ( {
27- name : 'article' ,
28- fields : [
29- ...BASE_ENTITY_FIELDS ,
30- { name : 'title' , dataType : DataType . STRING , dataSubType : StringDataSubType . VARYING_LENGTH , maxLength : 100 } ,
31- { name : 'creatorUserId' , dataType : DataType . NUMBER , dataSubType : NumberDataSubType . INTEGER } ,
32- { name : 'thumbnailImageId' , dataType : DataType . NUMBER , dataSubType : NumberDataSubType . INTEGER } ,
33- ] ,
34- } as const )
35-
36- const IMAGE_DFD = createDataFormatDeclaration ( {
37- name : 'image' ,
38- fields : [
39- ...BASE_ENTITY_FIELDS ,
40- { name : 'fileName' , dataType : DataType . STRING , dataSubType : StringDataSubType . VARYING_LENGTH , maxLength : 200 } ,
41- { name : 'creatorUserId' , dataType : DataType . NUMBER , dataSubType : NumberDataSubType . INTEGER } ,
42- ] ,
43- } as const )
44-
45- const USER_ADDRESS_DFD = createDataFormatDeclaration ( {
46- name : 'userAddress' ,
47- fields : [
48- ...BASE_ENTITY_FIELDS ,
49- { name : 'userId' , dataType : DataType . NUMBER , dataSubType : NumberDataSubType . INTEGER } ,
50- { name : 'postCode' , dataType : DataType . STRING , dataSubType : StringDataSubType . VARYING_LENGTH , maxLength : 10 } ,
51- { name : 'streetAddress' , dataType : DataType . STRING , dataSubType : StringDataSubType . VARYING_LENGTH , maxLength : 200 } ,
52- { name : 'city' , dataType : DataType . STRING , dataSubType : StringDataSubType . VARYING_LENGTH , maxLength : 100 } ,
53- { name : 'country' , dataType : DataType . STRING , dataSubType : StringDataSubType . VARYING_LENGTH , maxLength : 100 } ,
54- ] ,
55- } as const )
56-
57- const USER_GROUP_DFD = createDataFormatDeclaration ( {
58- name : 'userGroup' ,
59- fields : [
60- ...BASE_ENTITY_FIELDS ,
61- { name : 'name' , dataType : DataType . STRING , dataSubType : StringDataSubType . VARYING_LENGTH , maxLength : 100 } ,
62- { name : 'description' , dataType : DataType . STRING , dataSubType : StringDataSubType . VARYING_LENGTH , maxLength : 300 , allowNull : true } ,
63- { name : 'imageId' , dataType : DataType . NUMBER , dataSubType : NumberDataSubType . INTEGER , allowNull : true } ,
64- ] ,
65- } as const )
66-
67- const ORM = createTsPgOrm ( )
68- . loadDataFormats ( [ USER_DFD , IMAGE_DFD , ARTICLE_DFD , USER_ADDRESS_DFD , USER_GROUP_DFD ] as const )
69- . loadRelations ( dfs => [
70- {
71- type : RelationType . ONE_TO_MANY ,
72- fromOneField : dfs . user . fieldRefs . id ,
73- toManyField : dfs . article . fieldRefs . creatorUserId ,
74- } ,
75- {
76- type : RelationType . ONE_TO_MANY ,
77- fromOneField : dfs . image . fieldRefs . id ,
78- toManyField : dfs . article . fieldRefs . thumbnailImageId ,
79- } ,
80- {
81- type : RelationType . ONE_TO_MANY ,
82- fromOneField : dfs . user . fieldRefs . id ,
83- toManyField : dfs . image . fieldRefs . creatorUserId ,
84- } ,
85- {
86- type : RelationType . ONE_TO_ONE ,
87- fromOneField : dfs . user . fieldRefs . id ,
88- toOneField : dfs . userAddress . fieldRefs . userId ,
89- } ,
90- {
91- type : RelationType . MANY_TO_MANY ,
92- fieldRef1 : dfs . user . fieldRefs . id ,
93- fieldRef2 : dfs . userGroup . fieldRefs . id ,
94- includeDateCreated : true ,
95- } ,
96- ] as const )
97-
98- type Stores = StoresAndJoinTableStoresDict < typeof ORM [ 'dataFormatDeclarations' ] , typeof ORM [ 'relationDeclarations' ] >
99-
100- type CreateUserRecordOptions = CreateRecordOptions < typeof USER_DFD >
101-
102- type CreateImageRecordOptions = CreateRecordOptions < typeof IMAGE_DFD >
103-
104- type CreateArticleRecordOptions = CreateRecordOptions < typeof ARTICLE_DFD >
105-
106- type CreateUserAddressRecordOptions = CreateRecordOptions < typeof USER_ADDRESS_DFD >
107-
108- type CreateUserGroupRecordOptions = CreateRecordOptions < typeof USER_GROUP_DFD >
109-
110- type CreateUserToUserGroupLinkOptions = _CreateJoinTableRecordOptions <
111- typeof ORM [ 'dataFormatDeclarations' ] ,
112- typeof ORM [ 'relations' ] [ 'user.id <<-->> userGroup.id' ]
113- >
7+ import { addData } from './data'
8+ import { ORM , Stores } from './orm'
1149
11510const provision = async ( ) : Promise < Stores > => {
11611 await ORM . initDbClient ( {
@@ -134,56 +29,12 @@ const provision = async (): Promise<Stores> => {
13429 return stores
13530}
13631
137- const addData = async ( stores : Stores ) => {
138- // Add users
139- const createUserRecordsOptions : CreateUserRecordOptions [ ] = [
140- { name : 'user 1' , email : 'user1@email.com' , passwordHash : '123' } ,
141- { name : 'user 2' , email : 'user2@email.com' , passwordHash : '456' } ,
142- { name : 'user 3' , email : 'user3@email.com' , passwordHash : '789' } ,
143- ]
144- await Promise . all ( createUserRecordsOptions . map ( stores . user . create ) )
145-
146- // Add images
147- const createImageRecordsOptions : CreateImageRecordOptions [ ] = [
148- { fileName : 'funnydog.png' , creatorUserId : 1 } ,
149- { fileName : 'funnycat.png' , creatorUserId : 2 } ,
150- { fileName : 'user3avatar.png' , creatorUserId : 3 } ,
151- ]
152- await Promise . all ( createImageRecordsOptions . map ( stores . image . create ) )
153-
154- // Add articles
155- const createArticleRecordsOptions : CreateArticleRecordOptions [ ] = [
156- { title : 'Here is a funny dog!' , creatorUserId : 3 , thumbnailImageId : 1 } ,
157- { title : 'Here is a funny cat!' , creatorUserId : 3 , thumbnailImageId : 2 } ,
158- { title : 'I am User 3' , creatorUserId : 3 , thumbnailImageId : 3 } ,
159- ]
160- await Promise . all ( createArticleRecordsOptions . map ( stores . article . create ) )
161-
162- // Add user addresses
163- const createUserAddressRecordsOptions : CreateUserAddressRecordOptions [ ] = [
164- { userId : 1 , city : 'London' , country : 'UK' , postCode : 'SE11 119' , streetAddress : '1 FooStreet Lane' } ,
165- { userId : 2 , city : 'Madrid' , country : 'Spain' , postCode : 'BON BON' , streetAddress : '2 FooStreet Lane' } ,
166- { userId : 3 , city : 'Paris' , country : 'France' , postCode : 'SUI SUI' , streetAddress : '3 FooStreet Lane' } ,
167- ]
168- await Promise . all ( createUserAddressRecordsOptions . map ( stores . userAddress . create ) )
169-
170- // Add user groups
171- const createUserGroupRecordsOptions : CreateUserGroupRecordOptions [ ] = [
172- { name : 'User group 1' } ,
173- { name : 'User group 2' } ,
174- { name : 'User group 3' } ,
175- ]
176- await Promise . all ( createUserGroupRecordsOptions . map ( stores . userGroup . create ) )
177-
178- const createUserToUserGroupLinkOptions : CreateUserToUserGroupLinkOptions [ ] = [
179- { userId : 1 , userGroupId : 1 } ,
180- { userId : 2 , userGroupId : 2 } ,
181- { userId : 3 , userGroupId : 3 } ,
182- ]
183- await Promise . all ( createUserToUserGroupLinkOptions . map ( stores [ 'user.id <<-->> userGroup.id' ] . create ) )
184- }
185-
18632const getResult = ( stores : Stores ) => (
33+ /* E.g.:
34+ * Get all undeleted users sorted by newest to oldest, and each
35+ * with all of their uploaded articles and images, and each of those
36+ * articles with it's image.
37+ */
18738 stores . user . getMultiple ( {
18839 fields : [ 'uuid' , 'name' , 'email' , 'dateCreated' ] ,
18940 query : {
@@ -241,14 +92,15 @@ const init = async () => {
24192 const result1 = await timedFn ( ( ) => getResult ( stores ) , 'query' )
24293 fs . writeFileSync ( path . resolve ( outputDir , 'articles-query.json' ) , JSON . stringify ( result1 . result , null , 2 ) )
24394
95+ // many-to-many
24496 const result2 = await timedFn ( ( ) => stores . user . getMultiple ( {
245- fields : [ ] ,
97+ fields : [ 'name' ] ,
24698 relations : { userGroups : { } } ,
24799 } ) , 'query' )
248100 fs . writeFileSync ( path . resolve ( outputDir , 'user-user-groups-query.json' ) , JSON . stringify ( result2 . result , null , 2 ) )
249101
250102 const result3 = await timedFn ( ( ) => stores . user . getMultiple ( {
251- fields : [ ] ,
103+ fields : [ 'name' ] ,
252104 relations : {
253105 userGroups : {
254106 query : {
0 commit comments