Open
Description
I had to build a query hook for bun that allows me to apply the database time zone loc to all time structs before inserting them into the database. For instance i am creating an order and when i call the .UTC() method on the time it causes the .In() called in the time zone hook. When printing the requested date into the console it shows the time with the database offset but bun inserts the time as utc still. This issue goes away if UTC() was not called and no location was set but i do not have control over the fact the UTC() was called because my protobuf api has a helper method called AsTime() that returns the time struct after calling the UTC() function.
I am using the mssql dialect v1.2.11
// Order Repository
requestedDate := time.Unix(1745335353,0).UTC()
orderDate := time.Unix(1745428361,0)
prophet.OeHdr{
OrderNo: strconv.Itoa(int(orderNo)),
OrderDate: &orderDate,
RequestedDate: &requestedDate,
}
// timeZoneHook
type TimeZoneHook struct {
dbLocation *time.Location
}
func (h TimeZoneHook) BeforeQuery(ctx context.Context, event *bun.QueryEvent) context.Context {
// Process different query types
switch event.IQuery.(type) {
case *bun.InsertQuery, *bun.UpdateQuery:
// Skip processing if there is no model
if event.Model == nil {
return ctx
}
// Get the model value
val := reflect.ValueOf(event.Model.Value())
// Handle pointer types
if val.Kind() == reflect.Ptr {
if val.IsNil() {
return ctx
}
val = val.Elem()
}
// Check if the value is valid for processing
if !val.IsValid() {
return ctx
}
// Process based on the kind of value
switch val.Kind() {
case reflect.Struct:
// Process struct directly
h.inDBTimezone(val)
case reflect.Slice:
// Process each element in the slice
for i := 0; i < val.Len(); i++ {
elem := val.Index(i)
// If element is a struct or pointer to struct
if elem.Kind() == reflect.Struct {
h.inDBTimezone(val)
} else if elem.Kind() == reflect.Ptr && !elem.IsNil() {
elemVal := elem.Elem()
if elemVal.Kind() == reflect.Struct {
h.inDBTimezone(val)
}
}
}
}
}
return ctx
}
// inDBTimezone converts time fields to the database time zone
func (h TimeZoneHook) inDBTimezone(val reflect.Value) {
h.processTimeFields(val, func(t *time.Time) time.Time {
return t.In(h.dbLocation)
})
}
Metadata
Metadata
Assignees
Labels
No labels