github.com/aacfactory/fns-contrib/databases/sql@v1.2.84/dac/specifications/values.go (about) 1 package specifications 2 3 import ( 4 "bytes" 5 "context" 6 stdsql "database/sql" 7 "fmt" 8 "github.com/aacfactory/errors" 9 "github.com/aacfactory/fns-contrib/databases/sql" 10 "github.com/aacfactory/fns/commons/times" 11 "github.com/aacfactory/json" 12 "reflect" 13 "time" 14 ) 15 16 func ScanRows[T any](ctx context.Context, rows sql.Rows, fields []string) (entries []T, err error) { 17 spec, specErr := GetSpecification(ctx, Instance[T]()) 18 if specErr != nil { 19 err = specErr 20 return 21 } 22 for rows.Next() { 23 generics := acquireGenerics(len(fields)) 24 scanErr := rows.Scan(generics...) 25 if scanErr != nil { 26 releaseGenerics(generics) 27 err = scanErr 28 return 29 } 30 entry := Instance[T]() 31 writeErr := generics.WriteTo(spec, fields, &entry) 32 releaseGenerics(generics) 33 if writeErr != nil { 34 err = scanErr 35 return 36 } 37 entries = append(entries, entry) 38 } 39 return 40 } 41 42 func NewBasicValueWriter(rt reflect.Type) (vw ValueWriter, ct ColumnTypeName, err error) { 43 switch rt.Kind() { 44 case reflect.String: 45 vw = &StringValue{} 46 ct = StringType 47 break 48 case reflect.Bool: 49 vw = &BoolValue{} 50 ct = BoolType 51 break 52 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 53 vw = &IntValue{} 54 ct = IntType 55 break 56 case reflect.Float32, reflect.Float64: 57 vw = &FloatValue{} 58 ct = FloatType 59 break 60 case reflect.Uint8: 61 vw = &ByteValue{} 62 ct = ByteType 63 break 64 default: 65 if rt.ConvertibleTo(nullStringType) { 66 vw = &StringValue{null: true} 67 ct = StringType 68 break 69 } 70 if rt.ConvertibleTo(nullBoolType) { 71 vw = &BoolValue{null: true} 72 ct = BoolType 73 break 74 } 75 if rt.ConvertibleTo(nullInt64Type) { 76 vw = &IntValue{null: true, base: 64} 77 ct = IntType 78 break 79 } 80 if rt.ConvertibleTo(nullInt32Type) { 81 vw = &IntValue{null: true, base: 32} 82 ct = IntType 83 break 84 } 85 if rt.ConvertibleTo(nullInt16Type) { 86 vw = &IntValue{null: true, base: 16} 87 ct = IntType 88 break 89 } 90 if rt.ConvertibleTo(nullFloatType) { 91 vw = &FloatValue{null: true} 92 ct = FloatType 93 break 94 } 95 if rt.ConvertibleTo(nullByteType) { 96 vw = &ByteValue{null: true} 97 ct = ByteType 98 break 99 } 100 if rt.ConvertibleTo(nullBytesType) { 101 vw = &BytesValue{null: true} 102 ct = BytesType 103 break 104 } 105 if rt.ConvertibleTo(datetimeType) { 106 vw = &DatetimeValue{} 107 ct = DatetimeType 108 break 109 } 110 if rt.ConvertibleTo(nullTimeType) || rt.ConvertibleTo(nullDatetimeType) { 111 vw = &DatetimeValue{null: true} 112 ct = DatetimeType 113 break 114 } 115 if rt.ConvertibleTo(dateType) { 116 vw = &DateValue{} 117 ct = DateType 118 break 119 } 120 if rt.ConvertibleTo(nullTimesDateType) { 121 vw = &DateValue{ 122 null: true, 123 } 124 ct = DateType 125 break 126 } 127 if rt.ConvertibleTo(timeType) { 128 vw = &TimeValue{} 129 ct = TimeType 130 break 131 } 132 if rt.ConvertibleTo(nullTimesTimeType) { 133 vw = &TimeValue{ 134 null: true, 135 } 136 ct = TimeType 137 break 138 } 139 err = errors.Warning("sql: type is not basic").WithCause(fmt.Errorf("%s", rt.String())) 140 break 141 } 142 return 143 } 144 145 type ValueWriter interface { 146 Write(value any, field reflect.Value) (err error) 147 } 148 149 type StringValue struct { 150 null bool 151 } 152 153 func (w *StringValue) Write(value any, rv reflect.Value) (err error) { 154 vv, ok := value.(string) 155 if ok { 156 if w.null { 157 rv.Set(reflect.ValueOf(stdsql.NullString{ 158 String: vv, 159 Valid: vv != "", 160 }).Convert(rv.Type())) 161 } else { 162 rv.SetString(vv) 163 } 164 return 165 } 166 err = errors.Warning("sql: write value failed"). 167 WithCause(fmt.Errorf("rv is not string")) 168 return 169 } 170 171 type BoolValue struct { 172 null bool 173 } 174 175 func (w *BoolValue) Write(value any, rv reflect.Value) (err error) { 176 vv, ok := value.(bool) 177 if ok { 178 if w.null { 179 rv.Set(reflect.ValueOf(stdsql.NullBool{ 180 Bool: vv, 181 Valid: true, 182 }).Convert(rv.Type())) 183 } else { 184 rv.SetBool(vv) 185 } 186 return 187 } 188 err = errors.Warning("sql: write value failed"). 189 WithCause(fmt.Errorf("rv is not bool")) 190 return 191 } 192 193 type IntValue struct { 194 null bool 195 base int 196 } 197 198 func (w *IntValue) Write(value any, rv reflect.Value) (err error) { 199 n, ok := AsInt(value) 200 if ok { 201 if w.null { 202 switch w.base { 203 case 64: 204 rv.Set(reflect.ValueOf(stdsql.NullInt64{ 205 Int64: n, 206 Valid: true, 207 }).Convert(rv.Type())) 208 break 209 case 32: 210 rv.Set(reflect.ValueOf(stdsql.NullInt32{ 211 Int32: int32(n), 212 Valid: true, 213 }).Convert(rv.Type())) 214 break 215 default: 216 rv.Set(reflect.ValueOf(stdsql.NullInt16{ 217 Int16: int16(n), 218 Valid: true, 219 }).Convert(rv.Type())) 220 break 221 } 222 } else { 223 rv.SetInt(n) 224 } 225 return 226 } 227 err = errors.Warning("sql: write value failed"). 228 WithCause(fmt.Errorf("rv is not int")) 229 return 230 } 231 232 type FloatValue struct { 233 null bool 234 } 235 236 func (w *FloatValue) Write(value any, rv reflect.Value) (err error) { 237 f, ok := AsFloat(value) 238 if ok { 239 if w.null { 240 rv.Set(reflect.ValueOf(stdsql.NullFloat64{ 241 Float64: f, 242 Valid: true, 243 }).Convert(rv.Type())) 244 } else { 245 rv.SetFloat(f) 246 } 247 return 248 } 249 err = errors.Warning("sql: write value failed"). 250 WithCause(fmt.Errorf("rv is not float")) 251 return 252 } 253 254 type ByteValue struct { 255 null bool 256 } 257 258 func (w *ByteValue) Write(value any, rv reflect.Value) (err error) { 259 b, ok := value.(byte) 260 if ok { 261 if w.null { 262 rv.Set(reflect.ValueOf(stdsql.NullByte{ 263 Byte: b, 264 Valid: true, 265 }).Convert(rv.Type())) 266 } else { 267 rv.Set(reflect.ValueOf(b)) 268 } 269 return 270 } 271 err = errors.Warning("sql: write value failed"). 272 WithCause(fmt.Errorf("rv is not byte")) 273 return 274 } 275 276 type BytesValue struct { 277 null bool 278 } 279 280 func (w *BytesValue) Write(value any, rv reflect.Value) (err error) { 281 p, ok := value.([]byte) 282 if ok { 283 if w.null { 284 rv.Set(reflect.ValueOf(sql.NullBytes{ 285 Bytes: p, 286 Valid: true, 287 }).Convert(rv.Type())) 288 } else { 289 rv.Set(reflect.ValueOf(p).Convert(rv.Type())) 290 } 291 return 292 } 293 err = errors.Warning("sql: write value failed"). 294 WithCause(fmt.Errorf("rv is not bytes")) 295 return 296 } 297 298 type DatetimeValue struct { 299 null bool 300 } 301 302 func (w *DatetimeValue) Write(value any, rv reflect.Value) (err error) { 303 t, ok := value.(time.Time) 304 if ok { 305 if w.null { 306 if rv.Type().ConvertibleTo(nullTimeType) { 307 rv.Set(reflect.ValueOf(stdsql.NullTime{ 308 Time: t, 309 Valid: !t.IsZero(), 310 }).Convert(rv.Type())) 311 } else if rv.Type().ConvertibleTo(nullDatetimeType) { 312 rv.Set(reflect.ValueOf(sql.NullDatetime{ 313 NullTime: stdsql.NullTime{ 314 Time: t, 315 Valid: !t.IsZero(), 316 }, 317 }).Convert(rv.Type())) 318 } 319 } else { 320 rv.Set(reflect.ValueOf(t).Convert(rv.Type())) 321 } 322 return 323 } 324 err = errors.Warning("sql: write value failed"). 325 WithCause(fmt.Errorf("rv is not time.Time")) 326 return 327 } 328 329 type DateValue struct { 330 null bool 331 } 332 333 func (w *DateValue) Write(value any, rv reflect.Value) (err error) { 334 t, ok := value.(time.Time) 335 if ok { 336 if w.null { 337 rv.Set(reflect.ValueOf(sql.NullDate{ 338 Date: times.DataOf(t), 339 Valid: !t.IsZero(), 340 }).Convert(rv.Type())) 341 } else { 342 rv.Set(reflect.ValueOf(times.DataOf(t))) 343 } 344 return 345 } 346 err = errors.Warning("sql: write value failed"). 347 WithCause(fmt.Errorf("rv is not time.Time")) 348 return 349 } 350 351 type TimeValue struct { 352 null bool 353 } 354 355 func (w *TimeValue) Write(value any, rv reflect.Value) (err error) { 356 t, ok := value.(time.Time) 357 if ok { 358 if w.null { 359 rv.Set(reflect.ValueOf(sql.NullTime{ 360 Time: times.TimeOf(t), 361 Valid: !t.IsZero(), 362 }).Convert(rv.Type())) 363 } else { 364 rv.Set(reflect.ValueOf(times.TimeOf(t))) 365 } 366 return 367 } 368 err = errors.Warning("sql: write value failed"). 369 WithCause(fmt.Errorf("rv is not time.Time")) 370 return 371 } 372 373 type JsonValue struct { 374 ValueType reflect.Type 375 } 376 377 func (w *JsonValue) Write(value any, rv reflect.Value) (err error) { 378 p, ok := value.([]byte) 379 if ok { 380 if json.IsNull(p) || bytes.Equal(p, jsonEmptyBytes) || bytes.Equal(p, jsonEmptyArrayBytes) { 381 return 382 } 383 if !json.Validate(p) { 384 err = errors.Warning("sql: write value failed"). 385 WithCause(fmt.Errorf("rv is not valid json bytes")) 386 return 387 } 388 if w.ValueType.ConvertibleTo(bytesType) { 389 rv.SetBytes(p) 390 return 391 } 392 if w.ValueType.Kind() == reflect.Ptr { 393 rv.Set(reflect.New(rv.Type().Elem())) 394 decodeErr := json.Unmarshal(p, rv.Interface()) 395 if decodeErr != nil { 396 err = errors.Warning("sql: write value failed"). 397 WithCause(fmt.Errorf("rv is not valid json bytes")).WithCause(decodeErr) 398 return 399 } 400 } else { 401 element := reflect.New(rv.Type()).Interface() 402 decodeErr := json.Unmarshal(p, element) 403 if decodeErr != nil { 404 err = errors.Warning("sql: write value failed"). 405 WithCause(fmt.Errorf("rv is not valid json bytes")).WithCause(decodeErr) 406 return 407 } 408 rv.Set(reflect.ValueOf(element).Elem()) 409 } 410 return 411 } 412 err = errors.Warning("sql: write value failed"). 413 WithCause(fmt.Errorf("rv is not bytes")) 414 return 415 } 416 417 type MappingValue struct { 418 ValueType reflect.Type 419 } 420 421 func (w *MappingValue) Write(value any, rv reflect.Value) (err error) { 422 p, ok := value.([]byte) 423 if ok { 424 if !json.Validate(p) { 425 err = errors.Warning("sql: write value failed"). 426 WithCause(fmt.Errorf("rv is not valid json bytes")) 427 return 428 } 429 if w.ValueType.Kind() == reflect.Ptr { 430 rv.Set(reflect.New(rv.Type().Elem())) 431 decodeErr := json.Unmarshal(p, rv.Interface()) 432 if decodeErr != nil { 433 err = errors.Warning("sql: write value failed"). 434 WithCause(fmt.Errorf("rv is not valid json bytes")).WithCause(decodeErr) 435 return 436 } 437 } else { 438 element := reflect.New(rv.Type()).Interface() 439 decodeErr := json.Unmarshal(p, element) 440 if decodeErr != nil { 441 err = errors.Warning("sql: write value failed"). 442 WithCause(fmt.Errorf("rv is not valid json bytes")).WithCause(decodeErr) 443 return 444 } 445 rv.Set(reflect.ValueOf(element).Elem()) 446 } 447 return 448 } 449 err = errors.Warning("sql: write value failed"). 450 WithCause(fmt.Errorf("rv is not bytes")) 451 return 452 } 453 454 type ScanValue struct { 455 } 456 457 func (w *ScanValue) Write(value any, rv reflect.Value) (err error) { 458 nv := reflect.New(reflect.Indirect(rv).Type()) 459 scanner, ok := nv.Interface().(stdsql.Scanner) 460 if !ok { 461 err = errors.Warning("sql: write value failed"). 462 WithCause(fmt.Errorf("rv is not sql.Scanner")) 463 return 464 } 465 scanFieldValueErr := scanner.Scan(value) 466 if scanFieldValueErr != nil { 467 err = errors.Warning("sql: write value failed"). 468 WithCause(scanFieldValueErr) 469 return 470 } 471 rv.Set(nv.Elem()) 472 return 473 }