@@ -2,7 +2,7 @@ import type { ColumnBuilderBaseConfig, ColumnBuilderRuntimeConfig, MakeColumnCon
2
2
import type { ColumnBaseConfig } from '~/column.ts' ;
3
3
import { entityKind } from '~/entity.ts' ;
4
4
import type { AnyMySqlTable } from '~/mysql-core/table.ts' ;
5
- import { getColumnNameAndConfig } from '~/utils.ts' ;
5
+ import { type Equal , getColumnNameAndConfig } from '~/utils.ts' ;
6
6
import { MySqlColumnBuilderWithAutoIncrement , MySqlColumnWithAutoIncrement } from './common.ts' ;
7
7
8
8
export type MySqlDecimalBuilderInitial < TName extends string > = MySqlDecimalBuilder < {
@@ -67,21 +67,153 @@ export class MySqlDecimal<T extends ColumnBaseConfig<'string', 'MySqlDecimal'>>
67
67
}
68
68
}
69
69
70
- export interface MySqlDecimalConfig {
70
+ export type MySqlDecimalNumberBuilderInitial < TName extends string > = MySqlDecimalNumberBuilder < {
71
+ name : TName ;
72
+ dataType : 'number' ;
73
+ columnType : 'MySqlDecimalNumber' ;
74
+ data : number ;
75
+ driverParam : string ;
76
+ enumValues : undefined ;
77
+ } > ;
78
+
79
+ export class MySqlDecimalNumberBuilder <
80
+ T extends ColumnBuilderBaseConfig < 'number' , 'MySqlDecimalNumber' > ,
81
+ > extends MySqlColumnBuilderWithAutoIncrement < T , MySqlDecimalConfig > {
82
+ static override readonly [ entityKind ] : string = 'MySqlDecimalNumberBuilder' ;
83
+
84
+ constructor ( name : T [ 'name' ] , config : MySqlDecimalConfig | undefined ) {
85
+ super ( name , 'number' , 'MySqlDecimalNumber' ) ;
86
+ this . config . precision = config ?. precision ;
87
+ this . config . scale = config ?. scale ;
88
+ this . config . unsigned = config ?. unsigned ;
89
+ }
90
+
91
+ /** @internal */
92
+ override build < TTableName extends string > (
93
+ table : AnyMySqlTable < { name : TTableName } > ,
94
+ ) : MySqlDecimalNumber < MakeColumnConfig < T , TTableName > > {
95
+ return new MySqlDecimalNumber < MakeColumnConfig < T , TTableName > > (
96
+ table ,
97
+ this . config as ColumnBuilderRuntimeConfig < any , any > ,
98
+ ) ;
99
+ }
100
+ }
101
+
102
+ export class MySqlDecimalNumber < T extends ColumnBaseConfig < 'number' , 'MySqlDecimalNumber' > >
103
+ extends MySqlColumnWithAutoIncrement < T , MySqlDecimalConfig >
104
+ {
105
+ static override readonly [ entityKind ] : string = 'MySqlDecimalNumber' ;
106
+
107
+ readonly precision : number | undefined = this . config . precision ;
108
+ readonly scale : number | undefined = this . config . scale ;
109
+ readonly unsigned : boolean | undefined = this . config . unsigned ;
110
+
111
+ override mapFromDriverValue ( value : unknown ) : number {
112
+ if ( typeof value === 'number' ) return value ;
113
+
114
+ return Number ( value ) ;
115
+ }
116
+
117
+ override mapToDriverValue = String ;
118
+
119
+ getSQLType ( ) : string {
120
+ let type = '' ;
121
+ if ( this . precision !== undefined && this . scale !== undefined ) {
122
+ type += `decimal(${ this . precision } ,${ this . scale } )` ;
123
+ } else if ( this . precision === undefined ) {
124
+ type += 'decimal' ;
125
+ } else {
126
+ type += `decimal(${ this . precision } )` ;
127
+ }
128
+ type = type === 'decimal(10,0)' || type === 'decimal(10)' ? 'decimal' : type ;
129
+ return this . unsigned ? `${ type } unsigned` : type ;
130
+ }
131
+ }
132
+
133
+ export type MySqlDecimalBigIntBuilderInitial < TName extends string > = MySqlDecimalBigIntBuilder < {
134
+ name : TName ;
135
+ dataType : 'bigint' ;
136
+ columnType : 'MySqlDecimalBigInt' ;
137
+ data : bigint ;
138
+ driverParam : string ;
139
+ enumValues : undefined ;
140
+ } > ;
141
+
142
+ export class MySqlDecimalBigIntBuilder <
143
+ T extends ColumnBuilderBaseConfig < 'bigint' , 'MySqlDecimalBigInt' > ,
144
+ > extends MySqlColumnBuilderWithAutoIncrement < T , MySqlDecimalConfig > {
145
+ static override readonly [ entityKind ] : string = 'MySqlDecimalBigIntBuilder' ;
146
+
147
+ constructor ( name : T [ 'name' ] , config : MySqlDecimalConfig | undefined ) {
148
+ super ( name , 'bigint' , 'MySqlDecimalBigInt' ) ;
149
+ this . config . precision = config ?. precision ;
150
+ this . config . scale = config ?. scale ;
151
+ this . config . unsigned = config ?. unsigned ;
152
+ }
153
+
154
+ /** @internal */
155
+ override build < TTableName extends string > (
156
+ table : AnyMySqlTable < { name : TTableName } > ,
157
+ ) : MySqlDecimalBigInt < MakeColumnConfig < T , TTableName > > {
158
+ return new MySqlDecimalBigInt < MakeColumnConfig < T , TTableName > > (
159
+ table ,
160
+ this . config as ColumnBuilderRuntimeConfig < any , any > ,
161
+ ) ;
162
+ }
163
+ }
164
+
165
+ export class MySqlDecimalBigInt < T extends ColumnBaseConfig < 'bigint' , 'MySqlDecimalBigInt' > >
166
+ extends MySqlColumnWithAutoIncrement < T , MySqlDecimalConfig >
167
+ {
168
+ static override readonly [ entityKind ] : string = 'MySqlDecimalBigInt' ;
169
+
170
+ readonly precision : number | undefined = this . config . precision ;
171
+ readonly scale : number | undefined = this . config . scale ;
172
+ readonly unsigned : boolean | undefined = this . config . unsigned ;
173
+
174
+ override mapFromDriverValue = BigInt ;
175
+
176
+ override mapToDriverValue = String ;
177
+
178
+ getSQLType ( ) : string {
179
+ let type = '' ;
180
+ if ( this . precision !== undefined && this . scale !== undefined ) {
181
+ type += `decimal(${ this . precision } ,${ this . scale } )` ;
182
+ } else if ( this . precision === undefined ) {
183
+ type += 'decimal' ;
184
+ } else {
185
+ type += `decimal(${ this . precision } )` ;
186
+ }
187
+ type = type === 'decimal(10,0)' || type === 'decimal(10)' ? 'decimal' : type ;
188
+ return this . unsigned ? `${ type } unsigned` : type ;
189
+ }
190
+ }
191
+
192
+ export interface MySqlDecimalConfig < T extends 'string' | 'number' | 'bigint' = 'string' | 'number' | 'bigint' > {
71
193
precision ?: number ;
72
194
scale ?: number ;
73
195
unsigned ?: boolean ;
196
+ mode ?: T ;
74
197
}
75
198
76
199
export function decimal ( ) : MySqlDecimalBuilderInitial < '' > ;
77
- export function decimal (
78
- config : MySqlDecimalConfig ,
79
- ) : MySqlDecimalBuilderInitial < '' > ;
80
- export function decimal < TName extends string > (
200
+ export function decimal < TMode extends 'string' | 'number' | 'bigint' > (
201
+ config : MySqlDecimalConfig < TMode > ,
202
+ ) : Equal < TMode , 'number' > extends true ? MySqlDecimalNumberBuilderInitial < '' >
203
+ : Equal < TMode , 'bigint' > extends true ? MySqlDecimalBigIntBuilderInitial < '' >
204
+ : MySqlDecimalBuilderInitial < '' > ;
205
+ export function decimal < TName extends string , TMode extends 'string' | 'number' | 'bigint' > (
81
206
name : TName ,
82
- config ?: MySqlDecimalConfig ,
83
- ) : MySqlDecimalBuilderInitial < TName > ;
207
+ config ?: MySqlDecimalConfig < TMode > ,
208
+ ) : Equal < TMode , 'number' > extends true ? MySqlDecimalNumberBuilderInitial < TName >
209
+ : Equal < TMode , 'bigint' > extends true ? MySqlDecimalBigIntBuilderInitial < TName >
210
+ : MySqlDecimalBuilderInitial < TName > ;
84
211
export function decimal ( a ?: string | MySqlDecimalConfig , b : MySqlDecimalConfig = { } ) {
85
212
const { name, config } = getColumnNameAndConfig < MySqlDecimalConfig > ( a , b ) ;
86
- return new MySqlDecimalBuilder ( name , config ) ;
213
+ const mode = config ?. mode ;
214
+ return mode === 'number'
215
+ ? new MySqlDecimalNumberBuilder ( name , config )
216
+ : mode === 'bigint'
217
+ ? new MySqlDecimalBigIntBuilder ( name , config )
218
+ : new MySqlDecimalBuilder ( name , config ) ;
87
219
}
0 commit comments