Browse Source

修改bug

yjp 10 months ago
parent
commit
55798771ec
10 changed files with 1088 additions and 0 deletions
  1. 70 0
      dboperations.go
  2. 45 0
      go.mod
  3. 127 0
      go.sum
  4. 93 0
      operations/condition.go
  5. 73 0
      operations/db.go
  6. 10 0
      operations/dberr.go
  7. 61 0
      operations/interface.go
  8. 286 0
      operations/operations.go
  9. 302 0
      operations/table_row.go
  10. 21 0
      operations/transaction_operations.go

+ 70 - 0
dboperations.go

@@ -0,0 +1,70 @@
+package sdk
+
+import (
+	"git.sxidc.com/go-tools/dboperations/operations"
+	"strings"
+)
+
+var dbOperationsInstance operations.DBOperations
+
+func GetInstance() operations.DBOperations {
+	return dbOperationsInstance
+}
+
+type DBConfig struct {
+	Type               string
+	UserName           string
+	Password           string
+	Address            string
+	Port               string
+	Database           string
+	MaxConnections     int
+	MaxIdleConnections int
+}
+
+func InitInstance(dbConfig *DBConfig) error {
+	if dbOperationsInstance != nil {
+		return nil
+	}
+
+	dbOperations, err := operations.NewOperations(&operations.DBConfig{
+		Type:               dbConfig.Type,
+		UserName:           dbConfig.UserName,
+		Password:           dbConfig.Password,
+		Address:            dbConfig.Address,
+		Port:               dbConfig.Port,
+		Database:           dbConfig.Database,
+		MaxConnections:     dbConfig.MaxConnections,
+		MaxIdleConnections: dbConfig.MaxIdleConnections,
+	})
+	if err != nil {
+		return err
+	}
+
+	dbOperationsInstance = dbOperations
+
+	return nil
+}
+
+func DestroyInstance() error {
+	if dbOperationsInstance == nil {
+		return nil
+	}
+
+	err := operations.DestroyOperation(dbOperationsInstance.(*operations.Operations))
+	if err != nil {
+		return err
+	}
+
+	dbOperationsInstance = nil
+
+	return nil
+}
+
+func IsErrorDBRecordHasExist(err error) bool {
+	return strings.Contains(err.Error(), "记录已存在")
+}
+
+func IsErrorDBRecordNotExist(err error) bool {
+	return strings.Contains(err.Error(), "记录不存在")
+}

+ 45 - 0
go.mod

@@ -1,3 +1,48 @@
 module git.sxidc.com/go-tools/dboperations
 
 go 1.22.0
+
+require (
+	git.sxidc.com/service-supports/fslog v0.5.9
+	github.com/mitchellh/mapstructure v1.5.0
+	gorm.io/driver/postgres v1.5.7
+	gorm.io/gorm v1.25.9
+)
+
+require (
+	github.com/bytedance/sonic v1.10.0 // indirect
+	github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
+	github.com/chenzhuoyu/iasm v0.9.0 // indirect
+	github.com/gabriel-vasile/mimetype v1.4.2 // indirect
+	github.com/gin-contrib/sse v0.1.0 // indirect
+	github.com/gin-gonic/gin v1.9.1 // indirect
+	github.com/go-playground/locales v0.14.1 // indirect
+	github.com/go-playground/universal-translator v0.18.1 // indirect
+	github.com/go-playground/validator/v10 v10.15.3 // indirect
+	github.com/goccy/go-json v0.10.2 // indirect
+	github.com/jackc/pgpassfile v1.0.0 // indirect
+	github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
+	github.com/jackc/pgx/v5 v5.4.3 // indirect
+	github.com/jinzhu/inflection v1.0.0 // indirect
+	github.com/jinzhu/now v1.1.5 // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/klauspost/cpuid/v2 v2.2.5 // indirect
+	github.com/leodido/go-urn v1.2.4 // indirect
+	github.com/mattn/go-isatty v0.0.19 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/pelletier/go-toml/v2 v2.1.0 // indirect
+	github.com/rogpeppe/go-internal v1.12.0 // indirect
+	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
+	github.com/ugorji/go/codec v1.2.11 // indirect
+	go.uber.org/multierr v1.11.0 // indirect
+	go.uber.org/zap v1.25.0 // indirect
+	golang.org/x/arch v0.5.0 // indirect
+	golang.org/x/crypto v0.14.0 // indirect
+	golang.org/x/net v0.15.0 // indirect
+	golang.org/x/sys v0.13.0 // indirect
+	golang.org/x/text v0.13.0 // indirect
+	google.golang.org/protobuf v1.31.0 // indirect
+	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+)

+ 127 - 0
go.sum

@@ -0,0 +1,127 @@
+git.sxidc.com/service-supports/fslog v0.5.9 h1:q2XIK2o/fk/qmByy4x5kKLC+k7kolT5LrXHcWRSffXQ=
+git.sxidc.com/service-supports/fslog v0.5.9/go.mod h1:/m03ATmmOle75qtEgvEw8a1+Dcg6iHp08M1bGFXJTBU=
+github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
+github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
+github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
+github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
+github.com/bytedance/sonic v1.10.0 h1:qtNZduETEIWJVIyDl01BeNxur2rW9OwTQ/yBqFRkKEk=
+github.com/bytedance/sonic v1.10.0/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
+github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
+github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
+github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
+github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo=
+github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
+github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
+github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.15.3 h1:S+sSpunYjNPDuXkWbK+x+bA7iXiW296KG4dL3X7xUZo=
+github.com/go-playground/validator/v10 v10.15.3/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
+github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
+github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY=
+github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA=
+github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
+github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
+github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
+github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
+github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
+github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
+github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
+github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
+github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
+github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
+github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
+github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
+github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
+github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
+go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
+go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
+go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
+go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/arch v0.5.0 h1:jpGode6huXQxcskEIpOCvrU+tzo81b6+oFLUYXWtH/Y=
+golang.org/x/arch v0.5.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
+google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
+gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
+gorm.io/gorm v1.25.9 h1:wct0gxZIELDk8+ZqF/MVnHLkA1rvYlBWUMv2EdsK1g8=
+gorm.io/gorm v1.25.9/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
+nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

+ 93 - 0
operations/condition.go

@@ -0,0 +1,93 @@
+package operations
+
+import "gorm.io/gorm"
+
+type Conditions struct {
+	queries   []string
+	queryArgs [][]any
+}
+
+func NewConditions() *Conditions {
+	return &Conditions{
+		queries:   make([]string, 0),
+		queryArgs: make([][]any, 0),
+	}
+}
+
+func (clause *Conditions) Equal(columnName string, value any) *Conditions {
+	clause.queries = append(clause.queries, columnName+" = ?")
+	clause.queryArgs = append(clause.queryArgs, []any{value})
+	return clause
+}
+
+func (clause *Conditions) Like(columnName string, value any) *Conditions {
+	clause.queries = append(clause.queries, columnName+" LIKE ?")
+	clause.queryArgs = append(clause.queryArgs, []any{value})
+	return clause
+}
+
+func (clause *Conditions) In(columnName string, value any) *Conditions {
+	clause.queries = append(clause.queries, columnName+" IN ?")
+	clause.queryArgs = append(clause.queryArgs, []any{value})
+	return clause
+}
+
+func (clause *Conditions) NotIn(columnName string, value any) *Conditions {
+	clause.queries = append(clause.queries, columnName+" NOT IN ?")
+	clause.queryArgs = append(clause.queryArgs, []any{value})
+	return clause
+}
+
+func (clause *Conditions) Not(columnName string, value any) *Conditions {
+	clause.queries = append(clause.queries, columnName+" != ?")
+	clause.queryArgs = append(clause.queryArgs, []any{value})
+	return clause
+}
+
+func (clause *Conditions) LessThan(columnName string, value any) *Conditions {
+	clause.queries = append(clause.queries, columnName+" < ?")
+	clause.queryArgs = append(clause.queryArgs, []any{value})
+	return clause
+}
+
+func (clause *Conditions) LessThanAndEqual(columnName string, value any) *Conditions {
+	clause.queries = append(clause.queries, columnName+" <= ?")
+	clause.queryArgs = append(clause.queryArgs, []any{value})
+	return clause
+}
+
+func (clause *Conditions) GreaterThan(columnName string, value any) *Conditions {
+	clause.queries = append(clause.queries, columnName+" > ?")
+	clause.queryArgs = append(clause.queryArgs, []any{value})
+	return clause
+}
+
+func (clause *Conditions) GreaterThanAndEqual(columnName string, value any) *Conditions {
+	clause.queries = append(clause.queries, columnName+" >= ?")
+	clause.queryArgs = append(clause.queryArgs, []any{value})
+	return clause
+}
+
+func (clause *Conditions) where(db *gorm.DB) *gorm.DB {
+	for i, query := range clause.queries {
+		db = db.Where(query, clause.queryArgs[i]...)
+	}
+
+	return db
+}
+
+func (clause *Conditions) or(db *gorm.DB) *gorm.DB {
+	for i, query := range clause.queries {
+		db = db.Or(query, clause.queryArgs[i]...)
+	}
+
+	return db
+}
+
+func (clause *Conditions) having(db *gorm.DB) *gorm.DB {
+	for i, query := range clause.queries {
+		db = db.Having(query, clause.queryArgs[i]...)
+	}
+
+	return db
+}

+ 73 - 0
operations/db.go

@@ -0,0 +1,73 @@
+package operations
+
+import (
+	"errors"
+	"fmt"
+	"gorm.io/driver/postgres"
+	"gorm.io/gorm"
+	"gorm.io/gorm/logger"
+)
+
+const (
+	databaseTypePostgres = "postgres"
+)
+
+type DBConfig struct {
+	Type               string `mapstructure:"type"`
+	UserName           string `mapstructure:"user_name"`
+	Password           string `mapstructure:"password"`
+	Address            string `mapstructure:"address"`
+	Port               string `mapstructure:"port"`
+	Database           string `mapstructure:"database"`
+	MaxConnections     int    `mapstructure:"max_connections"`
+	MaxIdleConnections int    `mapstructure:"max_idle_connections"`
+}
+
+func newGormDB(dbConfig *DBConfig) (*gorm.DB, error) {
+	if dbConfig == nil {
+		return nil, errors.New("没有传递数据库配置")
+	}
+
+	var gormDB *gorm.DB
+
+	switch dbConfig.Type {
+	case databaseTypePostgres:
+		innerGormDB, err := newPostgresSQLOperationsItem(dbConfig)
+		if err != nil {
+			return nil, err
+		}
+
+		gormDB = innerGormDB
+	default:
+		innerGormDB, err := newPostgresSQLOperationsItem(dbConfig)
+		if err != nil {
+			return nil, err
+		}
+
+		gormDB = innerGormDB
+	}
+
+	return gormDB, nil
+}
+
+func newPostgresSQLOperationsItem(dbConfig *DBConfig) (*gorm.DB, error) {
+	dsn := "host=%s port=%s user=%s password=%s dbname=%s sslmode=disable TimeZone=Asia/Shanghai"
+	connStr := fmt.Sprintf(dsn, dbConfig.Address, dbConfig.Port, dbConfig.UserName, dbConfig.Password, dbConfig.Database)
+	return gorm.Open(postgres.Open(connStr), &gorm.Config{
+		Logger:      logger.Default.LogMode(logger.Info),
+		PrepareStmt: true,
+	})
+}
+
+func destroyGormDB(gormDB *gorm.DB) error {
+	if gormDB == nil {
+		return nil
+	}
+
+	db, err := gormDB.DB()
+	if err != nil {
+		return err
+	}
+
+	return db.Close()
+}

+ 10 - 0
operations/dberr.go

@@ -0,0 +1,10 @@
+package operations
+
+import (
+	"errors"
+)
+
+var (
+	ErrDBRecordHasExist = errors.New("记录已存在")
+	ErrDBRecordNotExist = errors.New("记录不存在")
+)

+ 61 - 0
operations/interface.go

@@ -0,0 +1,61 @@
+package operations
+
+type DBOperations interface {
+	BeginTransaction() TransactionDBOperations
+	// BeginEvent() EventDBOperations
+	BaseDBOperations
+}
+
+type TransactionDBOperations interface {
+	BaseDBOperations
+	RollbackTransaction()
+	CommitTransaction()
+}
+
+type EventDBOperations interface {
+	RollbackEvent()
+	CommitEvent()
+	// TODO 需要重新定义创建等方法,传递必要的key
+	EventRows(table string, keys []string, pageSize int, pageNo string)
+	Replay(table string, keys []string)
+}
+
+type BaseDBOperations interface {
+	// 会重置数据库连接的方法
+	Table(name string, args ...any) DBOperations
+
+	// 会重置数据库连接的方法,一般配合Raw使用
+	NewSession() DBOperations
+
+	// 执行SQL语句,使用Raw之后,为了触发SQL执行,需要调用Row或者Rows
+	// 如果是查询语句,使用Rows或Row均可,主要看自己需要查询的是单行还是多行
+	// 如果是写语句,必须使用Rows,否则由于没有返回结果,Rows会报错
+	// 使用Raw以后,所有分页相关的参数都无效,需要使用SQL语句进行分页
+	Raw(sql string, values ...any) DBOperations
+
+	// 组织SQL语句相关的方法
+	Select(query string, args ...any) DBOperations
+	Joins(query string, args ...any) DBOperations
+	Where(conditions *Conditions) DBOperations
+	Or(conditions *Conditions) DBOperations
+	Having(conditions *Conditions) DBOperations
+	GroupBy(groupBy string) DBOperations
+	OrderBy(orderBy string) DBOperations
+	Paging(pageNo int, pageSize int) DBOperations
+
+	// 写方法
+	Create(tableRow *TableRow) error
+	CreateBatch(tableRows []TableRow) error
+	Delete() error
+	Updates(newTableRow *TableRow) error
+	UpdatesWithRowsAffected(newTableRow *TableRow) (int64, error)
+
+	// 查询方法
+	Rows(pageNo int, pageSize int) ([]TableRow, error)
+	Row() (*TableRow, error)
+
+	// 其他方法
+	Count(count *int64) error
+	CheckExist() (bool, error)
+	CheckHasOnlyOne() (bool, error)
+}

+ 286 - 0
operations/operations.go

@@ -0,0 +1,286 @@
+package operations
+
+import (
+	"database/sql"
+	"git.sxidc.com/service-supports/fslog"
+	"gorm.io/gorm"
+	"strings"
+	"time"
+)
+
+type Operations struct {
+	initDB       *gorm.DB
+	processDB    *gorm.DB
+	stopPingChan chan any
+}
+
+func NewOperations(dbConfig *DBConfig) (*Operations, error) {
+	gormDB, err := newGormDB(dbConfig)
+	if err != nil {
+		return nil, err
+	}
+
+	sqlDB, err := gormDB.DB()
+	if err != nil {
+		return nil, err
+	}
+
+	if dbConfig.MaxConnections == 0 {
+		dbConfig.MaxConnections = 50
+	}
+
+	if dbConfig.MaxIdleConnections == 0 {
+		dbConfig.MaxIdleConnections = 10
+	}
+
+	sqlDB.SetMaxOpenConns(dbConfig.MaxConnections)
+	sqlDB.SetMaxIdleConns(dbConfig.MaxIdleConnections)
+
+	op := &Operations{
+		initDB:       gormDB,
+		processDB:    gormDB,
+		stopPingChan: make(chan any),
+	}
+
+	op.startBeatHeart(sqlDB)
+
+	return op, nil
+}
+
+func DestroyOperation(op *Operations) error {
+	if op == nil {
+		return nil
+	}
+
+	if op.initDB == nil {
+		return nil
+	}
+
+	op.stopBeatHeart()
+
+	return destroyGormDB(op.initDB)
+}
+
+func (op *Operations) startBeatHeart(sqlDB *sql.DB) {
+	go func() {
+		pingTicker := time.NewTicker(time.Minute * 1)
+		defer pingTicker.Stop()
+
+		for {
+			select {
+			case <-op.stopPingChan:
+				return
+			case <-pingTicker.C:
+				err := sqlDB.Ping()
+				if err != nil {
+					fslog.Error(err)
+				}
+			}
+		}
+	}()
+}
+
+func (op *Operations) stopBeatHeart() {
+	if op.stopPingChan != nil {
+		close(op.stopPingChan)
+		op.stopPingChan = nil
+	}
+}
+
+func (op *Operations) BeginTransaction() TransactionDBOperations {
+	tx := op.initDB.Begin()
+	return &TransactionOperations{
+		Operations{
+			initDB:    tx,
+			processDB: tx,
+		},
+	}
+}
+
+func (op *Operations) NewSession() DBOperations {
+	return &Operations{
+		initDB:    op.initDB,
+		processDB: op.initDB,
+	}
+}
+
+func (op *Operations) Table(name string, args ...any) DBOperations {
+	op.processDB = op.initDB.Table(name, args...)
+	return op
+}
+
+func (op *Operations) Raw(sql string, values ...any) DBOperations {
+	op.processDB = op.processDB.Raw(sql, values...)
+	return op
+}
+
+func (op *Operations) Select(query string, args ...any) DBOperations {
+	op.processDB = op.processDB.Select(query, args...)
+	return op
+}
+
+func (op *Operations) Joins(query string, args ...any) DBOperations {
+	op.processDB = op.processDB.Joins(query, args...)
+	return op
+}
+
+func (op *Operations) Where(conditions *Conditions) DBOperations {
+	op.processDB = conditions.where(op.processDB)
+	return op
+}
+
+func (op *Operations) Or(conditions *Conditions) DBOperations {
+	op.processDB = conditions.or(op.processDB)
+	return op
+}
+
+func (op *Operations) Having(conditions *Conditions) DBOperations {
+	op.processDB = conditions.having(op.processDB)
+	return op
+}
+
+func (op *Operations) GroupBy(groupBy string) DBOperations {
+	op.processDB = op.processDB.Group(groupBy)
+	return op
+}
+
+func (op *Operations) OrderBy(orderBy string) DBOperations {
+	op.processDB = op.processDB.Order(orderBy)
+	return op
+}
+
+func (op *Operations) Paging(pageNo int, pageSize int) DBOperations {
+	if pageNo != 0 && pageSize != 0 {
+		offset := -1
+
+		if pageNo == -1 || pageSize == -1 {
+			offset = -1
+			pageSize = -1
+		} else {
+			offset = (pageNo - 1) * pageSize
+		}
+
+		op.processDB = op.processDB.Offset(offset).Limit(pageSize)
+	}
+
+	return op
+}
+
+func (op *Operations) Create(tableRow *TableRow) error {
+	err := op.processDB.Create(tableRow.ToMap()).Error
+	if err != nil {
+		if strings.Contains(err.Error(), "SQLSTATE 23505") {
+			return ErrDBRecordHasExist
+		}
+
+		return err
+	}
+
+	return nil
+}
+
+func (op *Operations) CreateBatch(tableRows []TableRow) error {
+	tableRowMaps := make([]map[string]any, 0)
+	for _, tableRow := range tableRows {
+		tableRowMaps = append(tableRowMaps, tableRow.ToMap())
+	}
+
+	err := op.processDB.Create(tableRowMaps).Error
+	if err != nil {
+		if strings.Contains(err.Error(), "SQLSTATE 23505") {
+			return ErrDBRecordHasExist
+		}
+
+		return err
+	}
+
+	return nil
+}
+
+func (op *Operations) Delete() error {
+	return op.processDB.Delete(make(map[string]any)).Error
+}
+
+func (op *Operations) Updates(newTableRow *TableRow) error {
+	err := op.processDB.Updates(newTableRow.ToMap()).Error
+	if err != nil {
+		if strings.Contains(err.Error(), "SQLSTATE 23505") {
+			return ErrDBRecordHasExist
+		}
+
+		return err
+	}
+
+	return nil
+}
+
+func (op *Operations) UpdatesWithRowsAffected(newTableRow *TableRow) (int64, error) {
+	op.processDB = op.processDB.Updates(newTableRow.ToMap())
+	if op.processDB.Error != nil {
+		return 0, op.processDB.Error
+	}
+
+	return op.processDB.RowsAffected, nil
+}
+
+func (op *Operations) Rows(pageNo int, pageSize int) ([]TableRow, error) {
+	if pageNo != 0 && pageSize != 0 {
+		offset := (pageNo - 1) * pageSize
+		op.processDB = op.processDB.Offset(offset).Limit(pageSize)
+	}
+
+	defer func() {
+		op.processDB = op.processDB.Offset(-1).Limit(-1)
+	}()
+
+	tableRowMaps := make([]map[string]any, 0)
+	err := op.processDB.Scan(&tableRowMaps).Error
+	if err != nil {
+		return nil, err
+	}
+
+	tableRows := make([]TableRow, 0)
+	for _, tableRowMap := range tableRowMaps {
+		tableRows = append(tableRows, *NewTableRowFromMap(tableRowMap))
+	}
+
+	return tableRows, nil
+}
+
+func (op *Operations) Row() (*TableRow, error) {
+	valueMap := make(map[string]any)
+	err := op.processDB.Scan(&valueMap).Error
+	if err != nil {
+		return nil, err
+	}
+
+	if valueMap == nil || len(valueMap) == 0 {
+		return nil, ErrDBRecordNotExist
+	}
+
+	return NewTableRowFromMap(valueMap), nil
+}
+
+func (op *Operations) Count(count *int64) error {
+	return op.processDB.Count(count).Error
+}
+
+func (op *Operations) CheckExist() (bool, error) {
+	var count int64
+	err := op.processDB.Count(&count).Error
+	if err != nil {
+		return false, err
+	}
+
+	return count > 0, nil
+}
+
+func (op *Operations) CheckHasOnlyOne() (bool, error) {
+	var count int64
+	err := op.processDB.Count(&count).Error
+	if err != nil {
+		return false, err
+	}
+
+	return count == 1, nil
+}

+ 302 - 0
operations/table_row.go

@@ -0,0 +1,302 @@
+package operations
+
+import (
+	"reflect"
+	"time"
+)
+
+type TableRow struct {
+	row map[string]any
+}
+
+func NewTableRow() *TableRow {
+	return &TableRow{row: make(map[string]any)}
+}
+
+func NewTableRowFromMap(m map[string]any) *TableRow {
+	tableRow := NewTableRow()
+
+	for key, value := range m {
+		v := value
+
+		valueType := reflect.TypeOf(value)
+		if valueType.Kind() == reflect.Ptr {
+			v = reflect.ValueOf(value).Elem().Interface()
+		}
+
+		switch typedValue := v.(type) {
+		case string:
+			tableRow.row[key] = typedValue
+		case int:
+			tableRow.row[key] = uint64(typedValue)
+		case uint:
+			tableRow.row[key] = uint64(typedValue)
+		case int8:
+			tableRow.row[key] = uint64(typedValue)
+		case uint8:
+			tableRow.row[key] = uint64(typedValue)
+		case int16:
+			tableRow.row[key] = uint64(typedValue)
+		case uint16:
+			tableRow.row[key] = uint64(typedValue)
+		case int32:
+			tableRow.row[key] = uint64(typedValue)
+		case uint32:
+			tableRow.row[key] = uint64(typedValue)
+		case int64:
+			tableRow.row[key] = uint64(typedValue)
+		case uint64:
+			tableRow.row[key] = typedValue
+		case float32:
+			tableRow.row[key] = float64(typedValue)
+		case float64:
+			tableRow.row[key] = typedValue
+		case bool:
+			tableRow.row[key] = typedValue
+		case []byte:
+			tableRow.row[key] = typedValue
+		case time.Time:
+			tableRow.row[key] = typedValue
+		default:
+			panic("未支持的数据类型")
+		}
+	}
+
+	return tableRow
+}
+
+func (tableRow *TableRow) ToMap() map[string]any {
+	return tableRow.row
+}
+
+func (tableRow *TableRow) Len() int {
+	return len(tableRow.row)
+}
+
+func (tableRow *TableRow) Empty() bool {
+	return len(tableRow.row) == 0
+}
+
+func (tableRow *TableRow) AddColumnValueTime(columnName string, value time.Time) *TableRow {
+	tableRow.row[columnName] = value
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueBool(columnName string, value bool) *TableRow {
+	tableRow.row[columnName] = value
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueString(columnName string, value string) *TableRow {
+	tableRow.row[columnName] = value
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueBytes(columnName string, value []byte) *TableRow {
+	tableRow.row[columnName] = value
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueInt(columnName string, value int) *TableRow {
+	tableRow.row[columnName] = uint64(value)
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueInt8(columnName string, value int8) *TableRow {
+	tableRow.row[columnName] = uint64(value)
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueInt16(columnName string, value int16) *TableRow {
+	tableRow.row[columnName] = uint64(value)
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueInt32(columnName string, value int32) *TableRow {
+	tableRow.row[columnName] = uint64(value)
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueInt64(columnName string, value int64) *TableRow {
+	tableRow.row[columnName] = uint64(value)
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueUint(columnName string, value uint) *TableRow {
+	tableRow.row[columnName] = uint64(value)
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueUint8(columnName string, value uint8) *TableRow {
+	tableRow.row[columnName] = uint64(value)
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueUint16(columnName string, value uint16) *TableRow {
+	tableRow.row[columnName] = uint64(value)
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueUint32(columnName string, value uint32) *TableRow {
+	tableRow.row[columnName] = uint64(value)
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueUint64(columnName string, value uint64) *TableRow {
+	tableRow.row[columnName] = value
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueFloat32(columnName string, value float32) *TableRow {
+	tableRow.row[columnName] = float64(value)
+	return tableRow
+}
+
+func (tableRow *TableRow) AddColumnValueFloat64(columnName string, value float64) *TableRow {
+	tableRow.row[columnName] = value
+	return tableRow
+}
+
+func (tableRow *TableRow) ColumnValueTime(columnName string) time.Time {
+	value, ok := tableRow.row[columnName].(time.Time)
+	if !ok {
+		return time.Time{}
+	}
+
+	return value
+}
+
+func (tableRow *TableRow) ColumnValueBool(columnName string) bool {
+	value, ok := tableRow.row[columnName].(bool)
+	if !ok {
+		return false
+	}
+
+	return value
+}
+
+func (tableRow *TableRow) ColumnValueString(columnName string) string {
+	value, ok := tableRow.row[columnName].(string)
+	if !ok {
+		return ""
+	}
+
+	return value
+}
+
+func (tableRow *TableRow) ColumnValueBytes(columnName string) []byte {
+	value, ok := tableRow.row[columnName].([]byte)
+	if !ok {
+		return make([]byte, 0)
+	}
+
+	return value
+}
+
+func (tableRow *TableRow) ColumnValueInt(columnName string) int {
+	value, ok := tableRow.row[columnName].(uint64)
+	if !ok {
+		return 0
+	}
+
+	return int(value)
+}
+
+func (tableRow *TableRow) ColumnValueInt8(columnName string) int8 {
+	value, ok := tableRow.row[columnName].(uint64)
+	if !ok {
+		return 0
+	}
+
+	return int8(value)
+}
+
+func (tableRow *TableRow) ColumnValueInt16(columnName string) int16 {
+	value, ok := tableRow.row[columnName].(uint64)
+	if !ok {
+		return 0
+	}
+
+	return int16(value)
+}
+
+func (tableRow *TableRow) ColumnValueInt32(columnName string) int32 {
+	value, ok := tableRow.row[columnName].(uint64)
+	if !ok {
+		return 0
+	}
+
+	return int32(value)
+}
+
+func (tableRow *TableRow) ColumnValueInt64(columnName string) int64 {
+	value, ok := tableRow.row[columnName].(uint64)
+	if !ok {
+		return 0
+	}
+
+	return int64(value)
+}
+
+func (tableRow *TableRow) ColumnValueUint(columnName string) uint {
+	value, ok := tableRow.row[columnName].(uint64)
+	if !ok {
+		return 0
+	}
+
+	return uint(value)
+}
+
+func (tableRow *TableRow) ColumnValueUint8(columnName string) uint8 {
+	value, ok := tableRow.row[columnName].(uint64)
+	if !ok {
+		return 0
+	}
+
+	return uint8(value)
+}
+
+func (tableRow *TableRow) ColumnValueUint16(columnName string) uint16 {
+	value, ok := tableRow.row[columnName].(uint64)
+	if !ok {
+		return 0
+	}
+
+	return uint16(value)
+}
+
+func (tableRow *TableRow) ColumnValueUint32(columnName string) uint32 {
+	value, ok := tableRow.row[columnName].(uint64)
+	if !ok {
+		return 0
+	}
+
+	return uint32(value)
+}
+
+func (tableRow *TableRow) ColumnValueUint64(columnName string) uint64 {
+	value, ok := tableRow.row[columnName].(uint64)
+	if !ok {
+		return 0
+	}
+
+	return value
+}
+
+func (tableRow *TableRow) ColumnValueFloat32(columnName string) float32 {
+	value, ok := tableRow.row[columnName].(float64)
+	if !ok {
+		return 0
+	}
+
+	return float32(value)
+}
+
+func (tableRow *TableRow) ColumnValueFloat64(columnName string) float64 {
+	value, ok := tableRow.row[columnName].(float64)
+	if !ok {
+		return 0
+	}
+
+	return value
+}

+ 21 - 0
operations/transaction_operations.go

@@ -0,0 +1,21 @@
+package operations
+
+type TransactionOperations struct {
+	Operations
+}
+
+func (op *TransactionOperations) RollbackTransaction() {
+	defer func() {
+		op.processDB = op.initDB
+	}()
+
+	op.processDB.Rollback()
+}
+
+func (op *TransactionOperations) CommitTransaction() {
+	defer func() {
+		op.processDB = op.initDB
+	}()
+
+	op.processDB.Commit()
+}