1
1
/* eslint-disable no-use-before-define */
2
2
3
3
import { CreationOptional , DataTypes , InferAttributes , InferCreationAttributes , Model } from 'sequelize' ;
4
- import { postgreSequelize , shouldAlterTable } from '@/db/postgres' ;
4
+ import { v6 as UUIDv6 } from 'uuid' ;
5
+ import { postgreSequelize } from '@/db/postgres' ;
6
+ import { isUUIDv6 } from '@/utils' ;
5
7
import { CarBrandModel } from './car-brand' ;
6
8
7
9
export enum CarColors {
@@ -26,6 +28,16 @@ export enum CarColors {
26
28
export type CarModelAttributes = InferAttributes < CarModel > ;
27
29
export type CarModelCreationAttributes = InferCreationAttributes < CarModel > ;
28
30
31
+ /**
32
+ * Always create and modify tables using migration scripts instead of
33
+ * calling the createTable method, because everytime you restart the
34
+ * server, the same index will be called multiple times, which will
35
+ * eventually give you "Too many keys specified; max 64 keys allowed"
36
+ * error.
37
+ *
38
+ * Migrations can be easily replicated on different environments and should
39
+ * be the preferred way of creating and managing tables.
40
+ */
29
41
class CarModel extends Model < CarModelAttributes , CarModelCreationAttributes > {
30
42
declare id : CreationOptional < string > ;
31
43
name ! : string ;
@@ -44,9 +56,25 @@ class CarModel extends Model<CarModelAttributes, CarModelCreationAttributes> {
44
56
CarModel . init (
45
57
{
46
58
id : {
59
+ /**
60
+ * FYI UUIDv6 must be used instead of v4, as v6 is
61
+ * Timestamp-based + random whereas v4 is fully random,
62
+ * thus its better used for indexing. Previously it was
63
+ * DataTypes.UUIDV4.
64
+ *
65
+ * Also use DataTypes.UUID only instead of DataTypes.STRING as
66
+ * the former is lighter and faster in indexing.
67
+ */
47
68
type : DataTypes . UUID ,
48
- defaultValue : DataTypes . UUIDV4 ,
49
- primaryKey : true
69
+ defaultValue : ( ) => UUIDv6 ( ) ,
70
+ primaryKey : true ,
71
+ validate : {
72
+ isuuidV6 ( value : string ) {
73
+ if ( ! isUUIDv6 ( value ) ) {
74
+ throw new Error ( 'Invalid UUID v6 format.' ) ;
75
+ }
76
+ }
77
+ }
50
78
} ,
51
79
name : {
52
80
type : DataTypes . STRING ,
@@ -108,21 +136,30 @@ CarModel.init(
108
136
) ;
109
137
} ,
110
138
} ,
111
- created_at : DataTypes . DATE ,
112
- updated_at : DataTypes . DATE ,
139
+ created_at : {
140
+ type : DataTypes . DATE ,
141
+ allowNull : false ,
142
+ defaultValue : DataTypes . NOW ,
143
+ } ,
144
+ updated_at : {
145
+ type : DataTypes . DATE ,
146
+ allowNull : false ,
147
+ defaultValue : DataTypes . NOW ,
148
+ }
113
149
} ,
114
150
{
115
151
sequelize : postgreSequelize ,
116
152
/**
117
153
* This will prevent the auto-pluralization performed by Sequelize,
118
154
* ie. the table name will be equal to the model name, without
119
155
* any modifications
156
+ *
157
+ * freezeTableName: true,
120
158
*/
121
- freezeTableName : true ,
159
+ timestamps : true ,
122
160
createdAt : 'created_at' ,
123
161
updatedAt : 'updated_at' ,
124
162
modelName : 'car' ,
125
- timestamps : true ,
126
163
/**
127
164
* Sequelize provides paranoid tables which soft deletes a record
128
165
* by inserting deletedAt timestamp. Timestamps must be enabled to
@@ -157,7 +194,10 @@ CarModel.init(
157
194
}
158
195
) ;
159
196
160
- /* Define the relationship between CarModel and CarBrandModel using optional aliases */
197
+ /**
198
+ * Define the relationship between CarModel and CarBrandModel
199
+ * using optional aliases
200
+ */
161
201
CarModel . belongsTo ( CarBrandModel , {
162
202
foreignKey : 'brand_id' ,
163
203
as : 'brand' ,
@@ -167,7 +207,7 @@ CarModel.belongsTo(CarBrandModel, {
167
207
168
208
CarBrandModel . hasMany ( CarModel , {
169
209
foreignKey : 'brand_id' ,
170
- as : 'cars ' ,
210
+ as : 'carModels ' ,
171
211
} ) ;
172
212
173
213
@@ -176,12 +216,9 @@ CarBrandModel.hasMany(CarModel, {
176
216
* if it exists. The former option will drop the table while the
177
217
* latter performs the necessary changes in the table to make it
178
218
* match the model.
219
+ *
220
+ * await CarModel.sync({ alter: shouldAlterTable });
179
221
*/
180
- async function createTable ( ) {
181
- await CarModel . sync ( { alter : shouldAlterTable } ) ;
182
- }
183
-
184
- createTable ( ) ;
185
222
186
223
export { CarModel } ;
187
224
0 commit comments