yjp vor 1 Jahr
Ursprung
Commit
cbca3caf2b
56 geänderte Dateien mit 2509 neuen und 0 gelöschten Zeilen
  1. 19 0
      .gitignore
  2. 8 0
      .idea/.gitignore
  3. 9 0
      .idea/baize-demo.iml
  4. 8 0
      .idea/modules.xml
  5. 6 0
      .idea/vcs.xml
  6. 51 0
      assign_tag/main.go
  7. 80 0
      go.mod
  8. 237 0
      go.sum
  9. 7 0
      project/gateway/main.go
  10. 70 0
      project/server/application/application.go
  11. 92 0
      project/server/application/domain/class/entity.go
  12. 12 0
      project/server/application/domain/class/info.go
  13. 41 0
      project/server/application/domain/class/request_params.go
  14. 109 0
      project/server/application/domain/family/entity.go
  15. 12 0
      project/server/application/domain/family/info.go
  16. 47 0
      project/server/application/domain/family/request_params.go
  17. 58 0
      project/server/application/domain/hobby/entity.go
  18. 16 0
      project/server/application/domain/hobby/request_params.go
  19. 90 0
      project/server/application/domain/identity/entity.go
  20. 11 0
      project/server/application/domain/identity/info.go
  21. 38 0
      project/server/application/domain/identity/request_params.go
  22. 93 0
      project/server/application/domain/student/entity.go
  23. 11 0
      project/server/application/domain/student/info.go
  24. 75 0
      project/server/application/domain/student/request_params.go
  25. 36 0
      project/server/application/service/class.go
  26. 38 0
      project/server/application/service/class_and_student.go
  27. 28 0
      project/server/application/service/configuration.go
  28. 36 0
      project/server/application/service/family.go
  29. 36 0
      project/server/application/service/identity.go
  30. 25 0
      project/server/application/service/service.go
  31. 36 0
      project/server/application/service/student.go
  32. 39 0
      project/server/application/service/student_and_family.go
  33. 37 0
      project/server/application/service/student_and_hobby.go
  34. 37 0
      project/server/application/service/student_and_identity.go
  35. 38 0
      project/server/application/service/version.go
  36. 71 0
      project/server/config/config.go
  37. 21 0
      project/server/deployment/config/config.yaml
  38. 9 0
      project/server/deployment/data_service/apply_data_containers.ps1
  39. 10 0
      project/server/deployment/data_service/apply_data_containers.sh
  40. 20 0
      project/server/deployment/data_service/base.yaml
  41. 30 0
      project/server/deployment/data_service/data_containers/class.yaml
  42. 23 0
      project/server/deployment/data_service/data_containers/configuration.yaml
  43. 35 0
      project/server/deployment/data_service/data_containers/family.yaml
  44. 25 0
      project/server/deployment/data_service/data_containers/identity.yaml
  45. 35 0
      project/server/deployment/data_service/data_containers/student.yaml
  46. 16 0
      project/server/deployment/data_service/data_containers/student_and_hobby.yaml
  47. 16 0
      project/server/deployment/data_service/data_containers/student_and_identity.yaml
  48. 9 0
      project/server/deployment/data_service/delete_data_containers.ps1
  49. 10 0
      project/server/deployment/data_service/delete_data_containers.sh
  50. 100 0
      project/server/main.go
  51. 83 0
      project/server/test/configuration_test.go
  52. 186 0
      project/server/test/tool_kit.go
  53. 20 0
      project/server/test/version_test.go
  54. 102 0
      quick_start/main.go
  55. 51 0
      sql_mapping_tag/main.go
  56. 51 0
      sql_result_tag/main.go

+ 19 - 0
.gitignore

@@ -0,0 +1,19 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, build with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+.idea/
+.DS_Store
+**/bin
+
+/vendor/
+**/logs

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 9 - 0
.idea/baize-demo.iml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="Go" enabled="true" />
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/baize-demo.iml" filepath="$PROJECT_DIR$/.idea/baize-demo.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Git" />
+  </component>
+</project>

+ 51 - 0
assign_tag/main.go

@@ -0,0 +1,51 @@
+package main
+
+import (
+	"fmt"
+	assign2 "git.sxidc.com/go-framework/baize/framework/core/tag/assign"
+	"reflect"
+	"time"
+)
+
+type JsonBodyID struct {
+	ID string `assign:"toField:Id"`
+}
+
+type UpdateClassJsonBody struct {
+	JsonBodyID
+	Name        string `assign:"toField:Name"`
+	CreatedTime *time.Time
+	UpdatedTime *time.Time
+}
+
+type DomainID struct {
+	Id string
+}
+
+type ClassDomain struct {
+	*DomainID
+	Name        string
+	CreatedTime *time.Time
+}
+
+func main() {
+	class := new(ClassDomain)
+
+	err := assign2.UseTag(&UpdateClassJsonBody{}, class,
+		func(fromFieldName string, fromFieldElemValue reflect.Value, retFieldElementValue reflect.Value, assignTag *assign2.Tag) error {
+			fmt.Println("Field Name:", fromFieldName)
+			fmt.Println("Type:", fromFieldElemValue.Type().String())
+			if fromFieldElemValue.Kind() == reflect.String {
+				fmt.Printf("\"%+v\"\n", fromFieldElemValue.Interface())
+			} else {
+				fmt.Printf("%+v\n", fromFieldElemValue.Interface())
+			}
+			fmt.Printf("%+v\n", assignTag)
+			fmt.Println()
+
+			return nil
+		})
+	if err != nil {
+		panic(err)
+	}
+}

+ 80 - 0
go.mod

@@ -0,0 +1,80 @@
+module baize-demo
+
+go 1.22.3
+
+require (
+	git.sxidc.com/go-framework/baize v0.2.3
+	git.sxidc.com/go-tools/utils v1.5.15
+	git.sxidc.com/service-supports/fserr v0.3.5
+	git.sxidc.com/service-supports/fslog v0.5.9
+	git.sxidc.com/service-supports/scm-sdk v0.1.0
+	github.com/stretchr/testify v1.9.0
+	github.com/vrecan/death v3.0.1+incompatible
+)
+
+require (
+	git.sxidc.com/service-supports/websocket v1.3.1 // indirect
+	github.com/Masterminds/goutils v1.1.1 // indirect
+	github.com/Masterminds/semver/v3 v3.2.0 // indirect
+	github.com/Masterminds/sprig/v3 v3.2.3 // indirect
+	github.com/bytedance/sonic v1.11.6 // indirect
+	github.com/bytedance/sonic/loader v0.1.1 // indirect
+	github.com/cloudwego/base64x v0.1.4 // indirect
+	github.com/cloudwego/iasm v0.2.0 // indirect
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/gabriel-vasile/mimetype v1.4.3 // indirect
+	github.com/gin-contrib/sse v0.1.0 // indirect
+	github.com/gin-gonic/gin v1.10.0 // 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.20.0 // indirect
+	github.com/go-resty/resty/v2 v2.11.0 // indirect
+	github.com/goccy/go-json v0.10.2 // indirect
+	github.com/gogo/protobuf v1.3.0 // indirect
+	github.com/golang/protobuf v1.5.4 // indirect
+	github.com/google/uuid v1.6.0 // indirect
+	github.com/gopherjs/gopherjs v1.17.2 // indirect
+	github.com/gorilla/websocket v1.5.0 // indirect
+	github.com/huandu/xstrings v1.3.3 // indirect
+	github.com/iancoleman/strcase v0.3.0 // indirect
+	github.com/imdario/mergo v0.3.11 // 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/jtolds/gls v4.20.0+incompatible // indirect
+	github.com/klauspost/cpuid/v2 v2.2.7 // indirect
+	github.com/leodido/go-urn v1.4.0 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/mitchellh/copystructure v1.0.0 // indirect
+	github.com/mitchellh/reflectwalk v1.0.0 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/mwitkow/go-proto-validators v0.3.2 // indirect
+	github.com/olahol/melody v1.2.1 // indirect
+	github.com/pelletier/go-toml/v2 v2.2.2 // indirect
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/puzpuzpuz/xsync v1.5.2 // indirect
+	github.com/satori/go.uuid v1.2.0 // indirect
+	github.com/shopspring/decimal v1.2.0 // indirect
+	github.com/smarty/assertions v1.16.0 // indirect
+	github.com/spf13/cast v1.3.1 // indirect
+	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
+	github.com/ugorji/go/codec v1.2.12 // indirect
+	go.uber.org/multierr v1.11.0 // indirect
+	go.uber.org/zap v1.27.0 // indirect
+	golang.org/x/arch v0.8.0 // indirect
+	golang.org/x/crypto v0.23.0 // indirect
+	golang.org/x/net v0.25.0 // indirect
+	golang.org/x/sys v0.20.0 // indirect
+	golang.org/x/text v0.15.0 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
+	google.golang.org/grpc v1.64.0 // indirect
+	google.golang.org/protobuf v1.34.1 // indirect
+	gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+	gorm.io/driver/postgres v1.5.7 // indirect
+	gorm.io/gorm v1.25.10 // indirect
+)

+ 237 - 0
go.sum

@@ -0,0 +1,237 @@
+git.sxidc.com/go-framework/baize v0.2.3 h1:GQ32gwWMQnfB+wkdfhhlPcBYuOdIIckuSXO23bVdNKs=
+git.sxidc.com/go-framework/baize v0.2.3/go.mod h1:GJNNrdlwli5qpOU9eUbRRlxUbtkok9Zj0vvqlFEsujA=
+git.sxidc.com/go-tools/utils v1.5.15 h1:7xs/EM8XZyKycrSSHcPZ6wvyYs+v8uWQ7ZmPP/fHyFI=
+git.sxidc.com/go-tools/utils v1.5.15/go.mod h1:fkobAXFpOMTvkZ82TQXWcpsayePcyk/MS5TN6GTlRDg=
+git.sxidc.com/service-supports/fserr v0.3.5 h1:1SDC60r3FIDd2iRq/oHRLK4OMa1gf67h9B7kierKTUE=
+git.sxidc.com/service-supports/fserr v0.3.5/go.mod h1:8U+W/ulZIGVPFojV6cE18shkGXqvaICuzaxIJpOcBqI=
+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=
+git.sxidc.com/service-supports/scm-sdk v0.1.0 h1:198qs/XxffOrHioKEWXyPfsQLoO3E8Ifj4idOWJxIe0=
+git.sxidc.com/service-supports/scm-sdk v0.1.0/go.mod h1:F0DLFok92zElZZRxJujSk6KmRoVGN8bkrbXFdq19uwI=
+git.sxidc.com/service-supports/websocket v1.3.1 h1:1mRfUwvpg0QA2JVKVMK8YJ/B33HFpDhY9srqroIuNGc=
+git.sxidc.com/service-supports/websocket v1.3.1/go.mod h1:YqEZXkN8ZFzUp01tDlekgIJJ0Yz+67d6eTXyA0ZIkgM=
+github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
+github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
+github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
+github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
+github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
+github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
+github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
+github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
+github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
+github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
+github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs=
+github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo=
+github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
+github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
+github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
+github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
+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.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
+github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
+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.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
+github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
+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.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8=
+github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
+github.com/go-resty/resty/v2 v2.11.0 h1:i7jMfNOJYMp69lq7qozJP+bjgzfAzeOhuGlyDrqxT/8=
+github.com/go-resty/resty/v2 v2.11.0/go.mod h1:iiP/OpA0CkcL3IGt1O0+/SIItFUbkkyw5BGXiVdTu+A=
+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/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE=
+github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
+github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
+github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
+github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
+github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI=
+github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
+github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
+github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+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/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
+github.com/klauspost/cpuid/v2 v2.2.7/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.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
+github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
+github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
+github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
+github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+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/mwitkow/go-proto-validators v0.3.2 h1:qRlmpTzm2pstMKKzTdvwPCF5QfBNURSlAgN/R+qbKos=
+github.com/mwitkow/go-proto-validators v0.3.2/go.mod h1:ej0Qp0qMgHN/KtDyUt+Q1/tA7a5VarXUOUxD+oeD30w=
+github.com/olahol/melody v1.2.1 h1:xdwRkzHxf+B0w4TKbGpUSSkV516ZucQZJIWLztOWICQ=
+github.com/olahol/melody v1.2.1/go.mod h1:GgkTl6Y7yWj/HtfD48Q5vLKPVoZOH+Qqgfa7CvJgJM4=
+github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
+github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
+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/puzpuzpuz/xsync v1.5.2 h1:yRAP4wqSOZG+/4pxJ08fPTwrfL0IzE/LKQ/cw509qGY=
+github.com/puzpuzpuz/xsync v1.5.2/go.mod h1:K98BYhX3k1dQ2M63t1YNVDanbwUPmBCAhNmVrrxfiGg=
+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/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
+github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/smarty/assertions v1.16.0 h1:EvHNkdRA4QHMrn75NZSoUQ/mAUXAYWfatfB01yTCzfY=
+github.com/smarty/assertions v1.16.0/go.mod h1:duaaFdCS0K9dnoM50iyek/eYINOZ64gbh1Xlf6LG7AI=
+github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
+github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
+github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
+github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+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/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+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.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+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.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
+github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+github.com/vrecan/death v3.0.1+incompatible h1:hYRRqrdyoUAbymk2KJ8tNHmZFKcVeThRUySCqwC5Itg=
+github.com/vrecan/death v3.0.1+incompatible/go.mod h1:ektTae4lwvcXJ7pytrLb2N0w7mwhzmu+f5vRHYzy33E=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+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.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
+go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
+golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+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.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
+golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
+google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
+google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
+google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
+google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+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.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+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.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s=
+gorm.io/gorm v1.25.10/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=

+ 7 - 0
project/gateway/main.go

@@ -0,0 +1,7 @@
+package main
+
+import "git.sxidc.com/go-framework/baize/convenient/gateway"
+
+func main() {
+	gateway.NewGateway()
+}

+ 70 - 0
project/server/application/application.go

@@ -0,0 +1,70 @@
+package application
+
+import (
+	"git.sxidc.com/go-framework/baize"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/service"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/config"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+	"net/http"
+)
+
+var appInstance *application.App
+
+func NewApp() {
+	if appInstance != nil {
+		return
+	}
+
+	appInstance = baize.NewApplication(config.GetConfig().ApplicationConfig)
+
+	// 注册Router
+	appInstance.Api().PrefixRouter().RegisterVersionedRouter("v1")
+}
+
+func DestroyApp() {
+	if appInstance == nil {
+		return
+	}
+
+	baize.DestroyApplication(appInstance)
+	appInstance = nil
+}
+
+func Start() error {
+	// 初始化服务
+	for _, svc := range service.RegisteredServices {
+		err := svc.Init(appInstance)
+		if err != nil {
+			return err
+		}
+	}
+
+	err := appInstance.Start()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func Finish() error {
+	err := appInstance.Finish()
+	if err != nil {
+		return err
+	}
+
+	// 销毁服务
+	for _, svc := range service.RegisteredServices {
+		err := svc.Destroy()
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func ServerHttpForTest(w http.ResponseWriter, req *http.Request) {
+	appInstance.Api().RootRouter().(*api.RootRouter).ServerHttp(w, req)
+}

+ 92 - 0
project/server/application/domain/class/entity.go

@@ -0,0 +1,92 @@
+package class
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/core/domain/entity"
+	"git.sxidc.com/go-tools/utils/strutils"
+	"git.sxidc.com/service-supports/fserr"
+)
+
+const (
+	ColumnName       = "name"
+	ColumnStudentNum = "student_num"
+)
+
+const (
+	fieldNameMaxLen = 128
+)
+
+type Entity struct {
+	entity.Base
+	Name       string   `sqlmapping:"column:name" sqlresult:"column:name"`
+	StudentNum int      `sqlmapping:"column:student_num;updateClear;" sqlresult:"column:student_num"`
+	StudentIDs []string `sqlmapping:"-" sqlresult:"-"`
+	entity.TimeFields
+}
+
+func (e *Entity) DomainCNName() string {
+	return "班级"
+}
+
+func (e *Entity) DomainCamelName() string {
+	return "Class"
+}
+
+func (e *Entity) CheckFieldID() error {
+	return e.Base.CheckFieldID(e.DomainCNName())
+}
+
+func (e *Entity) ForCreate() error {
+	err := e.CheckFieldID()
+	if err != nil {
+		return err
+	}
+
+	err = e.checkFieldName()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (e *Entity) ForDelete() error {
+	return e.CheckFieldID()
+}
+
+func (e *Entity) ForUpdate() error {
+	err := e.CheckFieldID()
+	if err != nil {
+		return err
+	}
+
+	err = e.checkUpdateFields()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (e *Entity) checkFieldName() error {
+	if strutils.IsStringEmpty(e.Name) {
+		return fserr.New(e.DomainCNName() + "名称为空")
+	}
+
+	if len(e.Name) > fieldNameMaxLen {
+		return fserr.New(e.DomainCNName() + "名称超出限定长度")
+	}
+
+	return nil
+}
+
+func (e *Entity) checkUpdateFields() error {
+	if strutils.AllBlank(e.Name) {
+		return fserr.New(e.DomainCNName() + "没有传递需要更新的字段")
+	}
+
+	if strutils.IsStringNotEmpty(e.Name) && len(e.Name) > fieldNameMaxLen {
+		return fserr.New(e.DomainCNName() + "名称超出限定长度")
+	}
+
+	return nil
+}

+ 12 - 0
project/server/application/domain/class/info.go

@@ -0,0 +1,12 @@
+package class
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+type Info struct {
+	application.InfoIDField
+	Name       string `json:"name" sqlresult:"column:name"`
+	StudentNum int    `json:"studentNum" sqlresult:"column:student_num"`
+	application.InfoTimeFields
+}

+ 41 - 0
project/server/application/domain/class/request_params.go

@@ -0,0 +1,41 @@
+package class
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/binding/request"
+)
+
+type (
+	CreateJsonBody struct {
+		Name       string `json:"name" binding:"required" assign:"toField:Name"`
+		StudentNum int    `json:"studentNum" binding:"required" assign:"toField:StudentNum"`
+	}
+
+	DeleteQueryParams struct {
+		request.IDQueryParam
+	}
+
+	UpdateJsonBody struct {
+		request.IDJsonBody
+		Name       string `json:"name" assign:"toField:Name"`
+		StudentNum int    `json:"studentNum" assign:"toField:StudentNum"`
+	}
+
+	QueryQueryParams struct {
+		request.BaseQueryParams
+		Name       string `form:"name" assign:"toField:Name"`
+		StudentNum int    `form:"studentNum" assign:"toField:StudentNum"`
+	}
+
+	GetByIDQueryParams struct {
+		request.IDQueryParam
+	}
+
+	UpdateStudentsOfClassJsonBody struct {
+		request.IDJsonBody
+		StudentIDs []string `json:"studentIds" assign:"toField:StudentIDs"`
+	}
+
+	QueryStudentsOfClassQueryParams struct {
+		request.BaseQueryWithIDParams
+	}
+)

+ 109 - 0
project/server/application/domain/family/entity.go

@@ -0,0 +1,109 @@
+package family
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/core/domain/entity"
+	"git.sxidc.com/go-tools/utils/strutils"
+	"git.sxidc.com/service-supports/fserr"
+)
+
+const (
+	ColumnFather = "father"
+	ColumnMother = "mother"
+)
+
+const (
+	fieldFatherMaxLen = 128
+	fieldMotherMaxLen = 128
+)
+
+type Entity struct {
+	entity.Base
+	Father    string `sqlmapping:"column:father" sqlresult:"column:father"`
+	Mother    string `sqlmapping:"column:mother" sqlresult:"column:mother"`
+	StudentID string `sqlmapping:"column:student_id" sqlresult:"column:student_id"`
+	entity.TimeFields
+}
+
+func (e *Entity) DomainCNName() string {
+	return "家庭"
+}
+
+func (e *Entity) DomainCamelName() string {
+	return "Family"
+}
+
+func (e *Entity) CheckFieldID() error {
+	return e.Base.CheckFieldID(e.DomainCNName())
+}
+
+func (e *Entity) ForCreate() error {
+	err := e.CheckFieldID()
+	if err != nil {
+		return err
+	}
+
+	err = e.checkFieldFather()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (e *Entity) ForDelete() error {
+	return e.CheckFieldID()
+}
+
+func (e *Entity) ForUpdate() error {
+	err := e.CheckFieldID()
+	if err != nil {
+		return err
+	}
+
+	err = e.checkUpdateFields()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (e *Entity) checkFieldFather() error {
+	if strutils.IsStringEmpty(e.Father) {
+		return fserr.New(e.DomainCNName() + "父亲姓名为空")
+	}
+
+	if len(e.Father) > fieldFatherMaxLen {
+		return fserr.New(e.DomainCNName() + "父亲姓名超出限定长度")
+	}
+
+	return nil
+}
+
+func (e *Entity) checkFieldMother() error {
+	if strutils.IsStringEmpty(e.Mother) {
+		return fserr.New(e.DomainCNName() + "母亲姓名为空")
+	}
+
+	if len(e.Mother) > fieldMotherMaxLen {
+		return fserr.New(e.DomainCNName() + "母亲姓名超出限定长度")
+	}
+
+	return nil
+}
+
+func (e *Entity) checkUpdateFields() error {
+	if strutils.AllBlank(e.Father, e.Mother) {
+		return fserr.New(e.DomainCNName() + "没有传递需要更新的字段")
+	}
+
+	if strutils.IsStringNotEmpty(e.Father) && len(e.Father) > fieldFatherMaxLen {
+		return fserr.New(e.DomainCNName() + "父亲姓名超出限定长度")
+	}
+
+	if strutils.IsStringNotEmpty(e.Mother) && len(e.Mother) > fieldMotherMaxLen {
+		return fserr.New(e.DomainCNName() + "母亲姓名超出限定长度")
+	}
+
+	return nil
+}

+ 12 - 0
project/server/application/domain/family/info.go

@@ -0,0 +1,12 @@
+package family
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+type Info struct {
+	application.InfoIDField
+	Father string `json:"father" sqlresult:"column:father"`
+	Mother string `json:"mother" sqlresult:"column:mother"`
+	application.InfoTimeFields
+}

+ 47 - 0
project/server/application/domain/family/request_params.go

@@ -0,0 +1,47 @@
+package family
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/binding/request"
+)
+
+type (
+	CreateJsonBody struct {
+		Father string `json:"father" binding:"required" assign:"toField:Father"`
+		Mother string `json:"mother" binding:"required" assign:"toField:Mother"`
+	}
+
+	DeleteQueryParams struct {
+		request.IDQueryParam
+	}
+
+	UpdateJsonBody struct {
+		request.IDJsonBody
+		Father string `json:"father" assign:"toField:Father"`
+		Mother string `json:"mother" assign:"toField:Mother"`
+	}
+
+	QueryQueryParams struct {
+		request.BaseQueryParams
+		Father string `form:"father" assign:"toField:Father"`
+		Mother string `form:"mother" assign:"toField:Mother"`
+	}
+
+	GetByIDQueryParams struct {
+		request.IDQueryParam
+	}
+
+	UpdateStudentOfFamilyJsonBody struct {
+		request.IDJsonBody
+		StudentID string `json:"studentId" assign:"toField:StudentID"`
+	}
+
+	QueryStudentOfFamilyQueryParams struct {
+		request.IDQueryParam
+	}
+
+	QueryFamilyWithStudentQueryParams struct {
+		request.BaseQueryParams
+		Father string `form:"father" assign:"toField:Father"`
+		Mother string `form:"mother" assign:"toField:Mother"`
+	}
+)

+ 58 - 0
project/server/application/domain/hobby/entity.go

@@ -0,0 +1,58 @@
+package hobby
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/core/domain/entity"
+	"git.sxidc.com/go-tools/utils/strutils"
+)
+
+type Entity struct {
+	ID         string   `sqlmapping:"-" sqlresult:"-"`
+	StudentIDs []string `sqlmapping:"-" sqlresult:"-"`
+}
+
+func (e *Entity) DBSchema() string {
+	return ""
+}
+
+func (e *Entity) GenerateID() error {
+	e.ID = strutils.SimpleUUID()
+	return nil
+}
+
+func (e *Entity) GetID() string {
+	return e.ID
+}
+
+func (e *Entity) CheckFieldID() error {
+	return entity.CheckID(e.DomainCNName(), "ID", e.ID)
+}
+
+func (e *Entity) DomainCNName() string {
+	return "爱好"
+}
+
+func (e *Entity) DomainCamelName() string {
+	return "Hobby"
+}
+
+func (e *Entity) ForCreate() error {
+	err := e.CheckFieldID()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (e *Entity) ForDelete() error {
+	return e.CheckFieldID()
+}
+
+func (e *Entity) ForUpdate() error {
+	err := e.CheckFieldID()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}

+ 16 - 0
project/server/application/domain/hobby/request_params.go

@@ -0,0 +1,16 @@
+package hobby
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/binding/request"
+)
+
+type (
+	UpdateStudentsOfHobbyJsonBody struct {
+		request.IDJsonBody
+		StudentIDs []string `json:"studentIds" assign:"toField:StudentIDs"`
+	}
+
+	QueryStudentsOfHobbyQueryParams struct {
+		request.BaseQueryWithIDParams
+	}
+)

+ 90 - 0
project/server/application/domain/identity/entity.go

@@ -0,0 +1,90 @@
+package identity
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/core/domain/entity"
+	"git.sxidc.com/go-tools/utils/strutils"
+	"git.sxidc.com/service-supports/fserr"
+)
+
+const (
+	ColumnName = "name"
+)
+
+const (
+	fieldNameMaxLen = 128
+)
+
+type Entity struct {
+	entity.Base
+	Name       string   `sqlmapping:"column:name" sqlresult:"column:name"`
+	StudentIDs []string `sqlmapping:"-" sqlresult:"-"`
+	entity.TimeFields
+}
+
+func (e *Entity) DomainCNName() string {
+	return "身份"
+}
+
+func (e *Entity) DomainCamelName() string {
+	return "Identity"
+}
+
+func (e *Entity) CheckFieldID() error {
+	return e.Base.CheckFieldID(e.DomainCNName())
+}
+
+func (e *Entity) ForCreate() error {
+	err := e.CheckFieldID()
+	if err != nil {
+		return err
+	}
+
+	err = e.checkFieldName()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (e *Entity) ForDelete() error {
+	return e.CheckFieldID()
+}
+
+func (e *Entity) ForUpdate() error {
+	err := e.CheckFieldID()
+	if err != nil {
+		return err
+	}
+
+	err = e.checkUpdateFields()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (e *Entity) checkFieldName() error {
+	if strutils.IsStringEmpty(e.Name) {
+		return fserr.New(e.DomainCNName() + "名称为空")
+	}
+
+	if len(e.Name) > fieldNameMaxLen {
+		return fserr.New(e.DomainCNName() + "名称超出限定长度")
+	}
+
+	return nil
+}
+
+func (e *Entity) checkUpdateFields() error {
+	if strutils.AllBlank(e.Name) {
+		return fserr.New(e.DomainCNName() + "没有传递需要更新的字段")
+	}
+
+	if strutils.IsStringNotEmpty(e.Name) && len(e.Name) > fieldNameMaxLen {
+		return fserr.New(e.DomainCNName() + "名称超出限定长度")
+	}
+
+	return nil
+}

+ 11 - 0
project/server/application/domain/identity/info.go

@@ -0,0 +1,11 @@
+package identity
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+type Info struct {
+	application.InfoIDField
+	Name string `json:"name" sqlresult:"column:name"`
+	application.InfoTimeFields
+}

+ 38 - 0
project/server/application/domain/identity/request_params.go

@@ -0,0 +1,38 @@
+package identity
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/binding/request"
+)
+
+type (
+	CreateJsonBody struct {
+		Name string `json:"name" binding:"required" assign:"toField:Name"`
+	}
+
+	DeleteQueryParams struct {
+		request.IDQueryParam
+	}
+
+	UpdateJsonBody struct {
+		request.IDJsonBody
+		Name string `json:"name" assign:"toField:Name"`
+	}
+
+	QueryQueryParams struct {
+		request.BaseQueryParams
+		Name string `form:"name" assign:"toField:Name"`
+	}
+
+	GetByIDQueryParams struct {
+		request.IDQueryParam
+	}
+
+	UpdateStudentsOfIdentityJsonBody struct {
+		request.IDJsonBody
+		StudentIDs []string `json:"studentIds" assign:"toField:StudentIDs"`
+	}
+
+	QueryStudentsOfIdentityQueryParams struct {
+		request.BaseQueryWithIDParams
+	}
+)

+ 93 - 0
project/server/application/domain/student/entity.go

@@ -0,0 +1,93 @@
+package student
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/core/domain/entity"
+	"git.sxidc.com/go-tools/utils/strutils"
+	"git.sxidc.com/service-supports/fserr"
+)
+
+const (
+	ColumnName = "name"
+)
+
+const (
+	fieldNameMaxLen = 128
+)
+
+type Entity struct {
+	entity.Base
+	Name        string   `sqlmapping:"column:name" sqlresult:"column:name"`
+	FamilyID    string   `sqlmapping:"column:family_id" sqlresult:"column:family_id"`
+	ClassID     string   `sqlmapping:"column:class_id" sqlresult:"column:class_id"`
+	IdentityIDs []string `sqlmapping:"-" sqlresult:"-"`
+	HobbyIDs    []string `sqlmapping:"-" sqlresult:"-"`
+	entity.TimeFields
+}
+
+func (e *Entity) DomainCNName() string {
+	return "学生"
+}
+
+func (e *Entity) DomainCamelName() string {
+	return "Student"
+}
+
+func (e *Entity) CheckFieldID() error {
+	return e.Base.CheckFieldID(e.DomainCNName())
+}
+
+func (e *Entity) ForCreate() error {
+	err := e.CheckFieldID()
+	if err != nil {
+		return err
+	}
+
+	err = e.checkFieldName()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (e *Entity) ForDelete() error {
+	return e.CheckFieldID()
+}
+
+func (e *Entity) ForUpdate() error {
+	err := e.CheckFieldID()
+	if err != nil {
+		return err
+	}
+
+	err = e.checkUpdateFields()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (e *Entity) checkFieldName() error {
+	if strutils.IsStringEmpty(e.Name) {
+		return fserr.New(e.DomainCNName() + "姓名为空")
+	}
+
+	if len(e.Name) > fieldNameMaxLen {
+		return fserr.New(e.DomainCNName() + "姓名超出限定长度")
+	}
+
+	return nil
+}
+
+func (e *Entity) checkUpdateFields() error {
+	if strutils.AllBlank(e.Name) {
+		return fserr.New(e.DomainCNName() + "没有传递需要更新的字段")
+	}
+
+	if strutils.IsStringNotEmpty(e.Name) && len(e.Name) > fieldNameMaxLen {
+		return fserr.New(e.DomainCNName() + "姓名超出限定长度")
+	}
+
+	return nil
+}

+ 11 - 0
project/server/application/domain/student/info.go

@@ -0,0 +1,11 @@
+package student
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+type Info struct {
+	application.InfoIDField
+	Name string `json:"name" sqlresult:"column:name"`
+	application.InfoTimeFields
+}

+ 75 - 0
project/server/application/domain/student/request_params.go

@@ -0,0 +1,75 @@
+package student
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/binding/request"
+)
+
+type (
+	CreateJsonBody struct {
+		Name string `json:"name" binding:"required" assign:"toField:Name"`
+	}
+
+	DeleteQueryParams struct {
+		request.IDQueryParam
+	}
+
+	UpdateJsonBody struct {
+		request.IDJsonBody
+		Name string `json:"name" assign:"toField:Name"`
+	}
+
+	QueryQueryParams struct {
+		request.BaseQueryParams
+		Name string `form:"name" assign:"toField:Name"`
+	}
+
+	GetByIDQueryParams struct {
+		request.IDQueryParam
+	}
+
+	UpdateFamilyOfStudentJsonBody struct {
+		request.IDJsonBody
+		FamilyID string `json:"familyId" assign:"toField:FamilyID"`
+	}
+
+	QueryFamilyOfStudentQueryParams struct {
+		request.IDQueryParam
+	}
+
+	QueryStudentWithFamilyQueryParams struct {
+		request.BaseQueryParams
+		Name string `form:"name" assign:"toField:Name"`
+	}
+
+	UpdateIdentitiesOfStudentJsonBody struct {
+		request.IDJsonBody
+		IdentityIDs []string `json:"identityIds" assign:"toField:IdentityIDs"`
+	}
+
+	QueryIdentitiesOfStudentQueryParams struct {
+		request.BaseQueryWithIDParams
+	}
+
+	UpdateHobbiesOfStudentJsonBody struct {
+		request.IDJsonBody
+		HobbyIDs []string `json:"hobbyIds" assign:"toField:HobbyIDs"`
+	}
+
+	QueryHobbiesOfStudentQueryParams struct {
+		request.BaseQueryWithIDParams
+	}
+
+	UpdateClassOfStudentJsonBody struct {
+		request.IDJsonBody
+		ClassID string `json:"classId" assign:"toField:ClassID"`
+	}
+
+	QueryClassOfStudentQueryParams struct {
+		request.BaseQueryWithIDParams
+	}
+
+	QueryStudentWithClassQueryParams struct {
+		request.BaseQueryParams
+		Name string `form:"name" assign:"toField:Name"`
+	}
+)

+ 36 - 0
project/server/application/service/class.go

@@ -0,0 +1,36 @@
+package service
+
+import (
+	"git.sxidc.com/go-framework/baize/convenient/entity_crud"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/domain/class"
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+var classService = &ClassService{}
+
+type ClassService struct{}
+
+func (svc *ClassService) Init(appInstance *application.App) error {
+	svc.v1(appInstance)
+	return nil
+}
+
+func (svc *ClassService) Destroy() error {
+	return nil
+}
+
+func (svc *ClassService) v1(appInstance *application.App) {
+	v1Binder := binding.NewBinder(appInstance.ChooseRouter(api.RouterPrefix, "v1"), appInstance.Infrastructure())
+
+	entity_crud.BindSimple[class.Info](v1Binder, &entity_crud.Simple[class.Info]{
+		Entity:             &class.Entity{},
+		Schema:             dbSchema,
+		CreateJsonBody:     &class.CreateJsonBody{},
+		DeleteQueryParams:  &class.DeleteQueryParams{},
+		UpdateJsonBody:     &class.UpdateJsonBody{},
+		QueryQueryParams:   &class.QueryQueryParams{},
+		GetByIDQueryParams: &class.GetByIDQueryParams{},
+	})
+}

+ 38 - 0
project/server/application/service/class_and_student.go

@@ -0,0 +1,38 @@
+package service
+
+import (
+	"git.sxidc.com/go-framework/baize/convenient/relation/one2many"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/domain/class"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/domain/student"
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+var classAndStudentService = &ClassAndStudentService{}
+
+type ClassAndStudentService struct{}
+
+func (svc *ClassAndStudentService) Init(appInstance *application.App) error {
+	svc.v1(appInstance)
+	return nil
+}
+
+func (svc *ClassAndStudentService) Destroy() error {
+	return nil
+}
+
+func (svc *ClassAndStudentService) v1(appInstance *application.App) {
+	v1Binder := binding.NewBinder(appInstance.ChooseRouter(api.RouterPrefix, "v1"), appInstance.Infrastructure())
+
+	one2many.BindSimple(v1Binder, &one2many.Simple[class.Info, student.Info]{
+		Left:                          &class.Entity{},
+		Right:                         &student.Entity{},
+		Schema:                        dbSchema,
+		LeftUpdateJsonBody:            &class.UpdateStudentsOfClassJsonBody{},
+		LeftQueryQueryParams:          &class.QueryStudentsOfClassQueryParams{},
+		RightUpdateJsonBody:           &student.UpdateClassOfStudentJsonBody{},
+		RightQueryQueryParams:         &student.QueryClassOfStudentQueryParams{},
+		RightQueryWithLeftQueryParams: &student.QueryStudentWithClassQueryParams{},
+	})
+}

+ 28 - 0
project/server/application/service/configuration.go

@@ -0,0 +1,28 @@
+package service
+
+import (
+	"git.sxidc.com/go-framework/baize/convenient/domain/configuration"
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+var configurationService = &ConfigurationService{}
+
+type ConfigurationService struct{}
+
+func (svc *ConfigurationService) Init(appInstance *application.App) error {
+	svc.prefixRoot(appInstance)
+	return nil
+}
+
+func (svc *ConfigurationService) Destroy() error {
+	return nil
+}
+
+func (svc *ConfigurationService) prefixRoot(appInstance *application.App) {
+	prefixRootBinder := binding.NewBinder(appInstance.ChooseRouter(api.RouterPrefix, ""), appInstance.Infrastructure())
+	configuration.BindConfiguration(prefixRootBinder, &configuration.Simple{
+		Schema: dbSchema,
+	})
+}

+ 36 - 0
project/server/application/service/family.go

@@ -0,0 +1,36 @@
+package service
+
+import (
+	"git.sxidc.com/go-framework/baize/convenient/entity_crud"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/domain/family"
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+var familyService = &FamilyService{}
+
+type FamilyService struct{}
+
+func (svc *FamilyService) Init(appInstance *application.App) error {
+	svc.v1(appInstance)
+	return nil
+}
+
+func (svc *FamilyService) Destroy() error {
+	return nil
+}
+
+func (svc *FamilyService) v1(appInstance *application.App) {
+	v1Binder := binding.NewBinder(appInstance.ChooseRouter(api.RouterPrefix, "v1"), appInstance.Infrastructure())
+
+	entity_crud.BindSimple[family.Info](v1Binder, &entity_crud.Simple[family.Info]{
+		Entity:             &family.Entity{},
+		Schema:             dbSchema,
+		CreateJsonBody:     &family.CreateJsonBody{},
+		DeleteQueryParams:  &family.DeleteQueryParams{},
+		UpdateJsonBody:     &family.UpdateJsonBody{},
+		QueryQueryParams:   &family.QueryQueryParams{},
+		GetByIDQueryParams: &family.GetByIDQueryParams{},
+	})
+}

+ 36 - 0
project/server/application/service/identity.go

@@ -0,0 +1,36 @@
+package service
+
+import (
+	"git.sxidc.com/go-framework/baize/convenient/entity_crud"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/domain/identity"
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+var identityService = &IdentityService{}
+
+type IdentityService struct{}
+
+func (svc *IdentityService) Init(appInstance *application.App) error {
+	svc.v1(appInstance)
+	return nil
+}
+
+func (svc *IdentityService) Destroy() error {
+	return nil
+}
+
+func (svc *IdentityService) v1(appInstance *application.App) {
+	v1Binder := binding.NewBinder(appInstance.ChooseRouter(api.RouterPrefix, "v1"), appInstance.Infrastructure())
+
+	entity_crud.BindSimple[identity.Info](v1Binder, &entity_crud.Simple[identity.Info]{
+		Entity:             &identity.Entity{},
+		Schema:             dbSchema,
+		CreateJsonBody:     &identity.CreateJsonBody{},
+		DeleteQueryParams:  &identity.DeleteQueryParams{},
+		UpdateJsonBody:     &identity.UpdateJsonBody{},
+		QueryQueryParams:   &identity.QueryQueryParams{},
+		GetByIDQueryParams: &identity.GetByIDQueryParams{},
+	})
+}

+ 25 - 0
project/server/application/service/service.go

@@ -0,0 +1,25 @@
+package service
+
+import "git.sxidc.com/go-framework/baize/framework/core/application"
+
+const (
+	dbSchema = "test"
+)
+
+type Service interface {
+	Init(appInstance *application.App) error
+	Destroy() error
+}
+
+var RegisteredServices = []Service{
+	versionService,
+	configurationService,
+	classService,
+	studentService,
+	identityService,
+	familyService,
+	classAndStudentService,
+	studentAndFamilyService,
+	studentAndIdentityService,
+	studentAndHobbyService,
+}

+ 36 - 0
project/server/application/service/student.go

@@ -0,0 +1,36 @@
+package service
+
+import (
+	"git.sxidc.com/go-framework/baize/convenient/entity_crud"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/domain/student"
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+var studentService = &StudentService{}
+
+type StudentService struct{}
+
+func (svc *StudentService) Init(appInstance *application.App) error {
+	svc.v1(appInstance)
+	return nil
+}
+
+func (svc *StudentService) Destroy() error {
+	return nil
+}
+
+func (svc *StudentService) v1(appInstance *application.App) {
+	v1Binder := binding.NewBinder(appInstance.ChooseRouter(api.RouterPrefix, "v1"), appInstance.Infrastructure())
+
+	entity_crud.BindSimple[student.Info](v1Binder, &entity_crud.Simple[student.Info]{
+		Entity:             &student.Entity{},
+		Schema:             dbSchema,
+		CreateJsonBody:     &student.CreateJsonBody{},
+		DeleteQueryParams:  &student.DeleteQueryParams{},
+		UpdateJsonBody:     &student.UpdateJsonBody{},
+		QueryQueryParams:   &student.QueryQueryParams{},
+		GetByIDQueryParams: &student.GetByIDQueryParams{},
+	})
+}

+ 39 - 0
project/server/application/service/student_and_family.go

@@ -0,0 +1,39 @@
+package service
+
+import (
+	"git.sxidc.com/go-framework/baize/convenient/relation/one2one"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/domain/family"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/domain/student"
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+var studentAndFamilyService = &StudentAndFamilyService{}
+
+type StudentAndFamilyService struct{}
+
+func (svc *StudentAndFamilyService) Init(appInstance *application.App) error {
+	svc.v1(appInstance)
+	return nil
+}
+
+func (svc *StudentAndFamilyService) Destroy() error {
+	return nil
+}
+
+func (svc *StudentAndFamilyService) v1(appInstance *application.App) {
+	v1Binder := binding.NewBinder(appInstance.ChooseRouter(api.RouterPrefix, "v1"), appInstance.Infrastructure())
+
+	one2one.BindSimple(v1Binder, &one2one.Simple[student.Info, family.Info]{
+		Left:                          &student.Entity{},
+		Right:                         &family.Entity{},
+		Schema:                        dbSchema,
+		LeftUpdateJsonBody:            &student.UpdateFamilyOfStudentJsonBody{},
+		LeftQueryQueryParams:          &student.QueryFamilyOfStudentQueryParams{},
+		LeftQueryWithRightQueryParams: &student.QueryStudentWithFamilyQueryParams{},
+		RightUpdateJsonBody:           &family.UpdateStudentOfFamilyJsonBody{},
+		RightQueryQueryParams:         &family.QueryStudentOfFamilyQueryParams{},
+		RightQueryWithLeftQueryParams: &family.QueryFamilyWithStudentQueryParams{},
+	})
+}

+ 37 - 0
project/server/application/service/student_and_hobby.go

@@ -0,0 +1,37 @@
+package service
+
+import (
+	"git.sxidc.com/go-framework/baize/convenient/relation/remote"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/domain/hobby"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/domain/student"
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+var studentAndHobbyService = &StudentAndHobbyService{}
+
+type StudentAndHobbyService struct{}
+
+func (svc *StudentAndHobbyService) Init(appInstance *application.App) error {
+	svc.v1(appInstance)
+	return nil
+}
+
+func (svc *StudentAndHobbyService) Destroy() error {
+	return nil
+}
+
+func (svc *StudentAndHobbyService) v1(appInstance *application.App) {
+	v1Binder := binding.NewBinder(appInstance.ChooseRouter(api.RouterPrefix, "v1"), appInstance.Infrastructure())
+
+	remote.BindSimple(v1Binder, &remote.Simple[student.Info, string]{
+		Left:                  &student.Entity{},
+		Right:                 &hobby.Entity{},
+		Schema:                dbSchema,
+		LeftUpdateJsonBody:    &student.UpdateHobbiesOfStudentJsonBody{},
+		LeftQueryQueryParams:  &student.QueryHobbiesOfStudentQueryParams{},
+		RightUpdateJsonBody:   &hobby.UpdateStudentsOfHobbyJsonBody{},
+		RightQueryQueryParams: &hobby.QueryStudentsOfHobbyQueryParams{},
+	})
+}

+ 37 - 0
project/server/application/service/student_and_identity.go

@@ -0,0 +1,37 @@
+package service
+
+import (
+	"git.sxidc.com/go-framework/baize/convenient/relation/many2many"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/domain/identity"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application/domain/student"
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+)
+
+var studentAndIdentityService = &StudentAndIdentityService{}
+
+type StudentAndIdentityService struct{}
+
+func (svc *StudentAndIdentityService) Init(appInstance *application.App) error {
+	svc.v1(appInstance)
+	return nil
+}
+
+func (svc *StudentAndIdentityService) Destroy() error {
+	return nil
+}
+
+func (svc *StudentAndIdentityService) v1(appInstance *application.App) {
+	v1Binder := binding.NewBinder(appInstance.ChooseRouter(api.RouterPrefix, "v1"), appInstance.Infrastructure())
+
+	many2many.BindSimple(v1Binder, &many2many.Simple[student.Info, identity.Info]{
+		Left:                  &student.Entity{},
+		Right:                 &identity.Entity{},
+		Schema:                dbSchema,
+		LeftUpdateJsonBody:    &student.UpdateIdentitiesOfStudentJsonBody{},
+		LeftQueryQueryParams:  &student.QueryIdentitiesOfStudentQueryParams{},
+		RightUpdateJsonBody:   &identity.UpdateStudentsOfIdentityJsonBody{},
+		RightQueryQueryParams: &identity.QueryStudentsOfIdentityQueryParams{},
+	})
+}

+ 38 - 0
project/server/application/service/version.go

@@ -0,0 +1,38 @@
+package service
+
+import (
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/binding/request"
+	"git.sxidc.com/go-framework/baize/framework/binding/response"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+	"git.sxidc.com/go-framework/baize/framework/core/domain"
+	"git.sxidc.com/go-framework/baize/framework/core/infrastructure"
+)
+
+var versionService = &VersionService{}
+
+type VersionService struct{}
+
+func (svc *VersionService) Init(appInstance *application.App) error {
+	svc.prefixRoot(appInstance)
+	return nil
+}
+
+func (svc *VersionService) Destroy() error {
+	return nil
+}
+
+func (svc *VersionService) prefixRoot(appInstance *application.App) {
+	prefixRootBinder := binding.NewBinder(appInstance.ChooseRouter(api.RouterPrefix, ""), appInstance.Infrastructure())
+
+	binding.GetBind(prefixRootBinder, &binding.SimpleBindItem[map[string]any]{
+		Path:         "/version",
+		ResponseFunc: response.SendMapResponse,
+		ServiceFunc: func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (map[string]any, error) {
+			return map[string]any{
+				"version": "v1.0.0",
+			}, nil
+		},
+	})
+}

+ 71 - 0
project/server/config/config.go

@@ -0,0 +1,71 @@
+package config
+
+import (
+	"fmt"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+	"git.sxidc.com/go-tools/utils/strutils"
+	"git.sxidc.com/service-supports/fslog"
+	"git.sxidc.com/service-supports/scm-sdk"
+	"os"
+)
+
+type Config struct {
+	ApplicationConfig application.Config
+}
+
+var conf Config
+
+func init() {
+	useSCMEnv := os.Getenv("USE_SCM")
+	if useSCMEnv == "true" {
+		initConfigFromSCM()
+	} else {
+		initConfigFromConfigFile()
+	}
+}
+
+func GetConfig() Config {
+	return conf
+}
+
+func initConfigFromSCM() {
+	scmBaseUrl := loadEnvOrPanic("SCM_BASE_URL")
+	scmNamespace := loadEnvOrPanic("SCM_NAMESPACE")
+	scmName := loadEnvOrPanic("SCM_NAME")
+
+	info, err := scm_sdk.GetCurrentConfiguration(scmBaseUrl, scmNamespace, scmName)
+	if err != nil {
+		fslog.Error(err)
+		panic(err)
+	}
+
+	applicationConfig, err := application.LoadFromYaml(info.Content)
+	if err != nil {
+		panic(err)
+	}
+
+	conf.ApplicationConfig = applicationConfig
+
+	fslog.Info("Load config from scm finish")
+}
+
+func initConfigFromConfigFile() {
+	configFilePath := os.Getenv("CONFIG_FILE_PATH")
+	applicationConfig, err := application.LoadFromYamlFile(configFilePath)
+	if err != nil {
+		panic(err)
+	}
+
+	conf.ApplicationConfig = applicationConfig
+
+	fmt.Println("Load config file finish")
+}
+
+func loadEnvOrPanic(envName string) string {
+	envValue := os.Getenv(envName)
+	if strutils.IsStringEmpty(envValue) {
+		panic("请配置" + envName)
+	}
+
+	return envValue
+}

+ 21 - 0
project/server/deployment/config/config.yaml

@@ -0,0 +1,21 @@
+api:
+  url_prefix: /example/api
+  port: 31000
+infrastructure:
+  database:
+    operations:
+      user_name: test
+      password: "123456"
+      address: localhost
+      port: 30432
+      database: test
+      max_connections: 20
+      max_idle_connections: 5
+#    data_service:
+#      token: "8qe+uPgpQ2JWxu3lSyOx5NjX+INp5WsnoD1ZWb7PBm4="
+#      address: "localhost"
+#      http_port: "10000"
+#      grpc_port: "10001"
+#      namespace: "baize"
+#      data_source: "baize"
+#      timeout_sec: 30

+ 9 - 0
project/server/deployment/data_service/apply_data_containers.ps1

@@ -0,0 +1,9 @@
+Set-Location  $(Split-Path $MyInvocation.MyCommand.Path -Parent)
+
+datactl.exe apply -f base.yaml
+
+foreach ($file in $(Get-ChildItem -Path ".\data_containers")) {
+    if ($file.GetType() -eq [System.IO.FileInfo]) {
+        datactl.exe apply -f $file.FullName
+    }
+}

+ 10 - 0
project/server/deployment/data_service/apply_data_containers.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+cd "$(dirname "$0")" || exit 1
+
+datactl apply -f base.yaml
+
+for file in ./data_containers/*; do
+	if [ -f "$file" ]; then
+		datactl apply -f "$file"
+	fi
+done

+ 20 - 0
project/server/deployment/data_service/base.yaml

@@ -0,0 +1,20 @@
+kind: Namespace
+spec:
+  name: baize
+
+---
+
+kind: DataSource
+spec:
+  type: database
+  namespace: baize
+  name: baize
+  spec:
+    type: postgres
+    user_name: test
+    password: "123456"
+    address: "10.0.0.84"
+    port: "30432"
+    database: test
+    max_connections: 40
+    max_idle_connections: 10

+ 30 - 0
project/server/deployment/data_service/data_containers/class.yaml

@@ -0,0 +1,30 @@
+kind: DataContainer
+spec:
+  namespace: baize
+  data_source: baize
+  name: test.classes
+  spec:
+    table_name: test.classes
+    columns:
+      - name: id
+        type: varchar(32)
+        comment: id
+        primary_key: true
+      - name: name
+        type: varchar(128)
+        comment: 班名
+        not_null: true
+        index: true
+      - name: student_num
+        type: integer
+        comment: 学生数量
+        not_null: true
+        index: true
+      - name: created_time
+        type: "timestamp with time zone"
+        comment: 创建时间
+        not_null: true
+      - name: last_updated_time
+        type: "timestamp with time zone"
+        comment: 最近更新时间
+        not_null: true

+ 23 - 0
project/server/deployment/data_service/data_containers/configuration.yaml

@@ -0,0 +1,23 @@
+kind: DataContainer
+spec:
+  namespace: baize
+  data_source: baize
+  name: test.configurations
+  spec:
+    table_name: test.configurations
+    columns:
+      - name: scope
+        type: varchar(256)
+        comment: 范围
+        not_null: true
+        primary_key: true
+      - name: group
+        type: varchar(256)
+        comment: 组
+        not_null: true
+        primary_key: true
+      - name: value
+        type: varchar(256)
+        comment: 值
+        not_null: true
+        index: true

+ 35 - 0
project/server/deployment/data_service/data_containers/family.yaml

@@ -0,0 +1,35 @@
+kind: DataContainer
+spec:
+  namespace: baize
+  data_source: baize
+  name: test.families
+  spec:
+    table_name: test.families
+    columns:
+      - name: id
+        type: varchar(32)
+        comment: id
+        primary_key: true
+      - name: father
+        type: varchar(128)
+        comment: 父亲姓名
+        not_null: true
+        index: true
+      - name: mother
+        type: varchar(128)
+        comment: 母亲姓名
+        not_null: true
+        index: true
+      - name: student_id
+        type: varchar(32)
+        comment: 家庭ID
+        not_null: true
+        index: true
+      - name: created_time
+        type: "timestamp with time zone"
+        comment: 创建时间
+        not_null: true
+      - name: last_updated_time
+        type: "timestamp with time zone"
+        comment: 最近更新时间
+        not_null: true

+ 25 - 0
project/server/deployment/data_service/data_containers/identity.yaml

@@ -0,0 +1,25 @@
+kind: DataContainer
+spec:
+  namespace: baize
+  data_source: baize
+  name: test.identities
+  spec:
+    table_name: test.identities
+    columns:
+      - name: id
+        type: varchar(32)
+        comment: id
+        primary_key: true
+      - name: name
+        type: varchar(128)
+        comment: 名称
+        not_null: true
+        index: true
+      - name: created_time
+        type: "timestamp with time zone"
+        comment: 创建时间
+        not_null: true
+      - name: last_updated_time
+        type: "timestamp with time zone"
+        comment: 最近更新时间
+        not_null: true

+ 35 - 0
project/server/deployment/data_service/data_containers/student.yaml

@@ -0,0 +1,35 @@
+kind: DataContainer
+spec:
+  namespace: baize
+  data_source: baize
+  name: test.students
+  spec:
+    table_name: test.students
+    columns:
+      - name: id
+        type: varchar(32)
+        comment: id
+        primary_key: true
+      - name: name
+        type: varchar(128)
+        comment: 姓名
+        not_null: true
+        index: true
+      - name: class_id
+        type: varchar(32)
+        comment: 班级ID
+        not_null: true
+        index: true
+      - name: family_id
+        type: varchar(32)
+        comment: 家庭ID
+        not_null: true
+        index: true
+      - name: created_time
+        type: "timestamp with time zone"
+        comment: 创建时间
+        not_null: true
+      - name: last_updated_time
+        type: "timestamp with time zone"
+        comment: 最近更新时间
+        not_null: true

+ 16 - 0
project/server/deployment/data_service/data_containers/student_and_hobby.yaml

@@ -0,0 +1,16 @@
+kind: DataContainer
+spec:
+  namespace: baize
+  data_source: baize
+  name: test.student_and_hobby
+  spec:
+    table_name: test.student_and_hobby
+    columns:
+      - name: student_id
+        type: varchar(32)
+        comment: id
+        primary_key: true
+      - name: hobby_id
+        type: varchar(32)
+        comment: id
+        primary_key: true

+ 16 - 0
project/server/deployment/data_service/data_containers/student_and_identity.yaml

@@ -0,0 +1,16 @@
+kind: DataContainer
+spec:
+  namespace: baize
+  data_source: baize
+  name: test.student_and_identity
+  spec:
+    table_name: test.student_and_identity
+    columns:
+      - name: student_id
+        type: varchar(32)
+        comment: id
+        primary_key: true
+      - name: identity_id
+        type: varchar(32)
+        comment: id
+        primary_key: true

+ 9 - 0
project/server/deployment/data_service/delete_data_containers.ps1

@@ -0,0 +1,9 @@
+Set-Location  $(Split-Path $MyInvocation.MyCommand.Path -Parent)
+
+datactl.exe delete -f base.yaml
+
+foreach ($file in $(Get-ChildItem -Path ".\data_containers")) {
+    if ($file.GetType() -eq [System.IO.FileInfo]) {
+        datactl.exe apply -f $file.FullName
+    }
+}

+ 10 - 0
project/server/deployment/data_service/delete_data_containers.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+cd "$(dirname "$0")" || exit 1
+
+datactl delete -f base.yaml
+
+for file in ./data_containers/*; do
+	if [ -f "$file" ]; then
+		datactl apply -f "$file"
+	fi
+done

+ 100 - 0
project/server/main.go

@@ -0,0 +1,100 @@
+package main
+
+import (
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application"
+	DEATH "github.com/vrecan/death"
+	"syscall"
+)
+
+// Version
+// curl -X GET "http://localhost:31000/example/api/version"
+
+// Configuration
+// curl -X POST -H "Content-Type: application/json" -d '{"scope": "global", "group":"test", "value":"test-value"}' "http://localhost:31000/example/api/configuration/create"
+// curl -X GET "http://localhost:31000/example/api/configuration/values?scope=global&group=test&pageNo=1&pageSize=1"
+// curl -X POST -H "Content-Type: application/json" -d '{"scope": "global", "group":"test"}' "http://localhost:31000/example/api/configuration/delete"
+
+// Class
+// curl -X POST -H "Content-Type: application/json" -d '{"name":"test", "studentNum": 10}' "http://localhost:31000/example/api/v1/class/create"
+// curl -X PUT -H "Content-Type: application/json" -d '{"id":"b96c97e868c94250a754e8f9f91518b7", "name":"test-new"}' "http://localhost:31000/example/api/v1/class/update"
+// curl -X GET "http://localhost:31000/example/api/v1/class/query?name=test-new&pageNo=1&pageSize=1"
+// curl -X GET "http://localhost:31000/example/api/v1/class/get?id=b96c97e868c94250a754e8f9f91518b7"
+// curl -X DELETE "http://localhost:31000/example/api/v1/class/delete?id=b96c97e868c94250a754e8f9f91518b7"
+
+// Student
+// curl -X POST -H "Content-Type: application/json" -d '{"name":"test"}' "http://localhost:31000/example/api/v1/student/create"
+// curl -X PUT -H "Content-Type: application/json" -d '{"id":"d9332801b46c4f0c99fdd381954313d6", "name":"test-new"}' "http://localhost:31000/example/api/v1/student/update"
+// curl -X GET "http://localhost:31000/example/api/v1/student/query?name=test-new&pageNo=1&pageSize=1"
+// curl -X GET "http://localhost:31000/example/api/v1/student/get?id=d9332801b46c4f0c99fdd381954313d6"
+// curl -X DELETE "http://localhost:31000/example/api/v1/student/delete?id=d9332801b46c4f0c99fdd381954313d6"
+
+// Family
+// curl -X POST -H "Content-Type: application/json" -d '{"father":"father", "mother": "mother"}' "http://localhost:31000/example/api/v1/family/create"
+// curl -X PUT -H "Content-Type: application/json" -d '{"id":"85ffbfbef27b42879382b47718c7a99e", "father":"new-father", "mother": "new-mother"}' "http://localhost:31000/example/api/v1/family/update"
+// curl -X GET "http://localhost:31000/example/api/v1/family/query?father=new-father&pageNo=0&pageSize=0"
+// curl -X GET "http://localhost:31000/example/api/v1/family/get?id=85ffbfbef27b42879382b47718c7a99e"
+// curl -X DELETE "http://localhost:31000/example/api/v1/family/delete?id=85ffbfbef27b42879382b47718c7a99e"
+
+// Identity
+// curl -X POST -H "Content-Type: application/json" -d '{"name":"test"}' "http://localhost:31000/example/api/v1/identity/create"
+// curl -X PUT -H "Content-Type: application/json" -d '{"id":"6e12ee71397746b8920fa94e5f229366", "name":"test-new"}' "http://localhost:31000/example/api/v1/identity/update"
+// curl -X GET "http://localhost:31000/example/api/v1/identity/query?name=test-new&pageNo=1&pageSize=1"
+// curl -X GET "http://localhost:31000/example/api/v1/identity/get?id=6e12ee71397746b8920fa94e5f229366"
+// curl -X DELETE "http://localhost:31000/example/api/v1/identity/delete?id=6e12ee71397746b8920fa94e5f229366"
+
+// Class-Student
+// curl -X POST -H "Content-Type: application/json" -d '{"id":"a38786c698904224a6fc36a23c2eec1e", "studentIds": ["00254b4a7102429db35e6edc8e47a764"]}' "http://localhost:31000/example/api/v1/class/student/update"
+// curl -X GET "http://localhost:31000/example/api/v1/class/student/query?id=a38786c698904224a6fc36a23c2eec1e"
+
+// Student-Class
+// curl -X POST -H "Content-Type: application/json" -d '{"id":"00254b4a7102429db35e6edc8e47a764", "classId": "a38786c698904224a6fc36a23c2eec1e"}' "http://localhost:31000/example/api/v1/student/class/update"
+// curl -X GET "http://localhost:31000/example/api/v1/student/class/query?id=00254b4a7102429db35e6edc8e47a764"
+// curl -X GET "http://localhost:31000/example/api/v1/student/class/queryWith?name=test"
+
+// Student-Family
+// curl -X POST -H "Content-Type: application/json" -d '{"id":"00254b4a7102429db35e6edc8e47a764", "familyId": "df3aeee04ce94c17878bbb5383d15f18"}' "http://localhost:31000/example/api/v1/student/family/update"
+// curl -X GET "http://localhost:31000/example/api/v1/student/family/query?id=00254b4a7102429db35e6edc8e47a764"
+// curl -X GET "http://localhost:31000/example/api/v1/student/family/queryWith?father=test"
+
+// Family-Student
+// curl -X POST -H "Content-Type: application/json" -d '{"id":"df3aeee04ce94c17878bbb5383d15f18", "studentId": "00254b4a7102429db35e6edc8e47a764"}' "http://localhost:31000/example/api/v1/family/student/update"
+// curl -X GET "http://localhost:31000/example/api/v1/family/student/query?id=df3aeee04ce94c17878bbb5383d15f18"
+// curl -X GET "http://localhost:31000/example/api/v1/family/student/queryWith?father=test"
+
+// Student-Identity
+// curl -X POST -H "Content-Type: application/json" -d '{"id":"00254b4a7102429db35e6edc8e47a764", "identityIds": ["4481fd110a5f46d2babe52b650981384"]}' "http://localhost:31000/example/api/v1/student/identity/update"
+// curl -X GET "http://localhost:31000/example/api/v1/student/identity/query?id=00254b4a7102429db35e6edc8e47a764"
+
+// Identity-Student
+// curl -X POST -H "Content-Type: application/json" -d '{"id":"4481fd110a5f46d2babe52b650981384", "studentIds": ["00254b4a7102429db35e6edc8e47a764"]}' "http://localhost:31000/example/api/v1/identity/student/update"
+// curl -X GET "http://localhost:31000/example/api/v1/identity/student/query?id=4481fd110a5f46d2babe52b650981384"
+
+// Student-Hobby
+// curl -X POST -H "Content-Type: application/json" -d '{"id":"a3f28141a96e4cec850b485bd9c38813", "hobbyIds": ["42b305bb292c4082a3e91a2967f11111"]}' "http://localhost:31000/example/api/v1/student/hobby/update"
+// curl -X GET "http://localhost:31000/example/api/v1/student/hobby/query?id=a3f28141a96e4cec850b485bd9c38813"
+
+// Hobby-Student
+// curl -X POST -H "Content-Type: application/json" -d '{"id":"42b305bb292c4082a3e91a2967f11111", "studentIds": ["00254b4a7102429db35e6edc8e47a764"]}' "http://localhost:31000/example/api/v1/hobby/student/update"
+// curl -X GET "http://localhost:31000/example/api/v1/hobby/student/query?id=42b305bb292c4082a3e91a2967f11111"
+
+func main() {
+	application.NewApp()
+	defer application.DestroyApp()
+
+	go func() {
+		err := application.Start()
+		if err != nil {
+			panic(err)
+		}
+	}()
+
+	defer func() {
+		err := application.Finish()
+		if err != nil {
+			panic(err)
+		}
+	}()
+
+	death := DEATH.NewDeath(syscall.SIGINT, syscall.SIGTERM)
+	_ = death.WaitForDeath()
+}

+ 83 - 0
project/server/test/configuration_test.go

@@ -0,0 +1,83 @@
+package test
+
+import (
+	"git.sxidc.com/go-framework/baize/convenient/domain/configuration"
+	"git.sxidc.com/go-framework/baize/framework/binding/response"
+	"git.sxidc.com/go-tools/utils/strutils"
+	"net/http"
+	"testing"
+)
+
+func TestConfiguration(t *testing.T) {
+	Init()
+	defer Destroy()
+
+	scope := strutils.SimpleUUID()
+	group := strutils.SimpleUUID()
+	value := strutils.SimpleUUID()
+
+	values := make([]string, 0)
+
+	NewToolKit(t).CreateConfiguration(scope, group, value).
+		GetConfigurationValues(scope, group, &values).
+		AssertEqual(1, len(values), "值的长度不正确").
+		AssertEqual(value, values[0], "值不正确").
+		DeleteConfiguration(scope, group).
+		GetConfigurationValues(scope, group, &values).
+		AssertEqual(0, len(values), "值的长度不正确")
+}
+
+func (toolKit *ToolKit) CreateConfiguration(scope string, group string, value string) *ToolKit {
+	msgResponse := new(response.MsgResponse)
+
+	toolKit.SetHeader("Content-Type", "application/json").
+		SetJsonBody(&configuration.AddConfigurationJsonBody{
+			Scope: scope,
+			Group: group,
+			Value: value,
+		}).
+		SetJsonResponse(msgResponse).
+		Request("/example/api/configuration/create", http.MethodPost).
+		AssertStatusCode(http.StatusOK).
+		AssertEqual(true, msgResponse.Success, msgResponse.Msg)
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) DeleteConfiguration(scope string, group string) *ToolKit {
+	msgResponse := new(response.MsgResponse)
+
+	toolKit.SetHeader("Content-Type", "application/json").
+		SetJsonResponse(msgResponse).
+		SetJsonBody(&configuration.RemoveConfigurationJsonBody{
+			Scope: scope,
+			Group: group,
+		}).
+		Request("/example/api/configuration/delete", http.MethodPost).
+		AssertStatusCode(http.StatusOK).
+		AssertEqual(true, msgResponse.Success, msgResponse.Msg)
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) GetConfigurationValues(scope string, group string, retValues *[]string) *ToolKit {
+	getConfigurationValuesResponse := new(struct {
+		response.MsgResponse
+		Values []string `json:"values"`
+	})
+
+	toolKit.SetHeader("Content-Type", "application/json").
+		SetJsonResponse(getConfigurationValuesResponse).
+		SetQueryParams("scope", scope).
+		SetQueryParams("group", group).
+		Request("/example/api/configuration/values", http.MethodGet).
+		AssertStatusCode(http.StatusOK).
+		AssertEqual(true, getConfigurationValuesResponse.Success, getConfigurationValuesResponse.Msg)
+
+	if retValues != nil {
+		*retValues = make([]string, 0)
+		*retValues = getConfigurationValuesResponse.Values
+	}
+
+	return toolKit
+}

+ 186 - 0
project/server/test/tool_kit.go

@@ -0,0 +1,186 @@
+package test
+
+import (
+	"bytes"
+	"encoding/json"
+	"git.sxidc.com/go-framework/baize/examples/examples/project/application"
+	"git.sxidc.com/go-tools/utils/strutils"
+	"github.com/stretchr/testify/assert"
+	"io"
+	"net/http"
+	"net/http/httptest"
+	"reflect"
+	"testing"
+	"time"
+)
+
+type ToolKit struct {
+	t *testing.T
+
+	body         io.Reader
+	header       map[string]string
+	queryParams  map[string]string
+	jsonResponse interface{}
+	token        string
+
+	responseRecorder *httptest.ResponseRecorder
+}
+
+func Init() {
+	application.NewApp()
+
+	go func() {
+		err := application.Start()
+		if err != nil {
+			panic(err)
+		}
+	}()
+
+	time.Sleep(100 * time.Millisecond)
+}
+
+func Destroy() {
+	err := application.Finish()
+	if err != nil {
+		panic(err)
+	}
+
+	application.DestroyApp()
+}
+
+func NewToolKit(t *testing.T) *ToolKit {
+	return &ToolKit{
+		t:           t,
+		header:      make(map[string]string),
+		queryParams: make(map[string]string),
+	}
+}
+
+func (toolKit *ToolKit) SetHeader(key string, value string) *ToolKit {
+	toolKit.header[key] = value
+	return toolKit
+}
+
+func (toolKit *ToolKit) SetBody(body *bytes.Buffer) *ToolKit {
+	toolKit.body = body
+	return toolKit
+}
+
+func (toolKit *ToolKit) SetQueryParams(key string, value string) *ToolKit {
+	toolKit.queryParams[key] = value
+	return toolKit
+}
+
+func (toolKit *ToolKit) SetJsonBody(body interface{}) *ToolKit {
+	jsonBody, err := json.Marshal(body)
+	if err != nil {
+		toolKit.t.Fatal("转换JSON失败")
+	}
+
+	toolKit.body = bytes.NewBuffer(jsonBody)
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) SetJsonResponse(response interface{}) *ToolKit {
+	if response == nil {
+		toolKit.jsonResponse = nil
+		return toolKit
+	}
+
+	responseValue := reflect.ValueOf(response)
+	if responseValue.Kind() != reflect.Ptr {
+		toolKit.t.Fatal("JsonResponse应该传递指针类型")
+	}
+
+	toolKit.jsonResponse = response
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) SetToken(token string) *ToolKit {
+	toolKit.token = token
+	return toolKit
+}
+
+func (toolKit *ToolKit) Request(url string, method string) *ToolKit {
+	if len(toolKit.queryParams) != 0 {
+		url = url + "?"
+		for key, value := range toolKit.queryParams {
+			url = url + key + "=" + value + "&"
+		}
+
+		url = url[:len(url)-1]
+
+		toolKit.queryParams = make(map[string]string)
+	}
+
+	request, err := http.NewRequest(method, url, toolKit.body)
+	if err != nil {
+		toolKit.t.Fatal("创建请求失败", err)
+	}
+
+	if len(toolKit.header) != 0 {
+		for key, value := range toolKit.header {
+			request.Header.Add(key, value)
+		}
+
+		toolKit.header = make(map[string]string)
+	}
+
+	if !strutils.IsStringEmpty(toolKit.token) {
+		request.Header.Add("Authorization", toolKit.token)
+	}
+
+	toolKit.responseRecorder = httptest.NewRecorder()
+	application.ServerHttpForTest(toolKit.responseRecorder, request)
+
+	if toolKit.responseRecorder.Code == http.StatusOK && toolKit.jsonResponse != nil {
+		responseBody, err := io.ReadAll(toolKit.responseRecorder.Body)
+		if err != nil {
+			toolKit.t.Fatal("读取响应Body失败")
+		}
+
+		err = json.Unmarshal(responseBody, toolKit.jsonResponse)
+		if err != nil {
+			toolKit.t.Fatal("转换Response失败")
+		}
+	}
+
+	return toolKit
+}
+
+func (toolKit *ToolKit) AssertStatusCode(code int) *ToolKit {
+	assert.Equal(toolKit.t, code, toolKit.responseRecorder.Code)
+	return toolKit
+}
+
+func (toolKit *ToolKit) AssertBodyEqual(body string) *ToolKit {
+	assert.Equal(toolKit.t, body, toolKit.responseRecorder.Body.String())
+	return toolKit
+}
+
+func (toolKit *ToolKit) AssertEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) *ToolKit {
+	assert.Equal(toolKit.t, expected, actual, msgAndArgs)
+	return toolKit
+}
+
+func (toolKit *ToolKit) AssertNotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) *ToolKit {
+	assert.NotEqual(toolKit.t, expected, actual, msgAndArgs)
+	return toolKit
+}
+
+func (toolKit *ToolKit) AssertNotEmpty(object interface{}, msgAndArgs ...interface{}) *ToolKit {
+	assert.NotEmpty(toolKit.t, object, msgAndArgs)
+	return toolKit
+}
+
+func (toolKit *ToolKit) AssertGreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) *ToolKit {
+	assert.GreaterOrEqual(toolKit.t, e1, e2, msgAndArgs)
+	return toolKit
+}
+
+func (toolKit *ToolKit) AssertZero(e1 interface{}, msgAndArgs ...interface{}) *ToolKit {
+	assert.Zero(toolKit.t, e1, msgAndArgs)
+	return toolKit
+}

+ 20 - 0
project/server/test/version_test.go

@@ -0,0 +1,20 @@
+package test
+
+import (
+	"net/http"
+	"testing"
+)
+
+func TestVersion(t *testing.T) {
+	Init()
+	defer Destroy()
+
+	versionResponse := &struct {
+		Version string `json:"version"`
+	}{}
+
+	NewToolKit(t).SetJsonResponse(versionResponse).
+		Request("/example/api/version", http.MethodGet).
+		AssertStatusCode(http.StatusOK).
+		AssertEqual(versionResponse.Version, "v1.0.0")
+}

+ 102 - 0
quick_start/main.go

@@ -0,0 +1,102 @@
+package main
+
+import (
+	"fmt"
+	"git.sxidc.com/go-framework/baize"
+	"git.sxidc.com/go-framework/baize/framework/binding"
+	"git.sxidc.com/go-framework/baize/framework/binding/request"
+	"git.sxidc.com/go-framework/baize/framework/binding/response"
+	"git.sxidc.com/go-framework/baize/framework/core/api"
+	"git.sxidc.com/go-framework/baize/framework/core/application"
+	"git.sxidc.com/go-framework/baize/framework/core/domain"
+	"git.sxidc.com/go-framework/baize/framework/core/infrastructure"
+	DEATH "github.com/vrecan/death"
+	"net/http"
+	"syscall"
+)
+
+func main() {
+	app := baize.NewApplication(application.Config{
+		ApiConfig: application.ApiConfig{
+			UrlPrefix: "test",
+			Port:      "10100",
+		},
+	})
+
+	app.Api().
+		RootRouter().
+		AddMiddlewares(func(c *api.Context) {
+			fmt.Println("Global Before1")
+			c.Next()
+			fmt.Println("Global After1")
+		}, func(c *api.Context) {
+			fmt.Println("Global Before2")
+			c.Next()
+			fmt.Println("Global After2")
+		})
+
+	rootBinder := binding.NewBinder(app.ChooseRouter(api.RouterRoot, ""), app.Infrastructure())
+
+	binding.GetBind(rootBinder, &binding.SimpleBindItem[any]{
+		Path:         "/ping",
+		ResponseFunc: response.NoResponse,
+		ServiceFunc: func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (any, error) {
+			c.String(http.StatusOK, "pong")
+			return nil, nil
+		},
+	}, func(c *api.Context) {
+		fmt.Println("Root Route Before1")
+		c.Next()
+		fmt.Println("Root Route After1")
+	}, func(c *api.Context) {
+		fmt.Println("Root Route Before2")
+		c.Next()
+		fmt.Println("Root Route After2")
+	})
+
+	app.Api().
+		PrefixRouter().
+		RegisterVersionedRouter("v1", func(c *api.Context) {
+			fmt.Println("Global Before1")
+			c.Next()
+			fmt.Println("Global After1")
+		}, func(c *api.Context) {
+			fmt.Println("Global Before2")
+			c.Next()
+			fmt.Println("Global After2")
+		})
+
+	prefixRootBinder := binding.NewBinder(app.ChooseRouter(api.RouterPrefix, "v1"), app.Infrastructure())
+
+	binding.GetBind(prefixRootBinder, &binding.SimpleBindItem[any]{
+		Path:         "/ping",
+		ResponseFunc: response.NoResponse,
+		ServiceFunc: func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (any, error) {
+			c.String(http.StatusOK, "pong")
+			return nil, nil
+		},
+	}, func(c *api.Context) {
+		fmt.Println("Versioned Route Before1")
+		c.Next()
+		fmt.Println("Versioned Route After1")
+	}, func(c *api.Context) {
+		fmt.Println("Versioned Route Before2")
+		c.Next()
+		fmt.Println("Versioned Route After2")
+	})
+
+	go func() {
+		if err := app.Start(); err != nil {
+			panic(err)
+		}
+	}()
+
+	defer func() {
+		if err := app.Finish(); err != nil {
+			panic(err)
+		}
+	}()
+
+	death := DEATH.NewDeath(syscall.SIGINT, syscall.SIGTERM)
+	_ = death.WaitForDeath()
+}

+ 51 - 0
sql_mapping_tag/main.go

@@ -0,0 +1,51 @@
+package main
+
+import (
+	"fmt"
+	sql_mapping2 "git.sxidc.com/go-framework/baize/framework/core/tag/sql/sql_mapping"
+	"reflect"
+	"time"
+)
+
+type IDField struct {
+	ID string
+}
+
+type TimeFields struct {
+	CreatedTime     *time.Time
+	LastUpdatedTime time.Time
+}
+
+type GraduatedTimeTestStruct struct {
+	Field *string `sqlmapping:"-"`
+}
+
+type Class struct {
+	IDField
+	Name          string `sqlmapping:"updateClear;aes:@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L;"`
+	StudentNum    int    `sqlmapping:"column:student_num;notUpdate;"`
+	GraduatedTime *time.Time
+	StudentIDs    []string `sqlmapping:"column:student_ids;joinWith:'\n'"`
+	TimeFields
+	Ignored string `sqlmapping:"-"`
+	*GraduatedTimeTestStruct
+}
+
+func main() {
+	err := sql_mapping2.UseTag(&Class{}, func(fieldName string, entityFieldElemValue reflect.Value, sqlMappingTag *sql_mapping2.Tag) error {
+		fmt.Println("Field Name:", fieldName)
+		fmt.Println("Type:", entityFieldElemValue.Type().String())
+		if entityFieldElemValue.Kind() == reflect.String {
+			fmt.Printf("\"%+v\"\n", entityFieldElemValue.Interface())
+		} else {
+			fmt.Printf("%+v\n", entityFieldElemValue.Interface())
+		}
+		fmt.Printf("%+v\n", sqlMappingTag)
+		fmt.Println()
+
+		return nil
+	})
+	if err != nil {
+		panic(err)
+	}
+}

+ 51 - 0
sql_result_tag/main.go

@@ -0,0 +1,51 @@
+package main
+
+import (
+	"fmt"
+	sql_result2 "git.sxidc.com/go-framework/baize/framework/core/tag/sql/sql_result"
+	"reflect"
+	"time"
+)
+
+type IDField struct {
+	ID string
+}
+
+type TimeFields struct {
+	CreatedTime     *time.Time
+	LastUpdatedTime time.Time
+}
+
+type GraduatedTimeTestStruct struct {
+	Field *string `sqlresult:"column:graduated_time;parseTime:2006-01-02 15:04:05"`
+}
+
+type Class struct {
+	IDField
+	Name          string `sqlresult:"aes:@MKU^AHYCN$:j76J<TAHCVD#$XZSWQ@L;"`
+	StudentNum    int    `sqlresult:"column:student_num_alias"`
+	GraduatedTime *time.Time
+	StudentIDs    []string `sqlresult:"column:student_ids;splitWith:'\n'"`
+	TimeFields
+	Ignored string `sqlresult:"-"`
+	*GraduatedTimeTestStruct
+}
+
+func main() {
+	err := sql_result2.UseTag(&Class{}, func(fieldName string, entityFieldElemValue reflect.Value, sqlResultTag *sql_result2.Tag) error {
+		fmt.Println("Field Name:", fieldName)
+		fmt.Println("Type:", entityFieldElemValue.Type().String())
+		if entityFieldElemValue.Kind() == reflect.String {
+			fmt.Printf("\"%+v\"\n", entityFieldElemValue.Interface())
+		} else {
+			fmt.Printf("%+v\n", entityFieldElemValue.Interface())
+		}
+		fmt.Printf("%+v\n", sqlResultTag)
+		fmt.Println()
+
+		return nil
+	})
+	if err != nil {
+		panic(err)
+	}
+}