1
0
mirror of https://github.com/ManyakRus/starter.git synced 2025-11-28 23:20:10 +02:00

сделал // копия файла из https://github.com/jackc/pgtype/timestamptz.go

This commit is contained in:
Nikitin Aleksandr
2025-07-02 16:24:51 +03:00
parent 4bf52e5a7a
commit f3337f07b4
3 changed files with 44 additions and 32 deletions

View File

@@ -40,7 +40,7 @@ var mutex_Connect = &sync.RWMutex{}
var mutex_ReConnect = &sync.RWMutex{} var mutex_ReConnect = &sync.RWMutex{}
// Settings хранит все нужные переменные окружения // Settings хранит все нужные переменные окружения
var Settings SettingsINI var Settings = SettingsINI{}
// NeedReconnect - флаг необходимости переподключения // NeedReconnect - флаг необходимости переподключения
var NeedReconnect bool var NeedReconnect bool
@@ -332,7 +332,7 @@ func Start(ApplicationName string) {
// FillSettings загружает переменные окружения в структуру из файла или из переменных окружения // FillSettings загружает переменные окружения в структуру из файла или из переменных окружения
func FillSettings() { func FillSettings() {
Settings = SettingsINI{} //Settings = SettingsINI{}
Settings.DB_HOST = os.Getenv("DB_HOST") Settings.DB_HOST = os.Getenv("DB_HOST")
Settings.DB_PORT = os.Getenv("DB_PORT") Settings.DB_PORT = os.Getenv("DB_PORT")
Settings.DB_NAME = os.Getenv("DB_NAME") Settings.DB_NAME = os.Getenv("DB_NAME")

View File

@@ -1,3 +1,6 @@
// копия файла из https://github.com/jackc/pgtype/timestamptz.go
// чтоб не выдавала ошибку на null
// чтобы дата NULL = time.Time{}
package postgres_pgx package postgres_pgx
import ( import (
@@ -6,6 +9,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/jackc/pgx/v5/pgtype" "github.com/jackc/pgx/v5/pgtype"
"reflect"
"strings" "strings"
"time" "time"
) )
@@ -20,13 +24,13 @@ const (
infinityMicrosecondOffset = 9223372036854775807 infinityMicrosecondOffset = 9223372036854775807
) )
type TimestamptzScanner interface { //type TimestamptzScanner interface {
ScanTimestamptz(v Timestamptz) error // ScanTimestamptz(v Timestamptz) error
} //}
//
type TimestamptzValuer interface { //type TimestamptzValuer interface {
TimestamptzValue() (Timestamptz, error) // TimestamptzValue() (Timestamptz, error)
} //}
// Timestamptz represents the PostgreSQL timestamptz type. // Timestamptz represents the PostgreSQL timestamptz type.
type Timestamptz struct { type Timestamptz struct {
@@ -47,7 +51,8 @@ func (tstz Timestamptz) TimestamptzValue() (Timestamptz, error) {
// Scan implements the database/sql Scanner interface. // Scan implements the database/sql Scanner interface.
func (tstz *Timestamptz) Scan(src any) error { func (tstz *Timestamptz) Scan(src any) error {
if src == nil { if src == nil {
*tstz = Timestamptz{} *tstz = Timestamptz{Valid: true} //sanek
//*tstz = Timestamptz{}
return nil return nil
} }
@@ -138,7 +143,7 @@ func (*TimestamptzCodec) PreferredFormat() int16 {
} }
func (*TimestamptzCodec) PlanEncode(m *pgtype.Map, oid uint32, format int16, value any) pgtype.EncodePlan { func (*TimestamptzCodec) PlanEncode(m *pgtype.Map, oid uint32, format int16, value any) pgtype.EncodePlan {
if _, ok := value.(TimestamptzValuer); !ok { if _, ok := value.(pgtype.TimestamptzValuer); !ok {
return nil return nil
} }
@@ -155,7 +160,7 @@ func (*TimestamptzCodec) PlanEncode(m *pgtype.Map, oid uint32, format int16, val
type encodePlanTimestamptzCodecBinary struct{} type encodePlanTimestamptzCodecBinary struct{}
func (encodePlanTimestamptzCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { func (encodePlanTimestamptzCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) {
ts, err := value.(TimestamptzValuer).TimestamptzValue() ts, err := value.(pgtype.TimestamptzValuer).TimestamptzValue()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -183,7 +188,7 @@ func (encodePlanTimestamptzCodecBinary) Encode(value any, buf []byte) (newBuf []
type encodePlanTimestamptzCodecText struct{} type encodePlanTimestamptzCodecText struct{}
func (encodePlanTimestamptzCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { func (encodePlanTimestamptzCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) {
ts, err := value.(TimestamptzValuer).TimestamptzValue() ts, err := value.(pgtype.TimestamptzValuer).TimestamptzValue()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -227,13 +232,15 @@ func (c *TimestamptzCodec) PlanScan(m *pgtype.Map, oid uint32, format int16, tar
switch format { switch format {
case pgtype.BinaryFormatCode: case pgtype.BinaryFormatCode:
switch target.(type) { name := getInterfaceName(target) //sanek
case TimestamptzScanner: switch name {
case "*pgtype.timeWrapper":
return &scanPlanBinaryTimestamptzToTimestamptzScanner{location: c.ScanLocation} return &scanPlanBinaryTimestamptzToTimestamptzScanner{location: c.ScanLocation}
} }
case pgtype.TextFormatCode: case pgtype.TextFormatCode:
switch target.(type) { name := getInterfaceName(target) //sanek
case TimestamptzScanner: switch name {
case "*pgtype.timeWrapper":
return &scanPlanTextTimestamptzToTimestamptzScanner{location: c.ScanLocation} return &scanPlanTextTimestamptzToTimestamptzScanner{location: c.ScanLocation}
} }
} }
@@ -241,27 +248,32 @@ func (c *TimestamptzCodec) PlanScan(m *pgtype.Map, oid uint32, format int16, tar
return nil return nil
} }
func getInterfaceName(v interface{}) string {
return reflect.TypeOf(v).String()
}
type scanPlanBinaryTimestamptzToTimestamptzScanner struct{ location *time.Location } type scanPlanBinaryTimestamptzToTimestamptzScanner struct{ location *time.Location }
func (plan *scanPlanBinaryTimestamptzToTimestamptzScanner) Scan(src []byte, dst any) error { func (plan *scanPlanBinaryTimestamptzToTimestamptzScanner) Scan(src []byte, dst any) error {
scanner := (dst).(TimestamptzScanner) scanner := (dst).(pgtype.TimestamptzScanner)
if src == nil { if src == nil {
return scanner.ScanTimestamptz(Timestamptz{}) return scanner.ScanTimestamptz(pgtype.Timestamptz{Valid: true})
//return scanner.ScanTimestamptz(pgtype.Timestamptz{})
} }
if len(src) != 8 { if len(src) != 8 {
return fmt.Errorf("invalid length for timestamptz: %v", len(src)) return fmt.Errorf("invalid length for timestamptz: %v", len(src))
} }
var tstz Timestamptz var tstz pgtype.Timestamptz
microsecSinceY2K := int64(binary.BigEndian.Uint64(src)) microsecSinceY2K := int64(binary.BigEndian.Uint64(src))
switch microsecSinceY2K { switch microsecSinceY2K {
case infinityMicrosecondOffset: case infinityMicrosecondOffset:
tstz = Timestamptz{Valid: true, InfinityModifier: pgtype.Infinity} tstz = pgtype.Timestamptz{Valid: true, InfinityModifier: pgtype.Infinity}
case negativeInfinityMicrosecondOffset: case negativeInfinityMicrosecondOffset:
tstz = Timestamptz{Valid: true, InfinityModifier: -pgtype.Infinity} tstz = pgtype.Timestamptz{Valid: true, InfinityModifier: -pgtype.Infinity}
default: default:
tim := time.Unix( tim := time.Unix(
microsecFromUnixEpochToY2K/1000000+microsecSinceY2K/1000000, microsecFromUnixEpochToY2K/1000000+microsecSinceY2K/1000000,
@@ -270,7 +282,7 @@ func (plan *scanPlanBinaryTimestamptzToTimestamptzScanner) Scan(src []byte, dst
if plan.location != nil { if plan.location != nil {
tim = tim.In(plan.location) tim = tim.In(plan.location)
} }
tstz = Timestamptz{Time: tim, Valid: true} tstz = pgtype.Timestamptz{Time: tim, Valid: true}
} }
return scanner.ScanTimestamptz(tstz) return scanner.ScanTimestamptz(tstz)
@@ -279,19 +291,19 @@ func (plan *scanPlanBinaryTimestamptzToTimestamptzScanner) Scan(src []byte, dst
type scanPlanTextTimestamptzToTimestamptzScanner struct{ location *time.Location } type scanPlanTextTimestamptzToTimestamptzScanner struct{ location *time.Location }
func (plan *scanPlanTextTimestamptzToTimestamptzScanner) Scan(src []byte, dst any) error { func (plan *scanPlanTextTimestamptzToTimestamptzScanner) Scan(src []byte, dst any) error {
scanner := (dst).(TimestamptzScanner) scanner := (dst).(pgtype.TimestamptzScanner)
if src == nil { if src == nil {
return scanner.ScanTimestamptz(Timestamptz{}) return scanner.ScanTimestamptz(pgtype.Timestamptz{})
} }
var tstz Timestamptz var tstz pgtype.Timestamptz
sbuf := string(src) sbuf := string(src)
switch sbuf { switch sbuf {
case "infinity": case "infinity":
tstz = Timestamptz{Valid: true, InfinityModifier: pgtype.Infinity} tstz = pgtype.Timestamptz{Valid: true, InfinityModifier: pgtype.Infinity}
case "-infinity": case "-infinity":
tstz = Timestamptz{Valid: true, InfinityModifier: -pgtype.Infinity} tstz = pgtype.Timestamptz{Valid: true, InfinityModifier: -pgtype.Infinity}
default: default:
bc := false bc := false
if strings.HasSuffix(sbuf, " BC") { if strings.HasSuffix(sbuf, " BC") {
@@ -322,7 +334,7 @@ func (plan *scanPlanTextTimestamptzToTimestamptzScanner) Scan(src []byte, dst an
tim = tim.In(plan.location) tim = tim.In(plan.location)
} }
tstz = Timestamptz{Time: tim, Valid: true} tstz = pgtype.Timestamptz{Time: tim, Valid: true}
} }
return scanner.ScanTimestamptz(tstz) return scanner.ScanTimestamptz(tstz)

View File

@@ -33,7 +33,7 @@ var PgxPool *pgxpool.Pool
var mutex_ReConnect = &sync.RWMutex{} var mutex_ReConnect = &sync.RWMutex{}
// Settings хранит все нужные переменные окружения // Settings хранит все нужные переменные окружения
var Settings SettingsINI var Settings = SettingsINI{}
// NeedReconnect - флаг необходимости переподключения // NeedReconnect - флаг необходимости переподключения
var NeedReconnect bool var NeedReconnect bool
@@ -355,7 +355,7 @@ func Start(ApplicationName string) {
// FillSettings загружает переменные окружения в структуру из файла или из переменных окружения // FillSettings загружает переменные окружения в структуру из файла или из переменных окружения
func FillSettings() { func FillSettings() {
Settings = SettingsINI{} //Settings = SettingsINI{}
Settings.DB_HOST = os.Getenv("DB_HOST") Settings.DB_HOST = os.Getenv("DB_HOST")
Settings.DB_PORT = os.Getenv("DB_PORT") Settings.DB_PORT = os.Getenv("DB_PORT")
Settings.DB_NAME = os.Getenv("DB_NAME") Settings.DB_NAME = os.Getenv("DB_NAME")