From acef78070d74101b1b99761e06a5b296443313c7 Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Wed, 17 Nov 2021 14:55:06 +0800 Subject: [PATCH] fix: fix version of sqlchemy to v1.0.0 for release/3.6 --- Makefile | 3 +- go.mod | 8 +- go.sum | 48 +---- vendor/modules.txt | 8 +- vendor/yunion.io/x/jsonutils/jsonutils.go | 2 +- vendor/yunion.io/x/jsonutils/marshal.go | 191 ++++++++++------- vendor/yunion.io/x/pkg/errors/consts.go | 8 +- .../yunion.io/x/pkg/util/compare/compare.go | 23 ++- .../yunion.io/x/pkg/util/regutils/regutils.go | 18 ++ .../x/pkg/util/timeutils/timeutils.go | 22 ++ vendor/yunion.io/x/pkg/utils/tags.go | 18 ++ vendor/yunion.io/x/sqlchemy/README.md | 192 ++++++++++-------- vendor/yunion.io/x/sqlchemy/case.go | 6 + vendor/yunion.io/x/sqlchemy/column.go | 186 ++++++++++++++--- vendor/yunion.io/x/sqlchemy/conditions.go | 97 ++++++++- vendor/yunion.io/x/sqlchemy/const.go | 83 +++++--- vendor/yunion.io/x/sqlchemy/constraint.go | 14 +- vendor/yunion.io/x/sqlchemy/debug.go | 32 ++- vendor/yunion.io/x/sqlchemy/errors.go | 31 ++- vendor/yunion.io/x/sqlchemy/fetch.go | 10 +- vendor/yunion.io/x/sqlchemy/field_update.go | 2 + vendor/yunion.io/x/sqlchemy/filter.go | 158 ++++++++------ vendor/yunion.io/x/sqlchemy/functions.go | 54 ++++- vendor/yunion.io/x/sqlchemy/inc.go | 9 +- vendor/yunion.io/x/sqlchemy/index.go | 20 +- vendor/yunion.io/x/sqlchemy/insert.go | 31 ++- vendor/yunion.io/x/sqlchemy/parser.go | 19 +- vendor/yunion.io/x/sqlchemy/query.go | 184 ++++++++++++----- vendor/yunion.io/x/sqlchemy/rawquery.go | 10 + vendor/yunion.io/x/sqlchemy/reflect.go | 3 +- vendor/yunion.io/x/sqlchemy/sql.go | 6 + vendor/yunion.io/x/sqlchemy/sync.go | 42 ++-- vendor/yunion.io/x/sqlchemy/table.go | 61 +++++- vendor/yunion.io/x/sqlchemy/tablealias.go | 2 +- vendor/yunion.io/x/sqlchemy/union.go | 49 +++-- vendor/yunion.io/x/sqlchemy/update.go | 8 + 36 files changed, 1164 insertions(+), 494 deletions(-) diff --git a/Makefile b/Makefile index 9559836848..3782ea0f63 100644 --- a/Makefile +++ b/Makefile @@ -225,7 +225,8 @@ dep: @$(MAKE) mod mod: - go get -d $(patsubst %,%@master,$(shell GO111MODULE=on go mod edit -print | sed -n -e 's|.*\(yunion.io/x/[a-z].*\) v.*|\1|p')) + go get -d $(patsubst %,%@master,$(shell GO111MODULE=on go mod edit -print | sed -n -e 's|.*\(yunion.io/x/[a-z].*\) v.*|\1|p' | grep -v sqlchemy)) + go get -d yunion.io/x/sqlchemy@v1.0.0 go mod tidy go mod vendor -v diff --git a/go.mod b/go.mod index fd78554a6a..3276782dea 100644 --- a/go.mod +++ b/go.mod @@ -140,13 +140,13 @@ require ( k8s.io/apimachinery v0.19.3 k8s.io/client-go v0.19.3 k8s.io/cluster-bootstrap v0.19.3 - yunion.io/x/executor v0.0.0-20210310041834-3fcd1574f68e - yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769 + yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656 + yunion.io/x/jsonutils v0.0.0-20211105163012-d846c05a3c9a yunion.io/x/log v0.0.0-20201210064738-43181789dc74 yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7 - yunion.io/x/pkg v0.0.0-20210218105412-13a69f60034c + yunion.io/x/pkg v0.0.0-20211116020154-6a76ba2f7e97 yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e - yunion.io/x/sqlchemy v0.0.0-20210329171939-2c520f93aee3 + yunion.io/x/sqlchemy v1.0.0 yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce ) diff --git a/go.sum b/go.sum index 1cdb207344..0622922a57 100644 --- a/go.sum +++ b/go.sum @@ -2,14 +2,12 @@ bazil.org/fuse v0.0.0-20180421153158-65cc252bf669 h1:FNCRpXiquG1aoyqcIWVFmpTSKVc bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0 h1:0E3eE8MX426vUOs7aHfI7aN1BrIzzzf4ccKCSfSjGmc= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.51.0 h1:PvKAVQWCtlGUSlZkGW3QLelKaWq7KYv/MW1EboG8bfM= cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= @@ -32,16 +30,12 @@ github.com/Azure/azure-sdk-for-go v36.1.0+incompatible h1:smHlbChr/JDmsyUqELZXLs github.com/Azure/azure-sdk-for-go v36.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest v0.9.3 h1:OZEIaBbMdUE/Js+BQKlpO81XlISgipr6yDJ+PSwsgi4= github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= github.com/Azure/go-autorest/autorest v0.9.6 h1:5YWtOnckcudzIw8lPPBcWOnmIFWMtHci1ZWAZulMSx0= github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= -github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/adal v0.8.1 h1:pZdL8o72rK+avFWl+p9nE8RWi1JInZrWJYlnpfXJwHk= github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0= github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= @@ -49,12 +43,10 @@ github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 h1:iM6UAvjR97ZIeR93qTcwp github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= github.com/Azure/go-autorest/autorest/azure/cli v0.3.1 h1:LXl088ZQlP0SBppGFsRZonW6hSvwgL5gRByMbvUbx8U= github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= -github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= @@ -87,9 +79,7 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/a8m/mark v0.1.1-0.20170507133748-44f2db618845/go.mod h1:c8Mh99Cw82nrsAnPgxQSZHkswVOJF7/MqZb1ZdvriLM= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/aliyun/alibaba-cloud-sdk-go v1.61.684 h1:MHqPW0la4Op96JGMkpB7Kxrz0Se5nowF6rLhHTZBUn4= github.com/aliyun/alibaba-cloud-sdk-go v1.61.684/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA= @@ -216,7 +206,6 @@ github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e h1:P10tZmVD2XclAa github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e/go.mod h1:2H9hjfbpSMHwY503FclkV/lZTBh2YlOmLLSda12uL8c= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -282,7 +271,6 @@ github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -301,13 +289,11 @@ github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -366,7 +352,6 @@ github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= @@ -375,7 +360,6 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -397,7 +381,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGi github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -508,7 +491,6 @@ github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -576,7 +558,6 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 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.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -644,7 +625,6 @@ golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -696,10 +676,8 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= @@ -744,20 +722,17 @@ golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8 h1:JA8d3MPx/IToSyXZG/RhwYEtfrKO1Fxrqe8KrkiLXKM= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -786,7 +761,6 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4 h1:Toz2IK7k8rbltAXwNAxKcn9OzqyNfMUhUNjz3sL0NMk= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200417140056-c07e33ef3290/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515220128-d3bf790afa53 h1:vmsb6v0zUdmUlXfwKaYrHPPRCV0lHq/IwNIf0ASGjyQ= @@ -824,7 +798,6 @@ google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBr google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb h1:ADPHZzpzM4tk4V4S5cnCrr5SwzvlrPRmqqCuJDB8UTs= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= @@ -833,7 +806,6 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -847,12 +819,10 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -886,7 +856,6 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= @@ -908,15 +877,14 @@ k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -yunion.io/x/executor v0.0.0-20210310041834-3fcd1574f68e h1:uGmKmmHm4zeLXhc/MEbAFtEDtGtyEYhC0OaBRGFi+fQ= -yunion.io/x/executor v0.0.0-20210310041834-3fcd1574f68e/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws= +yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656 h1:0zlZD5uhZoIHgLVAWCz2aHaYk2ZrNsACCYD7R6EIBII= +yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws= yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634= -yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769 h1:LIQ4hhLGQuQK+XxlV+8JrKBuL37WUT+5ZTVxBwHOTD4= -yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769/go.mod h1:p0nyMqGA/apTxxyLIU/o1k4V7Vujl2O6ey30L594sYE= +yunion.io/x/jsonutils v0.0.0-20211105163012-d846c05a3c9a h1:X/ucfLNcYsCfc4GFEX7R7GNWiDPr3vopLdnE4PuU46U= +yunion.io/x/jsonutils v0.0.0-20211105163012-d846c05a3c9a/go.mod h1:p0nyMqGA/apTxxyLIU/o1k4V7Vujl2O6ey30L594sYE= yunion.io/x/log v0.0.0-20190514041436-04ce53b17c6b/go.mod h1:+gauLs73omeJAPlsXcevLsJLKixV+sR/E7WSYTSx1fE= yunion.io/x/log v0.0.0-20190629062853-9f6483a7103d/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U= yunion.io/x/log v0.0.0-20201210064738-43181789dc74 h1:7D+sQ/XaUTUEm+NCrKXOhXBKlzEd0RyS2qZ4vBGjx2o= @@ -926,11 +894,11 @@ yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7/go.mod h1:0vLkNEhlmA64HViPB yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= -yunion.io/x/pkg v0.0.0-20210218105412-13a69f60034c h1:J/joqbA1N2mAlOl0Uqd4LpAq3+DK5aoFMdz+p9Ld7pQ= -yunion.io/x/pkg v0.0.0-20210218105412-13a69f60034c/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= +yunion.io/x/pkg v0.0.0-20211116020154-6a76ba2f7e97 h1:lY+5NlWwO2aIkfNnVOGKHmZvMt6m4ZuGtarIjwNfUsg= +yunion.io/x/pkg v0.0.0-20211116020154-6a76ba2f7e97/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E= yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e h1:v+EzIadodSwkdZ/7bremd7J8J50Cise/HCylsOJngmo= yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo= -yunion.io/x/sqlchemy v0.0.0-20210329171939-2c520f93aee3 h1:C4yasW3gXronDIlIVUqHSbkA38PM1X9gxUWTYGsuIuI= -yunion.io/x/sqlchemy v0.0.0-20210329171939-2c520f93aee3/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI= +yunion.io/x/sqlchemy v1.0.0 h1:fRtWxe1xxMR+NDVKYNuI89m2HGSl6aad2DZ+Bn/mZ4Q= +yunion.io/x/sqlchemy v1.0.0/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI= yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce h1:kU8xE7O5uZ1GSJVMZHoJ+jrNL7csUQHYGyAPW9QfNpE= yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng= diff --git a/vendor/modules.txt b/vendor/modules.txt index 89072247b7..0955bc6c5a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1102,11 +1102,11 @@ k8s.io/utils/integer sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml -# yunion.io/x/executor v0.0.0-20210310041834-3fcd1574f68e +# yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656 yunion.io/x/executor/apis yunion.io/x/executor/client yunion.io/x/executor/server -# yunion.io/x/jsonutils v0.0.0-20201110084044-3e4e1cb49769 +# yunion.io/x/jsonutils v0.0.0-20211105163012-d846c05a3c9a yunion.io/x/jsonutils # yunion.io/x/log v0.0.0-20201210064738-43181789dc74 yunion.io/x/log @@ -1115,7 +1115,7 @@ yunion.io/x/log/hooks yunion.io/x/ovsdb/cli_util yunion.io/x/ovsdb/schema/ovn_nb yunion.io/x/ovsdb/types -# yunion.io/x/pkg v0.0.0-20210218105412-13a69f60034c +# yunion.io/x/pkg v0.0.0-20211116020154-6a76ba2f7e97 yunion.io/x/pkg/errors yunion.io/x/pkg/gotypes yunion.io/x/pkg/prettytable @@ -1149,7 +1149,7 @@ yunion.io/x/pkg/util/workqueue yunion.io/x/pkg/utils # yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e yunion.io/x/s3cli -# yunion.io/x/sqlchemy v0.0.0-20210329171939-2c520f93aee3 +# yunion.io/x/sqlchemy v1.0.0 yunion.io/x/sqlchemy # yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce yunion.io/x/structarg diff --git a/vendor/yunion.io/x/jsonutils/jsonutils.go b/vendor/yunion.io/x/jsonutils/jsonutils.go index b610037cc3..cc5f1977c8 100644 --- a/vendor/yunion.io/x/jsonutils/jsonutils.go +++ b/vendor/yunion.io/x/jsonutils/jsonutils.go @@ -239,7 +239,7 @@ func parseString(str []byte, offset int) (string, bool, int, error) { ret2: for i < len(str) { switch str[i] { - case ' ', ':', ',', '\t', '\n', '}', ']': + case ' ', ':', ',', '\t', '\r', '\n', '}', ']': break ret2 default: i++ diff --git a/vendor/yunion.io/x/jsonutils/marshal.go b/vendor/yunion.io/x/jsonutils/marshal.go index d47dc67fe5..c1c1279ec5 100644 --- a/vendor/yunion.io/x/jsonutils/marshal.go +++ b/vendor/yunion.io/x/jsonutils/marshal.go @@ -33,13 +33,23 @@ import ( "yunion.io/x/pkg/util/timeutils" ) -func marshalSlice(val reflect.Value, info *reflectutils.SStructFieldInfo) JSONObject { - if val.Len() == 0 && info != nil && info.OmitEmpty { - return JSONNull +func marshalSlice(val reflect.Value, info *reflectutils.SStructFieldInfo, omitEmpty bool) JSONObject { + if val.Kind() == reflect.Slice && val.IsNil() { + if !omitEmpty { + return JSONNull + } else { + return nil + } } - objs := make([]JSONObject, val.Len()) + if val.Len() == 0 && info != nil && info.OmitEmpty && omitEmpty { + return nil + } + objs := make([]JSONObject, 0) for i := 0; i < val.Len(); i += 1 { - objs[i] = marshalValue(val.Index(i), nil) + val := marshalValue(val.Index(i), nil, omitEmpty) + if val != nil { + objs = append(objs, val) + } } arr := NewArray(objs...) if info != nil && info.ForceString { @@ -49,16 +59,23 @@ func marshalSlice(val reflect.Value, info *reflectutils.SStructFieldInfo) JSONOb } } -func marshalMap(val reflect.Value, info *reflectutils.SStructFieldInfo) JSONObject { +func marshalMap(val reflect.Value, info *reflectutils.SStructFieldInfo, omitEmpty bool) JSONObject { + if val.IsNil() { + if !omitEmpty { + return JSONNull + } else { + return nil + } + } keys := val.MapKeys() - if len(keys) == 0 && info != nil && info.OmitEmpty { - return JSONNull + if len(keys) == 0 && info != nil && info.OmitEmpty && omitEmpty { + return nil } objPairs := make([]JSONPair, 0) for i := 0; i < len(keys); i += 1 { key := keys[i] - val := marshalValue(val.MapIndex(key), nil) - if val != JSONNull { + val := marshalValue(val.MapIndex(key), nil, omitEmpty) + if val != nil { objPairs = append(objPairs, JSONPair{key: fmt.Sprintf("%s", key), val: val}) } } @@ -70,10 +87,10 @@ func marshalMap(val reflect.Value, info *reflectutils.SStructFieldInfo) JSONObje } } -func marshalStruct(val reflect.Value, info *reflectutils.SStructFieldInfo) JSONObject { - objPairs := struct2JSONPairs(val) - if len(objPairs) == 0 && info != nil && info.OmitEmpty { - return JSONNull +func marshalStruct(val reflect.Value, info *reflectutils.SStructFieldInfo, omitEmpty bool) JSONObject { + objPairs := struct2JSONPairs(val, omitEmpty) + if len(objPairs) == 0 && info != nil && info.OmitEmpty && omitEmpty { + return nil } dict := NewDict(objPairs...) if info != nil && info.ForceString { @@ -92,7 +109,7 @@ func findValueByKey(pairs []JSONPair, key string) JSONObject { return nil } -func struct2JSONPairs(val reflect.Value) []JSONPair { +func struct2JSONPairs(val reflect.Value, omitEmpty bool) []JSONPair { fields := reflectutils.FetchStructFieldValueSet(val) objPairs := make([]JSONPair, 0, len(fields)) depFields := make(map[string]string) @@ -106,8 +123,8 @@ func struct2JSONPairs(val reflect.Value) []JSONPair { depFields[key] = deprecatedBy continue } - val := marshalValue(fields[i].Value, jsonInfo) - if val != nil && val != JSONNull { + val := marshalValue(fields[i].Value, jsonInfo, omitEmpty) + if val != nil { objPair := JSONPair{key: key, val: val} objPairs = append(objPairs, objPair) } @@ -140,9 +157,9 @@ func struct2JSONPairs(val reflect.Value) []JSONPair { return objPairs } -func marshalInt64(val int64, info *reflectutils.SStructFieldInfo) JSONObject { - if val == 0 && info != nil && info.OmitZero { - return JSONNull +func marshalInt64(val int64, info *reflectutils.SStructFieldInfo, omitEmpty bool) JSONObject { + if val == 0 && info != nil && info.OmitZero && omitEmpty { + return nil } else if info != nil && info.ForceString { return NewString(fmt.Sprintf("%d", val)) } else { @@ -150,9 +167,9 @@ func marshalInt64(val int64, info *reflectutils.SStructFieldInfo) JSONObject { } } -func marshalFloat64(val float64, info *reflectutils.SStructFieldInfo, bit int) JSONObject { - if val == 0.0 && info != nil && info.OmitZero { - return JSONNull +func marshalFloat64(val float64, info *reflectutils.SStructFieldInfo, bit int, omitEmpty bool) JSONObject { + if val == 0.0 && info != nil && info.OmitZero && omitEmpty { + return nil } else if info != nil && info.ForceString { return NewString(fmt.Sprintf("%f", val)) } else { @@ -160,9 +177,9 @@ func marshalFloat64(val float64, info *reflectutils.SStructFieldInfo, bit int) J } } -func marshalFloat32(val float32, info *reflectutils.SStructFieldInfo, bit int) JSONObject { - if val == 0.0 && info != nil && info.OmitZero { - return JSONNull +func marshalFloat32(val float32, info *reflectutils.SStructFieldInfo, bit int, omitEmpty bool) JSONObject { + if val == 0.0 && info != nil && info.OmitZero && omitEmpty { + return nil } else if info != nil && info.ForceString { return NewString(fmt.Sprintf("%f", val)) } else { @@ -170,9 +187,9 @@ func marshalFloat32(val float32, info *reflectutils.SStructFieldInfo, bit int) J } } -func marshalBoolean(val bool, info *reflectutils.SStructFieldInfo) JSONObject { - if !val && info != nil && info.OmitFalse { - return JSONNull +func marshalBoolean(val bool, info *reflectutils.SStructFieldInfo, omitEmpty bool) JSONObject { + if !val && info != nil && info.OmitFalse && omitEmpty { + return nil } else if info != nil && info.ForceString { return NewString(fmt.Sprintf("%v", val)) } else { @@ -184,28 +201,32 @@ func marshalBoolean(val bool, info *reflectutils.SStructFieldInfo) JSONObject { } } -func marshalTristate(val tristate.TriState, info *reflectutils.SStructFieldInfo) JSONObject { +func marshalTristate(val tristate.TriState, info *reflectutils.SStructFieldInfo, omitEmpty bool) JSONObject { if val.IsTrue() { return JSONTrue } else if val.IsFalse() { return JSONFalse } else { - return JSONNull + if omitEmpty { + return nil + } else { + return JSONNull + } } } -func marshalString(val string, info *reflectutils.SStructFieldInfo) JSONObject { - if len(val) == 0 && info != nil && info.OmitEmpty { - return JSONNull +func marshalString(val string, info *reflectutils.SStructFieldInfo, omitEmpty bool) JSONObject { + if len(val) == 0 && info != nil && info.OmitEmpty && omitEmpty { + return nil } else { return NewString(val) } } -func marshalTime(val time.Time, info *reflectutils.SStructFieldInfo) JSONObject { +func marshalTime(val time.Time, info *reflectutils.SStructFieldInfo, omitEmpty bool) JSONObject { if val.IsZero() { - if info != nil && info.OmitEmpty { - return JSONNull + if info != nil && info.OmitEmpty && omitEmpty { + return nil } return NewString("") } else { @@ -222,123 +243,151 @@ func Marshal(obj interface{}) JSONObject { return JSONNull } objValue := reflect.Indirect(val) - return marshalValue(objValue, nil) + mval := marshalValue(objValue, nil, true) + if mval == nil { + return JSONNull + } + return mval } -func marshalValue(objValue reflect.Value, info *reflectutils.SStructFieldInfo) JSONObject { +func marshalValue(objValue reflect.Value, info *reflectutils.SStructFieldInfo, omitEmpty bool) JSONObject { switch objValue.Type() { case JSONDictPtrType, JSONArrayPtrType, JSONBoolPtrType, JSONIntPtrType, JSONFloatPtrType, JSONStringPtrType, JSONObjectType: if objValue.IsNil() { - return JSONNull + if omitEmpty { + return nil + } else { + return JSONNull + } } return objValue.Interface().(JSONObject) case JSONDictType: json, ok := objValue.Interface().(JSONDict) if ok { - if len(json.data) == 0 && info != nil && info.OmitEmpty { - return JSONNull + if len(json.data) == 0 && info != nil && info.OmitEmpty && omitEmpty { + return nil } else { return &json } } else { - return JSONNull + return nil } case JSONArrayType: json, ok := objValue.Interface().(JSONArray) if ok { - if len(json.data) == 0 && info != nil && info.OmitEmpty { - return JSONNull + if len(json.data) == 0 && info != nil && info.OmitEmpty && omitEmpty { + return nil } else { return &json } } else { - return JSONNull + return nil } case JSONBoolType: json, ok := objValue.Interface().(JSONBool) if ok { - if !json.data && info != nil && info.OmitEmpty { - return JSONNull + if !json.data && info != nil && info.OmitEmpty && omitEmpty { + return nil } else { return &json } } else { - return JSONNull + return nil } case JSONIntType: json, ok := objValue.Interface().(JSONInt) if ok { - if json.data == 0 && info != nil && info.OmitEmpty { - return JSONNull + if json.data == 0 && info != nil && info.OmitEmpty && omitEmpty { + return nil } else { return &json } } else { - return JSONNull + return nil } case JSONFloatType: json, ok := objValue.Interface().(JSONFloat) if ok { - if json.data == 0.0 && info != nil && info.OmitEmpty { - return JSONNull + if json.data == 0.0 && info != nil && info.OmitEmpty && omitEmpty { + return nil } else { return &json } } else { - return JSONNull + return nil } case JSONStringType: json, ok := objValue.Interface().(JSONString) if ok { - if len(json.data) == 0 && info != nil && info.OmitEmpty { - return JSONNull + if len(json.data) == 0 && info != nil && info.OmitEmpty && omitEmpty { + return nil } else { return &json } } else { - return JSONNull + return nil } case tristate.TriStateType: tri, ok := objValue.Interface().(tristate.TriState) if ok { - return marshalTristate(tri, info) + return marshalTristate(tri, info, omitEmpty) } else { - return JSONNull + return nil } } switch objValue.Kind() { case reflect.Slice, reflect.Array: - return marshalSlice(objValue, info) + return marshalSlice(objValue, info, omitEmpty) case reflect.Struct: if objValue.Type() == gotypes.TimeType { - return marshalTime(objValue.Interface().(time.Time), info) + return marshalTime(objValue.Interface().(time.Time), info, omitEmpty) } else { - return marshalStruct(objValue, info) + return marshalStruct(objValue, info, omitEmpty) } case reflect.Map: - return marshalMap(objValue, info) + return marshalMap(objValue, info, omitEmpty) case reflect.String: strValue := objValue.Convert(gotypes.StringType) - return marshalString(strValue.Interface().(string), info) + return marshalString(strValue.Interface().(string), info, omitEmpty) case reflect.Bool: - return marshalBoolean(objValue.Interface().(bool), info) + return marshalBoolean(objValue.Interface().(bool), info, omitEmpty) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: intValue := objValue.Convert(gotypes.Int64Type) - return marshalInt64(intValue.Interface().(int64), info) + return marshalInt64(intValue.Interface().(int64), info, omitEmpty) case reflect.Float32: floatVal := objValue.Convert(gotypes.Float32Type) - return marshalFloat32(floatVal.Interface().(float32), info, 32) + return marshalFloat32(floatVal.Interface().(float32), info, 32, omitEmpty) case reflect.Float64: floatVal := objValue.Convert(gotypes.Float64Type) - return marshalFloat64(floatVal.Interface().(float64), info, 64) + return marshalFloat64(floatVal.Interface().(float64), info, 64, omitEmpty) case reflect.Interface, reflect.Ptr: if objValue.IsNil() { - return JSONNull + if omitEmpty { + return nil + } else { + return JSONNull + } } - return marshalValue(objValue.Elem(), info) + return marshalValue(objValue.Elem(), info, omitEmpty) default: log.Errorf("unsupport object %s %s", objValue.Type(), objValue.Interface()) return JSONNull } } + +func MarshalAll(obj interface{}) JSONObject { + if obj == nil { + return JSONNull + } + val := reflect.ValueOf(obj) + if kind := val.Kind(); val.IsZero() && kind == reflect.Ptr { + return JSONNull + } + objValue := reflect.Indirect(val) + mval := marshalValue(objValue, nil, false) + if mval == nil { + return JSONNull + } + return mval +} diff --git a/vendor/yunion.io/x/pkg/errors/consts.go b/vendor/yunion.io/x/pkg/errors/consts.go index 4ac451d15f..399142ec92 100644 --- a/vendor/yunion.io/x/pkg/errors/consts.go +++ b/vendor/yunion.io/x/pkg/errors/consts.go @@ -5,10 +5,16 @@ const ( ErrClient = Error("ClientError") ErrUnclassified = Error("UnclassifiedError") + // network error + ErrDNS = Error("DNSError") + ErrEOF = Error("EOFError") + ErrNetwork = Error("NetworkError") + ErrConnectRefused = Error("ConnectRefusedError") + ErrTimeout = Error("TimeoutError") + ErrNotFound = Error("NotFoundError") ErrDuplicateId = Error("DuplicateIdError") ErrInvalidStatus = Error("InvalidStatusError") - ErrTimeout = Error("TimeoutError") ErrNotImplemented = Error("NotImplementedError") ErrNotSupported = Error("NotSupportedError") diff --git a/vendor/yunion.io/x/pkg/util/compare/compare.go b/vendor/yunion.io/x/pkg/util/compare/compare.go index fb64a78af8..1351de1614 100644 --- a/vendor/yunion.io/x/pkg/util/compare/compare.go +++ b/vendor/yunion.io/x/pkg/util/compare/compare.go @@ -69,12 +69,19 @@ func valueSet2Array(dbSet interface{}, field string) ([]valueElement, error) { return ret, nil } -func CompareSets(dbSet interface{}, extSet interface{}, removed interface{}, commonDB interface{}, commonExt interface{}, added interface{}) error { - dbSetArray, err := valueSet2Array(dbSet, "GetExternalId") +type SCompareSet struct { + DBFunc string + DBSet interface{} + ExtFunc string + ExtSet interface{} +} + +func CompareSetsFunc(cs SCompareSet, removed interface{}, commonDB interface{}, commonExt interface{}, added interface{}) error { + dbSetArray, err := valueSet2Array(cs.DBSet, cs.DBFunc) if err != nil { return err } - extSetArray, err := valueSet2Array(extSet, "GetGlobalId") + extSetArray, err := valueSet2Array(cs.ExtSet, cs.ExtFunc) if err != nil { return err } @@ -135,4 +142,14 @@ func CompareSets(dbSet interface{}, extSet interface{}, removed interface{}, com } } return nil + +} + +func CompareSets(dbSet interface{}, extSet interface{}, removed interface{}, commonDB interface{}, commonExt interface{}, added interface{}) error { + return CompareSetsFunc(SCompareSet{ + DBFunc: "GetExternalId", + DBSet: dbSet, + ExtFunc: "GetGlobalId", + ExtSet: extSet, + }, removed, commonDB, commonExt, added) } diff --git a/vendor/yunion.io/x/pkg/util/regutils/regutils.go b/vendor/yunion.io/x/pkg/util/regutils/regutils.go index 8d9ea9d259..06be8fb77d 100644 --- a/vendor/yunion.io/x/pkg/util/regutils/regutils.go +++ b/vendor/yunion.io/x/pkg/util/regutils/regutils.go @@ -38,6 +38,9 @@ var DATE_COMPACT_REG *regexp.Regexp var ISO_TIME_REG *regexp.Regexp var ISO_NO_SECOND_TIME_REG *regexp.Regexp var FULLISO_TIME_REG *regexp.Regexp +var ISO_TIME_REG2 *regexp.Regexp +var ISO_NO_SECOND_TIME_REG2 *regexp.Regexp +var FULLISO_TIME_REG2 *regexp.Regexp var ZSTACK_TIME_REG *regexp.Regexp var COMPACT_TIME_REG *regexp.Regexp var MYSQL_TIME_REG *regexp.Regexp @@ -68,6 +71,9 @@ func init() { ISO_TIME_REG = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$`) ISO_NO_SECOND_TIME_REG = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$`) FULLISO_TIME_REG = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3,9}(Z|[+-]\d{2}:\d{2})$`) + ISO_TIME_REG2 = regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$`) + ISO_NO_SECOND_TIME_REG2 = regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$`) + FULLISO_TIME_REG2 = regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3,9}(Z|[+-]\d{2}:\d{2})$`) COMPACT_TIME_REG = regexp.MustCompile(`^\d{14}$`) ZSTACK_TIME_REG = regexp.MustCompile(`^\w+ \d{1,2}, \d{4} \d{1,2}:\d{1,2}:\d{1,2} (AM|PM)$`) //ZStack time format "Apr 1, 2019 3:23:17 PM" MYSQL_TIME_REG = regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$`) @@ -202,6 +208,18 @@ func MatchFullISOTime(str string) bool { return FULLISO_TIME_REG.MatchString(str) } +func MatchISOTime2(str string) bool { + return ISO_TIME_REG2.MatchString(str) +} + +func MatchISONoSecondTime2(str string) bool { + return ISO_NO_SECOND_TIME_REG2.MatchString(str) +} + +func MatchFullISOTime2(str string) bool { + return FULLISO_TIME_REG2.MatchString(str) +} + func MatchCompactTime(str string) bool { return COMPACT_TIME_REG.MatchString(str) } diff --git a/vendor/yunion.io/x/pkg/util/timeutils/timeutils.go b/vendor/yunion.io/x/pkg/util/timeutils/timeutils.go index 3dbd23eb18..c96393292c 100644 --- a/vendor/yunion.io/x/pkg/util/timeutils/timeutils.go +++ b/vendor/yunion.io/x/pkg/util/timeutils/timeutils.go @@ -58,6 +58,10 @@ const ( ShortMonthFormat = "200601" ZStackTimeFormat = "Jan 2, 2006 15:04:05 PM" + IsoTimeFormat2 = "2006-01-02 15:04:05Z07:00" + IsoNoSecondTimeFormat2 = "2006-01-02 15:04Z07:00" + FullIsoNanoTimeFormat2 = "2006-01-02 15:04:05.000000000Z07:00" + RFC2882Format = time.RFC1123 ) @@ -113,10 +117,18 @@ func ParseIsoTime(str string) (time.Time, error) { return time.Parse(IsoTimeFormat, str) } +func ParseIsoTime2(str string) (time.Time, error) { + return time.Parse(IsoTimeFormat2, str) +} + func ParseIsoNoSecondTime(str string) (time.Time, error) { return time.Parse(IsoNoSecondTimeFormat, str) } +func ParseIsoNoSecondTime2(str string) (time.Time, error) { + return time.Parse(IsoNoSecondTimeFormat2, str) +} + func toFullIsoNanoTimeFormat(str string) string { // 2019-09-17T20:50:17.66667134+08:00 // 2019-11-19T18:54:48.084-08:00 @@ -143,6 +155,10 @@ func ParseFullIsoTime(str string) (time.Time, error) { return time.Parse(FullIsoNanoTimeFormat, toFullIsoNanoTimeFormat(str)) } +func ParseFullIsoTime2(str string) (time.Time, error) { + return time.Parse(FullIsoNanoTimeFormat2, toFullIsoNanoTimeFormat(str)) +} + func ParseMysqlTime(str string) (time.Time, error) { return time.Parse(MysqlTimeFormat, str) } @@ -183,6 +199,12 @@ func ParseTimeStr(str string) (time.Time, error) { return ParseIsoTime(str) } else if regutils.MatchISONoSecondTime(str) { return ParseIsoNoSecondTime(str) + } else if regutils.MatchFullISOTime2(str) { + return ParseFullIsoTime2(str) + } else if regutils.MatchISOTime2(str) { + return ParseIsoTime2(str) + } else if regutils.MatchISONoSecondTime2(str) { + return ParseIsoNoSecondTime2(str) } else if regutils.MatchMySQLTime(str) { return ParseMysqlTime(str) } else if regutils.MatchNormalTime(str) { diff --git a/vendor/yunion.io/x/pkg/utils/tags.go b/vendor/yunion.io/x/pkg/utils/tags.go index 92c0ba88cb..9926630cc5 100644 --- a/vendor/yunion.io/x/pkg/utils/tags.go +++ b/vendor/yunion.io/x/pkg/utils/tags.go @@ -148,3 +148,21 @@ func TagPop(m map[string]string, key string) (map[string]string, string, bool) { } return m, val, ok } + +func SplitCSV(csv string) []string { + offset := 0 + words := make([]string, 0) + str := []byte(csv) + for offset < len(str) { + var word string + word, offset = _findWord(str, offset, ",\r\n") + words = append(words, word) + if offset < len(str) { + offset++ + if offset >= len(str) { + words = append(words, "") + } + } + } + return words +} diff --git a/vendor/yunion.io/x/sqlchemy/README.md b/vendor/yunion.io/x/sqlchemy/README.md index 8441d66e6e..2561351a95 100644 --- a/vendor/yunion.io/x/sqlchemy/README.md +++ b/vendor/yunion.io/x/sqlchemy/README.md @@ -1,6 +1,7 @@ # sqlchemy [![CircleCI](https://circleci.com/gh/yunionio/sqlchemy.svg?style=svg)](https://circleci.com/gh/yunionio/sqlchemy) +[![codecov](https://codecov.io/gh/yunionio/sqlchemy/branch/master/graph/badge.svg?token=K8cSYZzLbc)](https://codecov.io/gh/yunionio/sqlchemy) [![Go Report Card](https://goreportcard.com/badge/github.com/yunionio/sqlchemy)](https://goreportcard.com/report/github.com/yunionio/sqlchemy) A lightweight golang ORM library inspired by python sqlalchemy. @@ -20,134 +21,151 @@ Quick Examples Table schema is defined by struct field tags - type TestTable struct { - Id string `primary:"true" width:"128" charset:"ascii" nullable:"false"` - Name string `width:"64" charset:"utf8" index:"true"` - Gender string `width:"10" charset:"ascii"` - Age uint8 `default:"18"` - Info jsonutils.JSONObject `nullable:"false"` - Compond *SCompondStruct `width:1024` - CreatedAt time.Time `nullable:"false" created_at:"true"` - UpdatedAt time.Time `nullable:"false" updated_at:"true"` - Version int `default:"0" nullable:"false" auto_version:"true"` - DeletedAt time.Time `` - Deleted bool `nullable:"false" default:"false"` - Notes string `default:"default notes"` - } +```go +type TestTable struct { + Id string `primary:"true" width:"128" charset:"ascii" nullable:"false"` + Name string `width:"64" charset:"utf8" index:"true"` + Gender string `width:"10" charset:"ascii"` + Age uint8 `default:"18"` + Info jsonutils.JSONObject `nullable:"false"` + Compond *SCompondStruct `width:1024` + CreatedAt time.Time `nullable:"false" created_at:"true"` + UpdatedAt time.Time `nullable:"false" updated_at:"true"` + Version int `default:"0" nullable:"false" auto_version:"true"` + DeletedAt time.Time `` + Deleted bool `nullable:"false" default:"false"` + Notes string `default:"default notes"` +} +```` ## Table initialization Create a table from a struct schema - tablespec := sqlchemy.NewTableSpecFromStruct(TestTable{}, "testtable") +```go +tablespec := sqlchemy.NewTableSpecFromStruct(TestTable{}, "testtable") +``` Check whether table schema definition is consistent with schema in database. - if !tablespec.CheckSync() { - log.Fatalf("table not in sync") - } +```go +if !tablespec.CheckSync() { + log.Fatalf("table not in sync") +} +``` Synchronize database table schema and make it consistent with the struct defintion. - err := tablespec.Sync() - if err != nil { - log.Fataf("synchronize table schema failed: %s", er) - } +```go +err := tablespec.Sync() +if err != nil { + log.Fataf("synchronize table schema failed: %s", er) +} +``` ## Query ### Construct query - ti := tablespec.Instance() +```go +ti := tablespec.Instance() - // select * from testtable - q := ti.Query() +// select * from testtable +q := ti.Query() - // select * from testtable where id = '981b10ed-b6f9-4120-8a77-a3b03e343143' - // query by field name, in which the name is unique in the query - q := ti.Query().Equals("id", "981b10ed-b6f9-4120-8a77-a3b03e343143") +// select * from testtable where id = '981b10ed-b6f9-4120-8a77-a3b03e343143' +// query by field name, in which the name is unique in the query +q := ti.Query().Equals("id", "981b10ed-b6f9-4120-8a77-a3b03e343143") - // query by field instance, in which the field name might be ambiguous - q := ti.Query().Filter(sqlchemy.Equals(ti.Field("id"), "981b10ed-b6f9-4120-8a77-a3b03e343143")) +// query by field instance, in which the field name might be ambiguous +q := ti.Query().Filter(sqlchemy.Equals(ti.Field("id"), "981b10ed-b6f9-4120-8a77-a3b03e343143")) - // joint query +// joint query - // select * from t1 join t2 on t1.id=t2.testtable_id where t2.created_at > '2019-11-02' - q := ti.Query("name").Join(t2, sqlchemy.Equals(ti.Field("id"), t2.Field("testtable_id"))).Filter(sqlchermy.GT(t2.Field("created_at"), '2019-11-02') +// select * from t1 join t2 on t1.id=t2.testtable_id where t2.created_at > '2019-11-02' +q := ti.Query("name").Join(t2, sqlchemy.Equals(ti.Field("id"), t2.Field("testtable_id"))).Filter(sqlchermy.GT(t2.Field("created_at"), '2019-11-02') - // union query - // select id, name from testtable where id = '981b10ed-b6f9-4120-8a77-a3b03e343143' union select id, name from testtable where id='6fcc87ca-c1da-40ab-849a-305ff2663901' - q1 := t1.Query("id", "name").Equals("id", "981b10ed-b6f9-4120-8a77-a3b03e343143") - q2 := t1.Query("id", "name").Equals("id", "6fcc87ca-c1da-40ab-849a-305ff2663901") - qu := sqlchemy.Union(q1, q2) +// union query +// select id, name from testtable where id = '981b10ed-b6f9-4120-8a77-a3b03e343143' union select id, name from testtable where id='6fcc87ca-c1da-40ab-849a-305ff2663901' +q1 := t1.Query("id", "name").Equals("id", "981b10ed-b6f9-4120-8a77-a3b03e343143") +q2 := t1.Query("id", "name").Equals("id", "6fcc87ca-c1da-40ab-849a-305ff2663901") +qu := sqlchemy.Union(q1, q2) +``` ### Fetch data - q := ti.Query().Equals("id", "e2bc9b659cec407590dc2f3fcb009acb") +```go +q := ti.Query().Equals("id", "e2bc9b659cec407590dc2f3fcb009acb") - // fetch single row into object - row := TestTable{} - err := q.First(&row) - if err != nil { - log.Fatalf("fetch object error %s", err) - } +// fetch single row into object +row := TestTable{} +err := q.First(&row) +if err != nil { + log.Fatalf("fetch object error %s", err) +} - // fetch single row into a string map, where strMap is map[string]string - strMap, err := q.FirstStringMap() - if err != nil { - log.Fatalf("fetch object error %s", err) - } +// fetch single row into a string map, where strMap is map[string]string +strMap, err := q.FirstStringMap() +if err != nil { + log.Fatalf("fetch object error %s", err) +} - q := ti.Query().Startswith("id", "abc") - // fetch rows - rows := make([]TestTable, 0) - err := q.All(&rows) - if err != nil { - log.Fatalf("query failure: %s", err) - } +q := ti.Query().Startswith("id", "abc") +// fetch rows +rows := make([]TestTable, 0) +err := q.All(&rows) +if err != nil { + log.Fatalf("query failure: %s", err) +} - // fetch rows into string maps, where maps is []map[string]string - maps, err := q.AllStringMap() - if err != nil { - log.Fatalf("query failure: %s", err) - } +// fetch rows into string maps, where maps is []map[string]string +maps, err := q.AllStringMap() +if err != nil { + log.Fatalf("query failure: %s", err) +} +``` ### SubQuery Query can be used as a subquery in other queries. - // derive a subquery from an ordinary query - subq := t1.Query("id").Equals("version", "v2.0").SubQuery() - // use subquery - q := t1.Query().In("id", subq) +```go +// derive a subquery from an ordinary query +subq := t1.Query("id").Equals("version", "v2.0").SubQuery() +// use subquery +q := t1.Query().In("id", subq) +``` ## Insert - // hook to initialize data field before insert - func (t *TestTable) BeforeInsert() { - t.Id = uuid4() - } - // initialize data struct - dt1 := TestTable{ - Name: "Test", - } - // insert the data, primary key fields must be populated - // the primary key has been populated by the BeforeInsert hook - err = tablespec.Insert(&dt1) - - // insert or update - // insert the object if no primary key conflict, otherwise, update the record - err = tablespec.InsertOrUpdate(&dt1) +```go +// hook to initialize data field before insert +func (t *TestTable) BeforeInsert() { + t.Id = uuid4() +} +// initialize data struct +dt1 := TestTable{ + Name: "Test", +} +// insert the data, primary key fields must be populated +// the primary key has been populated by the BeforeInsert hook +err = tablespec.Insert(&dt1) +// insert or update +// insert the object if no primary key conflict, otherwise, update the record +err = tablespec.InsertOrUpdate(&dt1) +``` ## Update - // update the field - _, err = tablespec.Update(&dt3, func() error { - dt3.Name = "New name 4" - dt3.Compond = &SCompondStruct{Id: "998822333", Age: 80} - return nil - }) +```go +// update the field +_, err = tablespec.Update(&dt3, func() error { + dt3.Name = "New name 4" + dt3.Compond = &SCompondStruct{Id: "998822333", Age: 80} + return nil +}) +``` Please refer to sqltest/main.go for more examples. diff --git a/vendor/yunion.io/x/sqlchemy/case.go b/vendor/yunion.io/x/sqlchemy/case.go index acfca9e2bb..a40cd05d9e 100644 --- a/vendor/yunion.io/x/sqlchemy/case.go +++ b/vendor/yunion.io/x/sqlchemy/case.go @@ -23,11 +23,14 @@ type sCaseFieldBranch struct { thenField IQueryField } +// SCaseFunction represents function of case ... when ... branch type SCaseFunction struct { branches []sCaseFieldBranch elseField IQueryField } +// NewFunction creates a field with SQL function +// for example: SUM(count) as total func NewFunction(ifunc IFunction, name string) IQueryField { return &SFunctionFieldBase{ IFunction: ifunc, @@ -35,11 +38,13 @@ func NewFunction(ifunc IFunction, name string) IQueryField { } } +// Else adds else clause for case when function func (cf *SCaseFunction) Else(field IQueryField) *SCaseFunction { cf.elseField = field return cf } +// When adds when clause for case when function func (cf *SCaseFunction) When(when ICondition, then IQueryField) *SCaseFunction { cf.branches = append(cf.branches, sCaseFieldBranch{ whenCondition: when, @@ -48,6 +53,7 @@ func (cf *SCaseFunction) When(when ICondition, then IQueryField) *SCaseFunction return cf } +// NewCase creates a case... when...else... representation instance func NewCase() *SCaseFunction { return &SCaseFunction{} } diff --git a/vendor/yunion.io/x/sqlchemy/column.go b/vendor/yunion.io/x/sqlchemy/column.go index f99d300247..feb0dd6fa2 100644 --- a/vendor/yunion.io/x/sqlchemy/column.go +++ b/vendor/yunion.io/x/sqlchemy/column.go @@ -28,36 +28,82 @@ import ( "yunion.io/x/pkg/utils" ) +// IColumnSpec is an interface that represents a column of a table type IColumnSpec interface { + // Name returns the name of the column Name() string + + // ColType returns type of the column, e.g. INTEGER, VARCHAR ColType() string + + // Default returns default value of the column, represents in string Default() string + + // IsSupportDefault returns whether this column supports being given a default value IsSupportDefault() bool + + // IsNullable returns whether this column is nullable IsNullable() bool + + // SetNullable sets this column as nullable SetNullable(on bool) + + // IsPrimary returns whether this column is part of the primary keys IsPrimary() bool + + // IsUnique returns whether the value of this column unique for each row IsUnique() bool + + // IsIndex returns whether this column is indexable, if it is true, a index of this column will be automatically created IsIndex() bool + + // ExtraDefs returns some extra column attribute definitions, not covered by the standard fields ExtraDefs() string + + // DefinitionString return the SQL presentation of this column DefinitionString() string + + // IsText returns whether this column is actually a text, such a Datetime column is actually a text IsText() bool + + // IsSearchable returns whether this column is searchable, e.g. a integer column is not searchable, but a text field is searchable IsSearchable() bool + + // IsAscii returns whether this column is an ASCII type text, if true, the column should be compared with a UTF8 string IsAscii() bool + + // IsNumeric returns whether this column is a numeric type column, e.g. integer or float IsNumeric() bool + + // ConvertFromString returns the SQL representation of a value in string format for this column ConvertFromString(str string) string + // ConvertToString(str string) string + + // ConvertFromValue returns the SQL representation of a value for this column ConvertFromValue(val interface{}) interface{} + // ConvertToValue(str interface{}) interface{} + + // IsZero is used to determine a value is the zero value for this column IsZero(val interface{}) bool + + // AllowZero returns whether this column allow a zero value AllowZero() bool + // IsEqual(v1, v2 interface{}) bool + + // Tags returns the field tags for this column, which is in the struct definition Tags() map[string]string + // IsPointer returns whether this column is a pointer type definition, e.g. *int, *bool IsPointer() bool + // SetDefault sets the default value in the format of string for this column SetDefault(defStr string) } +// SBaseColumn is the base structure represents a column type SBaseColumn struct { name string dbName string @@ -72,98 +118,118 @@ type SBaseColumn struct { tags map[string]string } +// IsPointer implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) IsPointer() bool { return c.isPointer } +// Name implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) Name() string { if len(c.dbName) > 0 { return c.dbName - } else { - return c.name } + return c.name } +// ColType implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) ColType() string { return c.sqlType } +// Default implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) Default() string { return c.defaultString } +// SetDefault implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) SetDefault(defStr string) { c.defaultString = defStr } +// IsSupportDefault implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) IsSupportDefault() bool { return true } +// IsNullable implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) IsNullable() bool { return c.isNullable } +// SetNullable implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) SetNullable(on bool) { c.isNullable = on } +// IsPrimary implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) IsPrimary() bool { return c.isPrimary } +// IsUnique implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) IsUnique() bool { return c.isUnique } +// IsIndex implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) IsIndex() bool { return c.isIndex } +// ExtraDefs implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) ExtraDefs() string { return "" } +// IsText implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) IsText() bool { return false } +// IsAscii implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) IsAscii() bool { return false } +// IsSearchable implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) IsSearchable() bool { return false } +// IsNumeric implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) IsNumeric() bool { return false } +// AllowZero implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) AllowZero() bool { return c.isAllowZero } +// ConvertFromString implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) ConvertFromString(str string) string { return str } -func (c *SBaseColumn) ConvertToString(str string) string { +/*func (c *SBaseColumn) ConvertToString(str string) string { return str -} +}*/ +// ConvertFromValue implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) ConvertFromValue(val interface{}) interface{} { return val } -func (c *SBaseColumn) ConvertToValue(val interface{}) interface{} { +/*func (c *SBaseColumn) ConvertToValue(val interface{}) interface{} { return val -} +}*/ +// Tags implementation of SBaseColumn for IColumnSpec func (c *SBaseColumn) Tags() map[string]string { return c.tags } +// generate SQL representation of a column func definitionBuffer(c IColumnSpec) bytes.Buffer { var buf bytes.Buffer buf.WriteByte('`') @@ -204,6 +270,7 @@ func definitionBuffer(c IColumnSpec) bytes.Buffer { return buf } +// NewBaseColumn returns an instance of SBaseColumn func NewBaseColumn(name string, sqltype string, tagmap map[string]string, isPointer bool) SBaseColumn { var val string var ok bool @@ -260,19 +327,21 @@ func NewBaseColumn(name string, sqltype string, tagmap map[string]string, isPoin } } +// SBaseWidthColumn represents a type of column that with width attribute, such as VARCHAR(20), INT(10) type SBaseWidthColumn struct { SBaseColumn width int } +// ColType implementation of SBaseWidthColumn for IColumnSpec func (c *SBaseWidthColumn) ColType() string { if c.width > 0 { return fmt.Sprintf("%s(%d)", c.sqlType, c.width) - } else { - return c.sqlType } + return c.sqlType } +// NewBaseWidthColumn return an instance of SBaseWidthColumn func NewBaseWidthColumn(name string, sqltype string, tagmap map[string]string, isPointer bool) SBaseWidthColumn { width := 0 tagmap, v, ok := utils.TagPop(tagmap, TAG_WIDTH) @@ -286,15 +355,18 @@ func NewBaseWidthColumn(name string, sqltype string, tagmap map[string]string, i return wc } +// SBooleanColumn represents a boolean type column, which is a int(1) for mysql, with value of true or false type SBooleanColumn struct { SBaseWidthColumn } +// DefinitionString implementation of SBooleanColumn for IColumnSpec func (c *SBooleanColumn) DefinitionString() string { buf := definitionBuffer(c) return buf.String() } +// ConvertFromString implementation of SBooleanColumn for IColumnSpec func (c *SBooleanColumn) ConvertFromString(str string) string { switch strings.ToLower(str) { case "true", "yes", "on", "ok", "1": @@ -304,7 +376,7 @@ func (c *SBooleanColumn) ConvertFromString(str string) string { } } -func (c *SBooleanColumn) ConvertFromValue(val interface{}) interface{} { +/*func (c *SBooleanColumn) ConvertFromValue(val interface{}) interface{} { switch bVal := val.(type) { case bool: if bVal { @@ -323,18 +395,19 @@ func (c *SBooleanColumn) ConvertFromValue(val interface{}) interface{} { default: return 0 } -} +}*/ +// IsZero implementation of SBooleanColumn for IColumnSpec func (c *SBooleanColumn) IsZero(val interface{}) bool { if c.isPointer { bVal := val.(*bool) return bVal == nil - } else { - bVal := val.(bool) - return bVal == false } + bVal := val.(bool) + return bVal == false } +// NewBooleanColumn return an instance of SBooleanColumn func NewBooleanColumn(name string, tagmap map[string]string, isPointer bool) SBooleanColumn { bc := SBooleanColumn{SBaseWidthColumn: NewBaseWidthColumn(name, "TINYINT", tagmap, isPointer)} if !bc.IsPointer() && len(bc.Default()) > 0 && bc.ConvertFromString(bc.Default()) == "1" { @@ -344,15 +417,18 @@ func NewBooleanColumn(name string, tagmap map[string]string, isPointer bool) SBo return bc } +// STristateColumn represents a tristate type column, with value of true, false or none type STristateColumn struct { SBaseWidthColumn } +// DefinitionString implementation of STristateColumn for IColumnSpec func (c *STristateColumn) DefinitionString() string { buf := definitionBuffer(c) return buf.String() } +// ConvertFromString implementation of STristateColumn for IColumnSpec func (c *STristateColumn) ConvertFromString(str string) string { switch strings.ToLower(str) { case "true", "yes", "on", "ok", "1": @@ -364,43 +440,54 @@ func (c *STristateColumn) ConvertFromString(str string) string { } } +// ConvertFromValue implementation of STristateColumn for IColumnSpec func (c *STristateColumn) ConvertFromValue(val interface{}) interface{} { bVal := val.(tristate.TriState) if bVal == tristate.True { return 1 - } else { - return 0 } + return 0 } +// IsZero implementation of STristateColumn for IColumnSpec func (c *STristateColumn) IsZero(val interface{}) bool { if c.isPointer { bVal := val.(*tristate.TriState) return bVal == nil - } else { - bVal := val.(tristate.TriState) - return bVal == tristate.None } + bVal := val.(tristate.TriState) + return bVal == tristate.None } +// NewTristateColumn return an instance of STristateColumn func NewTristateColumn(name string, tagmap map[string]string, isPointer bool) STristateColumn { bc := STristateColumn{SBaseWidthColumn: NewBaseWidthColumn(name, "TINYINT", tagmap, isPointer)} return bc } +// SIntegerColumn represents an integer type of column, with value of integer type SIntegerColumn struct { SBaseWidthColumn - IsAutoIncrement bool - IsAutoVersion bool - IsUnsigned bool + // Is this column an autoincrement colmn + IsAutoIncrement bool + + // Is this column is a version column for this records + IsAutoVersion bool + + // Is this column a unsigned integer? + IsUnsigned bool + + // If this column is an autoincrement column, AutoIncrementOffset records the initial offset AutoIncrementOffset int64 } +// IsNumeric implementation of SIntegerColumn for IColumnSpec func (c *SIntegerColumn) IsNumeric() bool { return true } +// ExtraDefs implementation of SIntegerColumn for IColumnSpec func (c *SIntegerColumn) ExtraDefs() string { if c.IsAutoIncrement { return "AUTO_INCREMENT" @@ -408,11 +495,13 @@ func (c *SIntegerColumn) ExtraDefs() string { return "" } +// DefinitionString implementation of SIntegerColumn for IColumnSpec func (c *SIntegerColumn) DefinitionString() string { buf := definitionBuffer(c) return buf.String() } +// IsZero implementation of SIntegerColumn for IColumnSpec func (c *SIntegerColumn) IsZero(val interface{}) bool { if val == nil || (c.isPointer && reflect.ValueOf(val).IsNil()) { return true @@ -424,6 +513,7 @@ func (c *SIntegerColumn) IsZero(val interface{}) bool { return true } +// ColType implementation of SIntegerColumn for IColumnSpec func (c *SIntegerColumn) ColType() string { str := (&c.SBaseWidthColumn).ColType() if c.IsUnsigned { @@ -432,6 +522,7 @@ func (c *SIntegerColumn) ColType() string { return str } +// NewIntegerColumn return an instance of SIntegerColumn func NewIntegerColumn(name string, sqltype string, unsigned bool, tagmap map[string]string, isPointer bool) SIntegerColumn { autoinc := false autoincBase := int64(0) @@ -471,19 +562,23 @@ func NewIntegerColumn(name string, sqltype string, unsigned bool, tagmap map[str return c } +// SFloatColumn represents a float type column, e.g. float32 or float64 type SFloatColumn struct { SBaseColumn } +// IsNumeric implementation of SFloatColumn for IColumnSpec func (c *SFloatColumn) IsNumeric() bool { return true } +// DefinitionString implementation of SFloatColumn for IColumnSpec func (c *SFloatColumn) DefinitionString() string { buf := definitionBuffer(c) return buf.String() } +// IsZero implementation of SFloatColumn for IColumnSpec func (c *SFloatColumn) IsZero(val interface{}) bool { if c.isPointer { switch val.(type) { @@ -503,28 +598,34 @@ func (c *SFloatColumn) IsZero(val interface{}) bool { return true } +// NewFloatColumn returns an instance of SFloatColumn func NewFloatColumn(name string, sqlType string, tagmap map[string]string, isPointer bool) SFloatColumn { return SFloatColumn{SBaseColumn: NewBaseColumn(name, sqlType, tagmap, isPointer)} } +// SDecimalColumn represents a DECIMAL type of column, i.e. a float with fixed width of digits type SDecimalColumn struct { SBaseWidthColumn Precision int } +// ColType implementation of SDecimalColumn for IColumnSpec func (c *SDecimalColumn) ColType() string { return fmt.Sprintf("%s(%d, %d)", c.sqlType, c.width, c.Precision) } +// IsNumeric implementation of SDecimalColumn for IColumnSpec func (c *SDecimalColumn) IsNumeric() bool { return true } +// DefinitionString implementation of SDecimalColumn for IColumnSpec func (c *SDecimalColumn) DefinitionString() string { buf := definitionBuffer(c) return buf.String() } +// IsZero implementation of SDecimalColumn for IColumnSpec func (c *SDecimalColumn) IsZero(val interface{}) bool { if c.isPointer { switch val.(type) { @@ -544,6 +645,7 @@ func (c *SDecimalColumn) IsZero(val interface{}) bool { return true } +// NewDecimalColumn returns an instance of SDecimalColumn func NewDecimalColumn(name string, tagmap map[string]string, isPointer bool) SDecimalColumn { tagmap, v, ok := utils.TagPop(tagmap, TAG_PRECISION) if !ok { @@ -559,21 +661,23 @@ func NewDecimalColumn(name string, tagmap map[string]string, isPointer bool) SDe } } +// STextColumn represents a text type of column type STextColumn struct { SBaseWidthColumn Charset string } +// IsSupportDefault implementation of STextColumn for IColumnSpec func (c *STextColumn) IsSupportDefault() bool { // https://stackoverflow.com/questions/3466872/why-cant-a-text-column-have-a-default-value-in-mysql // MySQL does not support default for TEXT/BLOB if c.sqlType == "VARCHAR" { return true - } else { - return false } + return false } +// ColType implementation of STextColumn for IColumnSpec func (c *STextColumn) ColType() string { var charset string var collate string @@ -588,35 +692,39 @@ func (c *STextColumn) ColType() string { return fmt.Sprintf("%s CHARACTER SET '%s' COLLATE '%s'", c.SBaseWidthColumn.ColType(), charset, collate) } +// IsText implementation of STextColumn for IColumnSpec func (c *STextColumn) IsText() bool { return true } +// IsSearchable implementation of STextColumn for IColumnSpec func (c *STextColumn) IsSearchable() bool { return true } +// IsAscii implementation of STextColumn for IColumnSpec func (c *STextColumn) IsAscii() bool { if c.Charset == "ascii" { return true - } else { - return false } + return false } +// DefinitionString implementation of STextColumn for IColumnSpec func (c *STextColumn) DefinitionString() string { buf := definitionBuffer(c) return buf.String() } +// IsZero implementation of STextColumn for IColumnSpec func (c *STextColumn) IsZero(val interface{}) bool { if c.isPointer { return gotypes.IsNil(val) - } else { - return reflect.ValueOf(val).Len() == 0 } + return reflect.ValueOf(val).Len() == 0 } +// NewTextColumn return an instance of STextColumn func NewTextColumn(name string, tagmap map[string]string, isPointer bool) STextColumn { var width int var sqltype string @@ -666,29 +774,33 @@ func NewStringColumn(name string, sqltype string, tagmap map[string]string) SStr return sc }*/ +// STimeTypeColumn represents a Detetime type of column, e.g. DateTime type STimeTypeColumn struct { SBaseColumn } +// IsText implementation of STimeTypeColumn for IColumnSpec func (c *STimeTypeColumn) IsText() bool { return true } +// DefinitionString implementation of STimeTypeColumn for IColumnSpec func (c *STimeTypeColumn) DefinitionString() string { buf := definitionBuffer(c) return buf.String() } +// IsZero implementation of STimeTypeColumn for IColumnSpec func (c *STimeTypeColumn) IsZero(val interface{}) bool { if c.isPointer { bVal := val.(*time.Time) return bVal == nil - } else { - bVal := val.(time.Time) - return bVal.IsZero() } + bVal := val.(time.Time) + return bVal.IsZero() } +// NewTimeTypeColumn return an instance of STimeTypeColumn func NewTimeTypeColumn(name string, typeStr string, tagmap map[string]string, isPointer bool) STimeTypeColumn { dc := STimeTypeColumn{ NewBaseColumn(name, typeStr, tagmap, isPointer), @@ -696,12 +808,18 @@ func NewTimeTypeColumn(name string, typeStr string, tagmap map[string]string, is return dc } +// SDateTimeColumn represents a DateTime type of column type SDateTimeColumn struct { STimeTypeColumn + + // Is this column a 'created_at' field, whichi records the time of create this record IsCreatedAt bool + + // Is this column a 'updated_at' field, whichi records the time when this record was updated IsUpdatedAt bool } +// NewDateTimeColumn returns an instance of DateTime column func NewDateTimeColumn(name string, tagmap map[string]string, isPointer bool) SDateTimeColumn { createdAt := false updatedAt := false @@ -720,15 +838,18 @@ func NewDateTimeColumn(name string, tagmap map[string]string, isPointer bool) SD return dtc } +// CompoundColumn represents a column of compound tye, e.g. a JSON, an Array, or a struct type CompoundColumn struct { STextColumn } +// DefinitionString implementation of CompoundColumn for IColumnSpec func (c *CompoundColumn) DefinitionString() string { buf := definitionBuffer(c) return buf.String() } +// IsZero implementation of CompoundColumn for IColumnSpec func (c *CompoundColumn) IsZero(val interface{}) bool { if val == nil { return true @@ -739,15 +860,16 @@ func (c *CompoundColumn) IsZero(val interface{}) bool { return false } +// ConvertFromValue implementation of CompoundColumn for IColumnSpec func (c *CompoundColumn) ConvertFromValue(val interface{}) interface{} { bVal, ok := val.(gotypes.ISerializable) if ok && bVal != nil { return bVal.String() - } else { - return "" } + return "" } +// NewCompoundColumn returns an instance of CompoundColumn func NewCompoundColumn(name string, tagmap map[string]string, isPointer bool) CompoundColumn { dtc := CompoundColumn{NewTextColumn(name, tagmap, isPointer)} return dtc diff --git a/vendor/yunion.io/x/sqlchemy/conditions.go b/vendor/yunion.io/x/sqlchemy/conditions.go index cd317641c3..4628af41ef 100644 --- a/vendor/yunion.io/x/sqlchemy/conditions.go +++ b/vendor/yunion.io/x/sqlchemy/conditions.go @@ -21,11 +21,16 @@ import ( "yunion.io/x/pkg/util/reflectutils" ) +// ICondition is the interface representing a condition for SQL query +// e.g. WHERE a1 = b1 is a condition of equal +// the condition support nested condition, with AND, OR and NOT boolean operators type ICondition interface { WhereClause() string Variables() []interface{} } +// SCompoundConditions is a Compound condition represents AND or OR boolean operation +// Compound condition also follows the ICondition interface type SCompoundConditions struct { conditions []ICondition } @@ -45,10 +50,12 @@ func compoundWhereClause(c *SCompoundConditions, op string) string { return buf.String() } +// WhereClause implementation of SCompoundConditions for ICondition func (c *SCompoundConditions) WhereClause() string { return "" } +// Variables implementation of SCompoundConditions for ICondition func (c *SCompoundConditions) Variables() []interface{} { vars := make([]interface{}, 0) for _, cond := range c.conditions { @@ -60,22 +67,27 @@ func (c *SCompoundConditions) Variables() []interface{} { return vars } +// SAndConditions represents the AND condition, which is a SCompoundConditions type SAndConditions struct { SCompoundConditions } +// WhereClause implementation of SAndConditions for IConditionq func (c *SAndConditions) WhereClause() string { return compoundWhereClause(&c.SCompoundConditions, SQL_OP_AND) } +// SOrConditions represents the OR condition, which is a SCompoundConditions type SOrConditions struct { SCompoundConditions } +// WhereClause implementation of SOrConditions for ICondition func (c *SOrConditions) WhereClause() string { return compoundWhereClause(&c.SCompoundConditions, SQL_OP_OR) } +// AND method that combines many conditions with AND operator func AND(cond ...ICondition) ICondition { conds := make([]ICondition, 0) for _, c := range cond { @@ -90,6 +102,7 @@ func AND(cond ...ICondition) ICondition { return &cc } +// OR method that combines many conditions with OR operator func OR(cond ...ICondition) ICondition { conds := make([]ICondition, 0) for _, c := range cond { @@ -104,152 +117,187 @@ func OR(cond ...ICondition) ICondition { return &cc } +// SNotCondition represents the NOT condition, which is a boolean operator type SNotCondition struct { condition ICondition } +// WhereClause implementationq of SNotCondition for ICondition func (c *SNotCondition) WhereClause() string { return fmt.Sprintf("%s (%s)", SQL_OP_NOT, c.condition.WhereClause()) } +// Variables implementation of SNotCondition for ICondition func (c *SNotCondition) Variables() []interface{} { return c.condition.Variables() } +// NOT method that makes negative operator on a condition func NOT(cond ICondition) ICondition { cc := SNotCondition{condition: cond} return &cc } +// SSingleCondition represents a kind of condition that composed of one query field type SSingleCondition struct { field IQueryField } +// Variables implementation of SSingleCondition for ICondition func (c *SSingleCondition) Variables() []interface{} { return []interface{}{} } +// NewSingleCondition returns an instance of SSingleCondition func NewSingleCondition(field IQueryField) SSingleCondition { return SSingleCondition{field: field} } +// SIsNullCondition is a condition representing a comparison with null, e.g. a is null type SIsNullCondition struct { SSingleCondition } +// WhereClause implementation for SIsNullCondition for ICondition func (c *SIsNullCondition) WhereClause() string { return fmt.Sprintf("%s IS NULL", c.field.Reference()) } +// IsNull methods that justifies a field is null func IsNull(f IQueryField) ICondition { c := SIsNullCondition{NewSingleCondition(f)} return &c } +// SIsNotNullCondition is a condition represents a comparison with not null, e.g. a is not null type SIsNotNullCondition struct { SSingleCondition } +// WhereClause implementation of SIsNotNullCondition for ICondition func (c *SIsNotNullCondition) WhereClause() string { return fmt.Sprintf("%s IS NOT NULL", c.field.Reference()) } +// IsNotNull methods that justifies a field is not null func IsNotNull(f IQueryField) ICondition { c := SIsNotNullCondition{NewSingleCondition(f)} return &c } +// SIsEmptyCondition is a condition representing the empty status of a field type SIsEmptyCondition struct { SSingleCondition } +// WhereClause implementation of SIsEmptyCondition for ICondition func (c *SIsEmptyCondition) WhereClause() string { return fmt.Sprintf("LENGTH(%s) = 0", c.field.Reference()) } +// IsEmpty method that justifies where a text field is empty, e.g. length is zero func IsEmpty(f IQueryField) ICondition { c := SIsEmptyCondition{NewSingleCondition(f)} return &c } +// SIsNullOrEmptyCondition is a condition that justifies a field is null or empty type SIsNullOrEmptyCondition struct { SSingleCondition } +// WhereClause implementation of SIsNullOrEmptyCondition for ICondition func (c *SIsNullOrEmptyCondition) WhereClause() string { return fmt.Sprintf("%s IS NULL OR LENGTH(%s) = 0", c.field.Reference(), c.field.Reference()) } +// IsNullOrEmpty is the ethod justifies a field is null or empty, e.g. a is null or length(a) == 0 func IsNullOrEmpty(f IQueryField) ICondition { c := SIsNullOrEmptyCondition{NewSingleCondition(f)} return &c } +// SIsNotEmptyCondition represents a condition that represents a field is not empty type SIsNotEmptyCondition struct { SSingleCondition } +// WhereClause implementation of SIsNotEmptyCondition for ICondition func (c *SIsNotEmptyCondition) WhereClause() string { return fmt.Sprintf("%s IS NOT NULL AND LENGTH(%s) > 0", c.field.Reference(), c.field.Reference()) } +// IsNotEmpty method justifies a field is not empty func IsNotEmpty(f IQueryField) ICondition { c := SIsNotEmptyCondition{NewSingleCondition(f)} return &c } +// SIsTrueCondition represents a boolean field (TINYINT) is true, e.g. a == 1 type SIsTrueCondition struct { SSingleCondition } +// WhereClause implementation of SIsTrueCondition for ICondition func (c *SIsTrueCondition) WhereClause() string { return fmt.Sprintf("%s = 1", c.field.Reference()) } +// IsTrue method that justifies a field is true, e.g. field == 1 func IsTrue(f IQueryField) ICondition { c := SIsTrueCondition{NewSingleCondition(f)} return &c } +// SIsFalseCondition represents a boolean is false type SIsFalseCondition struct { SSingleCondition } +// WhereClause implementation of SIsFalseCondition for ICondition func (c *SIsFalseCondition) WhereClause() string { return fmt.Sprintf("%s = 0", c.field.Reference()) } +// IsFalse method justifies a boolean is false func IsFalse(f IQueryField) ICondition { c := SIsFalseCondition{NewSingleCondition(f)} return &c } +// SNoLaterThanCondition coompares a DATETIME field with current time and ensure the field is no later than now, e.g. a <= NOW() type SNoLaterThanCondition struct { SSingleCondition } +// WhereClause implementation of SNoLaterThanCondition for ICondition func (c *SNoLaterThanCondition) WhereClause() string { - return fmt.Sprintf("%s >= NOW()", c.field.Reference()) + return fmt.Sprintf("%s <= NOW()", c.field.Reference()) } +// NoLaterThan method justifies a DATETIME field is before current time func NoLaterThan(f IQueryField) ICondition { c := SNoLaterThanCondition{NewSingleCondition(f)} return &c } +// SNoEarlierThanCondition compares a field with current time and ensure the field is no earlier than NOW, e.g. a >= NOW() type SNoEarlierThanCondition struct { SSingleCondition } +// WhereClause implementation of SNoEarlierThanCondition for ICondition func (c *SNoEarlierThanCondition) WhereClause() string { - return fmt.Sprintf("%s <= NOW()", c.field.Reference()) + return fmt.Sprintf("%s >= NOW()", c.field.Reference()) } +// NoEarlierThan justifies a field is no earlier than current time func NoEarlierThan(f IQueryField) ICondition { c := SNoEarlierThanCondition{NewSingleCondition(f)} return &c } +// STupleCondition is a base condition that composed of two fields type STupleCondition struct { left IQueryField right interface{} @@ -273,7 +321,7 @@ func questionMark(count int) string { } else { var buf bytes.Buffer buf.WriteString("( ") - for i := 0; i < count; i += 1 { + for i := 0; i < count; i++ { if i > 0 { buf.WriteString(", ") } @@ -313,14 +361,17 @@ func varConditionVariables(v interface{}) []interface{} { } } +// NewTupleCondition returns an instance of tuple condition func NewTupleCondition(l IQueryField, r interface{}) STupleCondition { return STupleCondition{left: l, right: r} } +// Variables implementation of STupleCondition for ICondition func (t *STupleCondition) Variables() []interface{} { return varConditionVariables(t.right) } +// SInCondition represents a IN operation in SQL query type SInCondition struct { STupleCondition op string @@ -334,10 +385,12 @@ func inConditionWhereClause(t *STupleCondition, op string) string { return "0" } +// WhereClause implementation of SInCondition for ICondition func (t *SInCondition) WhereClause() string { return inConditionWhereClause(&t.STupleCondition, t.op) } +// In SQL operator func In(f IQueryField, v interface{}) ICondition { c := SInCondition{ NewTupleCondition(f, v), @@ -346,6 +399,7 @@ func In(f IQueryField, v interface{}) ICondition { return &c } +// NotIn SQL operator func NotIn(f IQueryField, v interface{}) ICondition { c := SInCondition{ NewTupleCondition(f, v), @@ -354,6 +408,7 @@ func NotIn(f IQueryField, v interface{}) ICondition { return &c } +// SLikeCondition represents LIKE operation in a SQL query type SLikeCondition struct { STupleCondition } @@ -369,15 +424,18 @@ func likeEscape(s string) string { return res.String() } +// WhereClause implementation for SLikeCondition for ICondition func (t *SLikeCondition) WhereClause() string { return tupleConditionWhereClause(&t.STupleCondition, SQL_OP_LIKE) } +// Like SQL operator func Like(f IQueryField, v string) ICondition { c := SLikeCondition{NewTupleCondition(f, v)} return &c } +// ContainsAny is a OR combination of serveral Contains conditions func ContainsAny(f IQueryField, v []string) ICondition { conds := make([]ICondition, len(v)) for i := range v { @@ -386,107 +444,130 @@ func ContainsAny(f IQueryField, v []string) ICondition { return OR(conds...) } +// Contains method is a shortcut of LIKE method, Contains represents the condtion that a field contains a substring func Contains(f IQueryField, v string) ICondition { v = likeEscape(v) nv := fmt.Sprintf("%%%s%%", v) return Like(f, nv) } +// Startswith method is a shortcut of LIKE method, Startswith represents the condition that field starts with a substring func Startswith(f IQueryField, v string) ICondition { v = likeEscape(v) nv := fmt.Sprintf("%s%%", v) return Like(f, nv) } +// Endswith method is a shortcut of LIKE condition, Endswith represents that condition that field endswith a substring func Endswith(f IQueryField, v string) ICondition { v = likeEscape(v) nv := fmt.Sprintf("%%%s", v) return Like(f, nv) } +// SEqualsCondition represents equal operation between two fields type SEqualsCondition struct { STupleCondition } +// WhereClause implementation of SEqualsCondition for ICondition func (t *SEqualsCondition) WhereClause() string { return tupleConditionWhereClause(&t.STupleCondition, SQL_OP_EQUAL) } +// Equals method represents equal of two fields func Equals(f IQueryField, v interface{}) ICondition { c := SEqualsCondition{NewTupleCondition(f, v)} return &c } +// SNotEqualsCondition is the opposite of equal condition type SNotEqualsCondition struct { STupleCondition } +// WhereClause implementation of SNotEqualsCondition for ICondition func (t *SNotEqualsCondition) WhereClause() string { return tupleConditionWhereClause(&t.STupleCondition, SQL_OP_NOTEQUAL) } +// NotEquals method represents not equal of two fields func NotEquals(f IQueryField, v interface{}) ICondition { c := SNotEqualsCondition{NewTupleCondition(f, v)} return &c } +// SGreatEqualCondition represents >= operation on two fields type SGreatEqualCondition struct { STupleCondition } +// WhereClause implementation of SGreatEqualCondition for ICondition func (t *SGreatEqualCondition) WhereClause() string { return tupleConditionWhereClause(&t.STupleCondition, SQL_OP_GE) } +// GE method represetns operation of Greate Than Or Equal to, e.g. a >= b func GE(f IQueryField, v interface{}) ICondition { c := SGreatEqualCondition{NewTupleCondition(f, v)} return &c } +// SGreatThanCondition represetns > operation on two fields type SGreatThanCondition struct { STupleCondition } +// WhereClause implementation of SGreatThanCondition for ICondition func (t *SGreatThanCondition) WhereClause() string { return tupleConditionWhereClause(&t.STupleCondition, SQL_OP_GT) } +// GT method represents operation of Great Than, e.g. a > b func GT(f IQueryField, v interface{}) ICondition { c := SGreatThanCondition{NewTupleCondition(f, v)} return &c } +// SLessEqualCondition represents <= operation on two fields type SLessEqualCondition struct { STupleCondition } +// WhereClause implementation of SLessEqualCondition for ICondition func (t *SLessEqualCondition) WhereClause() string { return tupleConditionWhereClause(&t.STupleCondition, SQL_OP_LE) } +// LE method represents operation of Less Than Or Equal to, e.q. a <= b func LE(f IQueryField, v interface{}) ICondition { c := SLessEqualCondition{NewTupleCondition(f, v)} return &c } +// SLessThanCondition represents < operation on two fields type SLessThanCondition struct { STupleCondition } +// WhereClause implementation of SLessThanCondition for ICondition func (t *SLessThanCondition) WhereClause() string { return tupleConditionWhereClause(&t.STupleCondition, SQL_OP_LT) } +// LT method represents operation of Less Than, e.g. a < b func LT(f IQueryField, v interface{}) ICondition { c := SLessThanCondition{NewTupleCondition(f, v)} return &c } +// STripleCondition represents a base condition that composed of THREE fields type STripleCondition struct { STupleCondition right2 interface{} } +// Variables implementation of STripleCondition for ICondition func (t *STripleCondition) Variables() []interface{} { ret := make([]interface{}, 0) vars := varConditionVariables(t.right) @@ -496,41 +577,51 @@ func (t *STripleCondition) Variables() []interface{} { return ret } +// NewTripleCondition return an instance of STripleCondition func NewTripleCondition(l IQueryField, r interface{}, r2 interface{}) STripleCondition { return STripleCondition{STupleCondition: NewTupleCondition(l, r), right2: r2} } +// SBetweenCondition represents BETWEEN operator, e.g. c between a and b type SBetweenCondition struct { STripleCondition } +// WhereClause implementation of SBetweenCondition for ICondition func (t *SBetweenCondition) WhereClause() string { ret := tupleConditionWhereClause(&t.STupleCondition, SQL_OP_BETWEEN) return fmt.Sprintf("%s AND %s", ret, varConditionWhereClause(t.right2)) } +// Between SQL operator func Between(f IQueryField, r1, r2 interface{}) ICondition { c := SBetweenCondition{NewTripleCondition(f, r1, r2)} return &c } +// STrueCondition represents a dummy condition that is always true type STrueCondition struct{} +// WhereClause implementation of STrueCondition for ICondition func (t *STrueCondition) WhereClause() string { return "1" } +// Variables implementation of STrueCondition for ICondition func (t *STrueCondition) Variables() []interface{} { return nil } +// SFalseCondition is a dummy condition that is always false type SFalseCondition struct{} +// WhereClause implementation of SFalseCondition for ICondition func (t *SFalseCondition) WhereClause() string { return "0" } +// Variables implementation of SFalseCondition for ICondition func (t *SFalseCondition) Variables() []interface{} { return nil } diff --git a/vendor/yunion.io/x/sqlchemy/const.go b/vendor/yunion.io/x/sqlchemy/const.go index 1f192b0030..d4478788ab 100644 --- a/vendor/yunion.io/x/sqlchemy/const.go +++ b/vendor/yunion.io/x/sqlchemy/const.go @@ -20,47 +20,78 @@ import ( ) const ( - SQL_OP_AND = "AND" - SQL_OP_OR = "OR" - SQL_OP_NOT = "NOT" - SQL_OP_LIKE = "LIKE" - SQL_OP_IN = "IN" - SQL_OP_NOTIN = "NOT IN" - SQL_OP_EQUAL = "=" - SQL_OP_LT = "<" - SQL_OP_LE = "<=" - SQL_OP_GT = ">" - SQL_OP_GE = ">=" - SQL_OP_BETWEEN = "BETWEEN" + // SQL_OP_AND represents AND operator + SQL_OP_AND = "AND" + // SQL_OP_OR represents OR operator + SQL_OP_OR = "OR" + // SQL_OP_NOT represents NOT operator + SQL_OP_NOT = "NOT" + // SQL_OP_LIKE represents LIKE operator + SQL_OP_LIKE = "LIKE" + // SQL_OP_IN represents IN operator + SQL_OP_IN = "IN" + // SQL_OP_NOTIN represents NOT IN operator + SQL_OP_NOTIN = "NOT IN" + // SQL_OP_EQUAL represents EQUAL operator + SQL_OP_EQUAL = "=" + // SQL_OP_LT represents < operator + SQL_OP_LT = "<" + // SQL_OP_LE represents <= operator + SQL_OP_LE = "<=" + // SQL_OP_GT represents > operator + SQL_OP_GT = ">" + // SQL_OP_GE represents >= operator + SQL_OP_GE = ">=" + // SQL_OP_BETWEEN represents BETWEEN operator + SQL_OP_BETWEEN = "BETWEEN" + // SQL_OP_NOTEQUAL represents NOT EQUAL operator SQL_OP_NOTEQUAL = "<>" ) const ( - TAG_IGNORE = "ignore" - TAG_NAME = "name" - TAG_WIDTH = "width" - TAG_TEXT_LENGTH = "length" - TAG_CHARSET = "charset" - TAG_PRECISION = "precision" - TAG_DEFAULT = "default" - TAG_UNIQUE = "unique" - TAG_INDEX = "index" - TAG_PRIMARY = "primary" - TAG_NULLABLE = "nullable" - TAG_AUTOINCREMENT = "auto_increment" - TAG_AUTOVERSION = "auto_version" + // TAG_IGNORE is a field tag that indicates the field is ignored, not represents a table column + TAG_IGNORE = "ignore" + // TAG_NAME is a field tag that indicates the column name of this field + TAG_NAME = "name" + // TAG_WIDTH is a field tag that indicates the width of the column, like VARCHAR(15) + TAG_WIDTH = "width" + // TAG_TEXT_LENGTH is a field tag that indicates the length of a text column + TAG_TEXT_LENGTH = "length" + // TAG_CHARSET is a field tag that indicates the charset of a text column + TAG_CHARSET = "charset" + // TAG_PRECISION is a field tag that indicates the precision of a float column + TAG_PRECISION = "precision" + // TAG_DEFAULT is a field tag that indicates the default value of a column + TAG_DEFAULT = "default" + // TAG_UNIQUE is a field tag that indicates the column value is unique + TAG_UNIQUE = "unique" + // TAG_INDEX is a field tag that indicates the column is a indexable column + TAG_INDEX = "index" + // TAG_PRIMARY is a field tag that indicates the column is part of primary key + TAG_PRIMARY = "primary" + // TAG_NULLABLE is a field tag that indicates the column is nullable + TAG_NULLABLE = "nullable" + // TAG_AUTOINCREMENT is a field tag that indicates the integer column is auto_increment, the column should must be primary + TAG_AUTOINCREMENT = "auto_increment" + // TAG_AUTOVERSION is a field tag that indicates the integer column is used to records the update version of a record + TAG_AUTOVERSION = "auto_version" + // TAG_UPDATE_TIMESTAMP is a field tag that indicates the datetime column is the updated_at timestamp TAG_UPDATE_TIMESTAMP = "updated_at" + // TAG_CREATE_TIMESTAMP is a field tag that indicates the datetime column is the created_at timestamp TAG_CREATE_TIMESTAMP = "created_at" - TAG_ALLOW_ZERO = "allow_zero" + // TAG_ALLOW_ZERO is a field tag that indicates whether the column allow zero value + TAG_ALLOW_ZERO = "allow_zero" ) var ( + // INT_WIDTH_DEFAULT records the default width of integer type INT_WIDTH_DEFAULT = map[string]int{ "TINYINT": 4, "SMALLINT": 6, "INT": 11, "BIGINT": 20, } + // UNSIGNED_INT_WIDTH_DEFAULT records the default width of unsigned integer type UNSIGNED_INT_WIDTH_DEFAULT = map[string]int{ "TINYINT": 3, "SMALLINT": 5, diff --git a/vendor/yunion.io/x/sqlchemy/constraint.go b/vendor/yunion.io/x/sqlchemy/constraint.go index 0041cf2efc..d0379a0deb 100644 --- a/vendor/yunion.io/x/sqlchemy/constraint.go +++ b/vendor/yunion.io/x/sqlchemy/constraint.go @@ -19,7 +19,7 @@ import ( "strings" ) -type STableConstraint struct { +type sTableConstraint struct { name string columns []string foreignTable string @@ -53,11 +53,11 @@ func fetchColumns(match string) []string { return ret } -func parseConstraints(defStr string) []STableConstraint { +func parseConstraints(defStr string) []sTableConstraint { matches := constraintRegexp.FindAllStringSubmatch(defStr, -1) - tcs := make([]STableConstraint, len(matches)) + tcs := make([]sTableConstraint, len(matches)) for i := range matches { - tcs[i] = STableConstraint{ + tcs[i] = sTableConstraint{ name: matches[i][1], foreignTable: matches[i][4], columns: fetchColumns(matches[i][2]), @@ -67,11 +67,11 @@ func parseConstraints(defStr string) []STableConstraint { return tcs } -func parseIndexes(defStr string) []STableIndex { +func parseIndexes(defStr string) []sTableIndex { matches := indexRegexp.FindAllStringSubmatch(defStr, -1) - tcs := make([]STableIndex, len(matches)) + tcs := make([]sTableIndex, len(matches)) for i := range matches { - tcs[i] = STableIndex{ + tcs[i] = sTableIndex{ name: matches[i][2], isUnique: len(matches[i][1]) > 0, columns: fetchColumns(matches[i][3]), diff --git a/vendor/yunion.io/x/sqlchemy/debug.go b/vendor/yunion.io/x/sqlchemy/debug.go index dee4307a0f..0ca6168d8e 100644 --- a/vendor/yunion.io/x/sqlchemy/debug.go +++ b/vendor/yunion.io/x/sqlchemy/debug.go @@ -15,33 +15,57 @@ package sqlchemy import ( + "fmt" + "strings" + "time" + "yunion.io/x/log" ) var ( + // DEBUG_SQLCHEMY is a global constant that indicates turn on SQL debug DEBUG_SQLCHEMY = false ) +func sqlDebug(sqlstr string, variables []interface{}) { + for _, v := range variables { + switch v.(type) { + case bool, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64: + sqlstr = strings.Replace(sqlstr, "?", fmt.Sprintf(`%v`, v), 1) + case string, time.Time: + sqlstr = strings.Replace(sqlstr, "?", fmt.Sprintf(`"%s"`, v), 1) + default: + sqlstr = strings.Replace(sqlstr, "?", fmt.Sprintf(`"%v"`, v), 1) + } + } + log.Debugln("SQuery ", sqlstr) +} + +// DebugQuery show the full query string for debug func (tq *SQuery) DebugQuery() { sqlstr := tq.String() vars := tq.Variables() - log.Debugf("SQuery %s with vars: %s", sqlstr, vars) + sqlDebug(sqlstr, vars) } +// DebugQuery show the full query string for a subquery for debug func (sqf *SSubQuery) DebugQuery() { sqlstr := sqf.Expression() vars := sqf.query.Variables() - log.Debugf("SQuery %s with vars: %s", sqlstr, vars) + sqlDebug(sqlstr, vars) } +// DebugInsert does insert with debug mode on func (t *STableSpec) DebugInsert(dt interface{}) error { return t.insert(dt, false, true) } +// DebugInsertOrUpdate does insertOrUpdate with debug mode on func (t *STableSpec) DebugInsertOrUpdate(dt interface{}) error { return t.insert(dt, true, true) } -func (ts *STableSpec) DebugUpdateFields(dt interface{}, fields map[string]interface{}) error { - return ts.updateFields(dt, fields, true) +// DebugUpdateFields does update with debug mode on +func (t *STableSpec) DebugUpdateFields(dt interface{}, fields map[string]interface{}) error { + return t.updateFields(dt, fields, true) } diff --git a/vendor/yunion.io/x/sqlchemy/errors.go b/vendor/yunion.io/x/sqlchemy/errors.go index f323edc22e..9aebf37494 100644 --- a/vendor/yunion.io/x/sqlchemy/errors.go +++ b/vendor/yunion.io/x/sqlchemy/errors.go @@ -21,19 +21,38 @@ import ( ) const ( - ErrNoDataToUpdate = errors.Error("No data to update") - ErrDuplicateEntry = errors.Error("duplicate entry") - ErrEmptyQuery = errors.Error("empty query") - ErrEmptyPrimaryKey = errors.Error("empty primary keys") + // ErrNoDataToUpdate is an Error constant: no data to update + ErrNoDataToUpdate = errors.Error("No data to update") + + // ErrDuplicateEntry is an Error constant: duplicate entry + ErrDuplicateEntry = errors.Error("duplicate entry") + + // ErrEmptyQuery is an Error constant: empty query + ErrEmptyQuery = errors.Error("empty query") + + // ErrEmptyPrimaryKey is an Error constant: no primary key + ErrEmptyPrimaryKey = errors.Error("empty primary keys") + + // ErrUnexpectRowCount is an Error constant: the number of rows impacted by modification unexpected ErrUnexpectRowCount = errors.Error("unexpected row count") + // ErrNeedsPointer is an Error constant: input should be a pointer ErrNeedsPointer = errors.Error("input needs pointer input") - ErrNeedsArray = errors.Error("input needs slice or array") - ErrReadOnly = errors.Error("read only input") + // ErrNeedsArray is an Error constant: input should be an Array or Slice + ErrNeedsArray = errors.Error("input needs slice or array") + + // ErrReadOnly is an Error constant: database is read-only + ErrReadOnly = errors.Error("read only input") + + // ErrNotSupported is an Error constant: method not supported yet ErrNotSupported = errors.ErrNotSupported + // ErrTableNotExists is an Error constant: table not exists ErrTableNotExists = errors.Error("TableNotExists") + + // ErrUnionFieldsNotMatch is an Error constant: fields of union queries not match + ErrUnionFieldsNotMatch = errors.Error("cannot union, name of fields not match") ) const ( diff --git a/vendor/yunion.io/x/sqlchemy/fetch.go b/vendor/yunion.io/x/sqlchemy/fetch.go index 06fec547a5..4088b5bb89 100644 --- a/vendor/yunion.io/x/sqlchemy/fetch.go +++ b/vendor/yunion.io/x/sqlchemy/fetch.go @@ -24,7 +24,7 @@ import ( "yunion.io/x/pkg/util/reflectutils" ) -// fetch the values of a struct whose primary key values have been set +// Fetch method fetches the values of a struct whose primary key values have been set // input is a pointer to the model to be populated func (ts *STableSpec) Fetch(dt interface{}) error { q := ts.Query() @@ -39,7 +39,7 @@ func (ts *STableSpec) Fetch(dt interface{}) error { return q.First(dt) } -// fetch the values of an array of structs whose primary key values have been set +// FetchAll method fetches the values of an array of structs whose primary key values have been set // input is a pointer to the array of models to be populated func (ts *STableSpec) FetchAll(dest interface{}) error { arrayType := reflect.TypeOf(dest).Elem() @@ -56,7 +56,7 @@ func (ts *STableSpec) FetchAll(dest interface{}) error { primaryCol := primaryCols[0] keyValues := make([]interface{}, arrayValue.Len()) - for i := 0; i < arrayValue.Len(); i += 1 { + for i := 0; i < arrayValue.Len(); i++ { eleValue := arrayValue.Index(i) fields := reflectutils.FetchStructFieldValueSet(eleValue) keyValues[i], _ = fields.GetInterface(primaryCol.Name()) @@ -69,11 +69,11 @@ func (ts *STableSpec) FetchAll(dest interface{}) error { } tmpDestMapMap := make(map[string]map[string]string) - for i := 0; i < len(tmpDestMaps); i += 1 { + for i := 0; i < len(tmpDestMaps); i++ { tmpDestMapMap[tmpDestMaps[i][primaryCol.Name()]] = tmpDestMaps[i] } - for i := 0; i < arrayValue.Len(); i += 1 { + for i := 0; i < arrayValue.Len(); i++ { keyValueStr := getStringValue(keyValues[i]) if tmpMap, ok := tmpDestMapMap[keyValueStr]; ok { err = mapString2Struct(tmpMap, arrayValue.Index(i)) diff --git a/vendor/yunion.io/x/sqlchemy/field_update.go b/vendor/yunion.io/x/sqlchemy/field_update.go index 342f84a53d..2633405b2b 100644 --- a/vendor/yunion.io/x/sqlchemy/field_update.go +++ b/vendor/yunion.io/x/sqlchemy/field_update.go @@ -51,6 +51,8 @@ func (ts *STableSpec) GetUpdateColumnValue(dataType reflect.Type, dataValue refl } */ +// UpdateFields update a record with the values provided by fields stringmap +// params dt: model struct, fileds: {struct-field-name-string: update-value} func (ts *STableSpec) UpdateFields(dt interface{}, fields map[string]interface{}) error { return ts.updateFields(dt, fields, false) } diff --git a/vendor/yunion.io/x/sqlchemy/filter.go b/vendor/yunion.io/x/sqlchemy/filter.go index b8c329d4e4..facd454812 100644 --- a/vendor/yunion.io/x/sqlchemy/filter.go +++ b/vendor/yunion.io/x/sqlchemy/filter.go @@ -14,6 +14,8 @@ package sqlchemy +// Filter method filters a SQL query with given ICondition +// equivalent to add a clause in where conditions func (tq *SQuery) Filter(cond ICondition) *SQuery { if tq.groupBy != nil && len(tq.groupBy) > 0 { if tq.having == nil { @@ -31,120 +33,144 @@ func (tq *SQuery) Filter(cond ICondition) *SQuery { return tq } +// FilterByTrue filters query with a true condition func (tq *SQuery) FilterByTrue() *SQuery { return tq.Filter(&STrueCondition{}) } +// FilterByFalse filters query with a false condition func (tq *SQuery) FilterByFalse() *SQuery { return tq.Filter(&SFalseCondition{}) } -func (q *SQuery) Like(f string, v string) *SQuery { - cond := Like(q.Field(f), v) - return q.Filter(cond) +// Like filters query with a like condition +func (tq *SQuery) Like(f string, v string) *SQuery { + cond := Like(tq.Field(f), v) + return tq.Filter(cond) } -func (q *SQuery) Contains(f string, v string) *SQuery { - cond := Contains(q.Field(f), v) - return q.Filter(cond) +// Contains filters query with a contains condition +func (tq *SQuery) Contains(f string, v string) *SQuery { + cond := Contains(tq.Field(f), v) + return tq.Filter(cond) } -func (q *SQuery) Startswith(f string, v string) *SQuery { - cond := Startswith(q.Field(f), v) - return q.Filter(cond) +// Startswith filters query with a startswith condition +func (tq *SQuery) Startswith(f string, v string) *SQuery { + cond := Startswith(tq.Field(f), v) + return tq.Filter(cond) } -func (q *SQuery) Endswith(f string, v string) *SQuery { - cond := Endswith(q.Field(f), v) - return q.Filter(cond) +// Endswith filters query with a endswith condition +func (tq *SQuery) Endswith(f string, v string) *SQuery { + cond := Endswith(tq.Field(f), v) + return tq.Filter(cond) } -func (q *SQuery) NotLike(f string, v string) *SQuery { - cond := Like(q.Field(f), v) - return q.Filter(NOT(cond)) +// NotLike filters query with a not like condition +func (tq *SQuery) NotLike(f string, v string) *SQuery { + cond := Like(tq.Field(f), v) + return tq.Filter(NOT(cond)) } -func (q *SQuery) In(f string, v interface{}) *SQuery { - cond := In(q.Field(f), v) - return q.Filter(cond) +// In filters query with a in condition +func (tq *SQuery) In(f string, v interface{}) *SQuery { + cond := In(tq.Field(f), v) + return tq.Filter(cond) } -func (q *SQuery) NotIn(f string, v interface{}) *SQuery { - cond := In(q.Field(f), v) - return q.Filter(NOT(cond)) +// NotIn filters query with a not in condition +func (tq *SQuery) NotIn(f string, v interface{}) *SQuery { + cond := In(tq.Field(f), v) + return tq.Filter(NOT(cond)) } -func (q *SQuery) Between(f string, v1, v2 interface{}) *SQuery { - cond := Between(q.Field(f), v1, v2) - return q.Filter(cond) +// Between filters query with a between condition +func (tq *SQuery) Between(f string, v1, v2 interface{}) *SQuery { + cond := Between(tq.Field(f), v1, v2) + return tq.Filter(cond) } -func (q *SQuery) NotBetween(f string, v1, v2 interface{}) *SQuery { - cond := Between(q.Field(f), v1, v2) - return q.Filter(NOT(cond)) +// NotBetween filters query with a not between condition +func (tq *SQuery) NotBetween(f string, v1, v2 interface{}) *SQuery { + cond := Between(tq.Field(f), v1, v2) + return tq.Filter(NOT(cond)) } -func (q *SQuery) Equals(f string, v interface{}) *SQuery { - cond := Equals(q.Field(f), v) - return q.Filter(cond) +// Equals filters query with a equals condition +func (tq *SQuery) Equals(f string, v interface{}) *SQuery { + cond := Equals(tq.Field(f), v) + return tq.Filter(cond) } -func (q *SQuery) NotEquals(f string, v interface{}) *SQuery { - cond := NotEquals(q.Field(f), v) - return q.Filter(cond) +// NotEquals filters the query with a not equals condition +func (tq *SQuery) NotEquals(f string, v interface{}) *SQuery { + cond := NotEquals(tq.Field(f), v) + return tq.Filter(cond) } -func (q *SQuery) GE(f string, v interface{}) *SQuery { - cond := GE(q.Field(f), v) - return q.Filter(cond) +// GE filters the query with a >= condition +func (tq *SQuery) GE(f string, v interface{}) *SQuery { + cond := GE(tq.Field(f), v) + return tq.Filter(cond) } -func (q *SQuery) LE(f string, v interface{}) *SQuery { - cond := LE(q.Field(f), v) - return q.Filter(cond) +// LE filters the query with a <= condition +func (tq *SQuery) LE(f string, v interface{}) *SQuery { + cond := LE(tq.Field(f), v) + return tq.Filter(cond) } -func (q *SQuery) GT(f string, v interface{}) *SQuery { - cond := GT(q.Field(f), v) - return q.Filter(cond) +// GT filters the query with a > condition +func (tq *SQuery) GT(f string, v interface{}) *SQuery { + cond := GT(tq.Field(f), v) + return tq.Filter(cond) } -func (q *SQuery) LT(f string, v interface{}) *SQuery { - cond := LT(q.Field(f), v) - return q.Filter(cond) +// LT filters the query with a < condition +func (tq *SQuery) LT(f string, v interface{}) *SQuery { + cond := LT(tq.Field(f), v) + return tq.Filter(cond) } -func (q *SQuery) IsNull(f string) *SQuery { - cond := IsNull(q.Field(f)) - return q.Filter(cond) +// IsNull filters the query with a is null condition +func (tq *SQuery) IsNull(f string) *SQuery { + cond := IsNull(tq.Field(f)) + return tq.Filter(cond) } -func (q *SQuery) IsNotNull(f string) *SQuery { - cond := IsNotNull(q.Field(f)) - return q.Filter(cond) +// IsNotNull filters the query with a is not null condition +func (tq *SQuery) IsNotNull(f string) *SQuery { + cond := IsNotNull(tq.Field(f)) + return tq.Filter(cond) } -func (q *SQuery) IsEmpty(f string) *SQuery { - cond := IsEmpty(q.Field(f)) - return q.Filter(cond) +// IsEmpty filters the query with a is_empty condition +func (tq *SQuery) IsEmpty(f string) *SQuery { + cond := IsEmpty(tq.Field(f)) + return tq.Filter(cond) } -func (q *SQuery) IsNullOrEmpty(f string) *SQuery { - cond := IsNullOrEmpty(q.Field(f)) - return q.Filter(cond) +// IsNullOrEmpty filters the query with a is null or empty condition +func (tq *SQuery) IsNullOrEmpty(f string) *SQuery { + cond := IsNullOrEmpty(tq.Field(f)) + return tq.Filter(cond) } -func (q *SQuery) IsNotEmpty(f string) *SQuery { - cond := IsNotEmpty(q.Field(f)) - return q.Filter(cond) +// IsNotEmpty filters the query with a is not empty condition +func (tq *SQuery) IsNotEmpty(f string) *SQuery { + cond := IsNotEmpty(tq.Field(f)) + return tq.Filter(cond) } -func (q *SQuery) IsTrue(f string) *SQuery { - cond := IsTrue(q.Field(f)) - return q.Filter(cond) +// IsTrue filters the query with a is true condition +func (tq *SQuery) IsTrue(f string) *SQuery { + cond := IsTrue(tq.Field(f)) + return tq.Filter(cond) } -func (q *SQuery) IsFalse(f string) *SQuery { - cond := IsFalse(q.Field(f)) - return q.Filter(cond) +// IsFalse filters the query with a is false condition +func (tq *SQuery) IsFalse(f string) *SQuery { + cond := IsFalse(tq.Field(f)) + return tq.Filter(cond) } diff --git a/vendor/yunion.io/x/sqlchemy/functions.go b/vendor/yunion.io/x/sqlchemy/functions.go index e33dc90a10..d2b8e4ebef 100644 --- a/vendor/yunion.io/x/sqlchemy/functions.go +++ b/vendor/yunion.io/x/sqlchemy/functions.go @@ -22,43 +22,46 @@ import ( "yunion.io/x/log" ) +// IFunction is the interface for a SQL embedded function, such as MIN, MAX, NOW, etc. type IFunction interface { expression() string variables() []interface{} } +// SFunctionFieldBase is a query field that is the result of a SQL embedded function, e.g. COUNT(*) as count type SFunctionFieldBase struct { IFunction alias string } +// Reference implementation of SFunctionFieldBase for IQueryField func (ff *SFunctionFieldBase) Reference() string { if len(ff.alias) == 0 { log.Warningf("reference a function field without alias! %s", ff.expression()) return ff.expression() - } else { - return fmt.Sprintf("`%s`", ff.alias) } + return fmt.Sprintf("`%s`", ff.alias) } +// Expression implementation of SFunctionFieldBase for IQueryField func (ff *SFunctionFieldBase) Expression() string { if len(ff.alias) > 0 { // add alias return fmt.Sprintf("%s AS `%s`", ff.expression(), ff.alias) - } else { - // no alias - return ff.expression() } + // no alias + return ff.expression() } +// Name implementation of SFunctionFieldBase for IQueryField func (ff *SFunctionFieldBase) Name() string { if len(ff.alias) > 0 { return ff.alias - } else { - return ff.expression() } + return ff.expression() } +// Label implementation of SFunctionFieldBase for IQueryField func (ff *SFunctionFieldBase) Label(label string) IQueryField { if len(label) > 0 && label != ff.alias { ff.alias = label @@ -66,16 +69,17 @@ func (ff *SFunctionFieldBase) Label(label string) IQueryField { return ff } +// Variables implementation of SFunctionFieldBase for IQueryField func (ff *SFunctionFieldBase) Variables() []interface{} { return ff.variables() } -type SExprFunction struct { +type sExprFunction struct { fields []IQueryField function string } -func (ff *SExprFunction) expression() string { +func (ff *sExprFunction) expression() string { fieldRefs := make([]interface{}, 0) for _, f := range ff.fields { fieldRefs = append(fieldRefs, f.Reference()) @@ -83,7 +87,7 @@ func (ff *SExprFunction) expression() string { return fmt.Sprintf(ff.function, fieldRefs...) } -func (ff *SExprFunction) variables() []interface{} { +func (ff *sExprFunction) variables() []interface{} { vars := make([]interface{}, 0) for _, f := range ff.fields { fromVars := f.Variables() @@ -92,8 +96,9 @@ func (ff *SExprFunction) variables() []interface{} { return vars } +// NewFunctionField returns an instance of query field by calling a SQL embedded function func NewFunctionField(name string, funcexp string, fields ...IQueryField) IQueryField { - funcBase := &SExprFunction{ + funcBase := &sExprFunction{ fields: fields, function: funcexp, } @@ -103,6 +108,7 @@ func NewFunctionField(name string, funcexp string, fields ...IQueryField) IQuery } } +// COUNT represents the SQL function COUNT func COUNT(name string, field ...IQueryField) IQueryField { var expr string if len(field) == 0 { @@ -113,47 +119,58 @@ func COUNT(name string, field ...IQueryField) IQueryField { return NewFunctionField(name, expr, field...) } +// MAX represents the SQL function MAX func MAX(name string, field IQueryField) IQueryField { return NewFunctionField(name, "MAX(%s)", field) } +// MIN represents the SQL function MIN func MIN(name string, field IQueryField) IQueryField { return NewFunctionField(name, "MIN(%s)", field) } +// SUM represents the SQL function SUM func SUM(name string, field IQueryField) IQueryField { return NewFunctionField(name, "SUM(%s)", field) } +// DISTINCT represents the SQL function DISTINCT func DISTINCT(name string, field IQueryField) IQueryField { return NewFunctionField(name, "DISTINCT(%s)", field) } +// GROUP_CONCAT represents the SQL function GROUP_CONCAT func GROUP_CONCAT(name string, field IQueryField) IQueryField { return NewFunctionField(name, "GROUP_CONCAT(%s)", field) } +// REPLACE represents the SQL function REPLACE func REPLACE(name string, field IQueryField, old string, new string) IQueryField { return NewFunctionField(name, fmt.Sprintf(`REPLACE(%s, "%s", "%s")`, "%s", old, new), field) } +// SConstField is a query field of a constant type SConstField struct { constVar interface{} alias string } +// Expression implementation of SConstField for IQueryField func (s *SConstField) Expression() string { return fmt.Sprintf("%s AS `%s`", s.Reference(), s.Name()) } +// Name implementation of SConstField for IQueryField func (s *SConstField) Name() string { return s.alias } +// Reference implementation of SConstField for IQueryField func (s *SConstField) Reference() string { return getQuoteStringValue(s.constVar) } +// Label implementation of SConstField for IQueryField func (s *SConstField) Label(label string) IQueryField { if len(label) > 0 { s.alias = label @@ -161,31 +178,38 @@ func (s *SConstField) Label(label string) IQueryField { return s } +// Variables implementation of SConstField for IQueryField func (s *SConstField) Variables() []interface{} { return nil } +// NewConstField returns an instance of SConstField func NewConstField(variable interface{}) *SConstField { return &SConstField{constVar: variable} } +// SStringField is a query field of a string constant type SStringField struct { strConst string alias string } +// Expression implementation of SStringField for IQueryField func (s *SStringField) Expression() string { return fmt.Sprintf("%s AS `%s`", s.Reference(), s.Name()) } +// Name implementation of SStringField for IQueryField func (s *SStringField) Name() string { return s.alias } +// Reference implementation of SStringField for IQueryField func (s *SStringField) Reference() string { return strconv.Quote(s.strConst) } +// Label implementation of SStringField for IQueryField func (s *SStringField) Label(label string) IQueryField { if len(label) > 0 { s.alias = label @@ -193,14 +217,17 @@ func (s *SStringField) Label(label string) IQueryField { return s } +// Variables implementation of SStringField for IQueryField func (s *SStringField) Variables() []interface{} { return nil } +// NewStringField returns an instance of SStringField func NewStringField(name string) *SStringField { return &SStringField{strConst: name} } +// CONCAT represents a SQL function CONCAT func CONCAT(name string, fields ...IQueryField) IQueryField { params := []string{} for i := 0; i < len(fields); i++ { @@ -209,6 +236,7 @@ func CONCAT(name string, fields ...IQueryField) IQueryField { return NewFunctionField(name, `CONCAT(`+strings.Join(params, ",")+`)`, fields...) } +// SubStr represents a SQL function SUBSTR func SubStr(name string, field IQueryField, pos, length int) IQueryField { var rightStr string if length <= 0 { @@ -219,20 +247,24 @@ func SubStr(name string, field IQueryField, pos, length int) IQueryField { return NewFunctionField(name, `SUBSTR(%s, `+rightStr, field) } +// OR_Val represents a SQL function that does binary | operation on a field func OR_Val(name string, field IQueryField, v interface{}) IQueryField { rightStr := fmt.Sprintf("|%v", v) return NewFunctionField(name, "%s"+rightStr, field) } +// AND_Val represents a SQL function that does binary & operation on a field func AND_Val(name string, field IQueryField, v interface{}) IQueryField { rightStr := fmt.Sprintf("&%v", v) return NewFunctionField(name, "%s"+rightStr, field) } +// INET_ATON represents a SQL function INET_ATON func INET_ATON(field IQueryField) IQueryField { return NewFunctionField("", `INET_ATON(%s)`, field) } +// TimestampAdd represents a SQL function TimestampAdd func TimestampAdd(name string, field IQueryField, offsetSeconds int) IQueryField { return NewFunctionField(name, `TIMESTAMPADD(SECOND, `+fmt.Sprintf("%d", offsetSeconds)+`, %s)`, field) } diff --git a/vendor/yunion.io/x/sqlchemy/inc.go b/vendor/yunion.io/x/sqlchemy/inc.go index 63a51a834a..399db674d8 100644 --- a/vendor/yunion.io/x/sqlchemy/inc.go +++ b/vendor/yunion.io/x/sqlchemy/inc.go @@ -26,10 +26,16 @@ import ( "yunion.io/x/pkg/util/reflectutils" ) +// Increment perform an incremental update on a record, the primary key of the record is specified in diff, +// the numeric fields of this record will be atomically added by the value of the corresponding field in diff +// if target is given as a pointer to a variable, the result will be stored in the target +// if target is not given, the updated result will be stored in diff func (t *STableSpec) Increment(diff interface{}, target interface{}) error { return t.incrementInternal(diff, "+", target) } +// Decrement is similar to Increment methods, the difference is that this method will atomically decrease the numeric fields +// with the value of diff func (t *STableSpec) Decrement(diff interface{}, target interface{}) error { return t.incrementInternal(diff, "-", target) } @@ -144,9 +150,8 @@ func (t *STableSpec) incrementInternal(diff interface{}, opcode string, target i if aCnt != 1 { if aCnt == 0 { return sql.ErrNoRows - } else { - return errors.Wrapf(ErrUnexpectRowCount, "affected rows %d != 1", aCnt) } + return errors.Wrapf(ErrUnexpectRowCount, "affected rows %d != 1", aCnt) } q := t.Query() for k, v := range primaries { diff --git a/vendor/yunion.io/x/sqlchemy/index.go b/vendor/yunion.io/x/sqlchemy/index.go index 5d29543be0..ee30008fd9 100644 --- a/vendor/yunion.io/x/sqlchemy/index.go +++ b/vendor/yunion.io/x/sqlchemy/index.go @@ -19,13 +19,13 @@ import ( "strings" ) -type STableIndex struct { +type sTableIndex struct { name string columns []string isUnique bool } -type TColumnNames []string +/*type TColumnNames []string func (cols TColumnNames) Len() int { return len(cols) @@ -41,13 +41,13 @@ func (cols TColumnNames) Less(i, j int) bool { } else { return false } -} +}*/ -func (index *STableIndex) IsIdentical(cols ...string) bool { +func (index *sTableIndex) IsIdentical(cols ...string) bool { if len(index.columns) != len(cols) { return false } - for i := 0; i < len(index.columns); i += 1 { + for i := 0; i < len(index.columns); i++ { if index.columns[i] != cols[i] { return false } @@ -55,22 +55,24 @@ func (index *STableIndex) IsIdentical(cols ...string) bool { return true } -func (index *STableIndex) QuotedColumns() []string { +func (index *sTableIndex) QuotedColumns() []string { ret := make([]string, len(index.columns)) - for i := 0; i < len(ret); i += 1 { + for i := 0; i < len(ret); i++ { ret[i] = fmt.Sprintf("`%s`", index.columns[i]) } return ret } +// AddIndex adds a SQL index over multiple columns for a Table +// param unique: indicates a unique index cols: name of columns func (ts *STableSpec) AddIndex(unique bool, cols ...string) bool { - for i := 0; i < len(ts.indexes); i += 1 { + for i := 0; i < len(ts.indexes); i++ { if ts.indexes[i].IsIdentical(cols...) { return false } } name := fmt.Sprintf("ix_%s_%s", ts.name, strings.Join(cols, "_")) - idx := STableIndex{name: name, columns: cols, isUnique: unique} + idx := sTableIndex{name: name, columns: cols, isUnique: unique} ts.indexes = append(ts.indexes, idx) return true } diff --git a/vendor/yunion.io/x/sqlchemy/insert.go b/vendor/yunion.io/x/sqlchemy/insert.go index ced9278cfa..95eb1207ca 100644 --- a/vendor/yunion.io/x/sqlchemy/insert.go +++ b/vendor/yunion.io/x/sqlchemy/insert.go @@ -25,11 +25,12 @@ import ( "yunion.io/x/pkg/util/reflectutils" ) +// Insert perform a insert operation, the value of the record is store in dt func (t *STableSpec) Insert(dt interface{}) error { return t.insert(dt, false, false) } -// +// InsertOrUpdate perform a insert or update operation, the value of the record is string in dt // MySQL: INSERT INTO ... ON DUPLICATE KEY UPDATE ... // works only for the cases that all values of primary keys are determeted before insert func (t *STableSpec) InsertOrUpdate(dt interface{}) error { @@ -148,11 +149,28 @@ func (t *STableSpec) insertSqlPrep(dataFields reflectutils.SStructFieldValueSet, return insertSql, values, nil } -func (t *STableSpec) insert(data interface{}, update bool, debug bool) error { - beforeInsertFunc := reflect.ValueOf(data).MethodByName("BeforeInsert") - if beforeInsertFunc.IsValid() && !beforeInsertFunc.IsNil() { - beforeInsertFunc.Call([]reflect.Value{}) +func beforeInsert(val reflect.Value) { + switch val.Kind() { + case reflect.Struct: + structType := val.Type() + for i := 0; i < val.NumField(); i++ { + fieldType := structType.Field(i) + if fieldType.Anonymous { + beforeInsert(val.Field(i)) + } + } + valPtr := val.Addr() + afterMarshalFunc := valPtr.MethodByName("BeforeInsert") + if afterMarshalFunc.IsValid() && !afterMarshalFunc.IsNil() { + afterMarshalFunc.Call([]reflect.Value{}) + } + case reflect.Ptr: + beforeInsert(val.Elem()) } +} + +func (t *STableSpec) insert(data interface{}, update bool, debug bool) error { + beforeInsert(reflect.ValueOf(data)) dataValue := reflect.ValueOf(data).Elem() dataFields := reflectutils.FetchStructFieldValueSet(dataValue) @@ -205,9 +223,8 @@ func (t *STableSpec) insert(data interface{}, update bool, debug bool) error { lastId, err := results.LastInsertId() if err != nil { return errors.Wrap(err, "fetching lastInsertId failed") - } else { - q = q.Equals(c.Name(), lastId) } + q = q.Equals(c.Name(), lastId) } else { priVal, _ := dataFields.GetInterface(c.Name()) if !gotypes.IsNil(priVal) { diff --git a/vendor/yunion.io/x/sqlchemy/parser.go b/vendor/yunion.io/x/sqlchemy/parser.go index 0f37d7967a..f02284ebe2 100644 --- a/vendor/yunion.io/x/sqlchemy/parser.go +++ b/vendor/yunion.io/x/sqlchemy/parser.go @@ -35,7 +35,7 @@ func structField2ColumnSpec(field *reflectutils.SStructFieldValue) IColumnSpec { retCol = getFiledTypeCol(fieldType.Elem(), fieldname, tagmap, true) } if retCol == nil { - panic("unsupported colume data type %s" + fieldType.Name()) + panic(fmt.Sprintf("unsupported colume %s data type %s", fieldname, fieldType.Name())) } return retCol } @@ -94,14 +94,13 @@ func getFiledTypeCol(fieldType reflect.Type, fieldname string, tagmap map[string if _, ok := tagmap[TAG_WIDTH]; ok { col := NewDecimalColumn(fieldname, tagmap, isPointer) return &col - } else { - colType := "FLOAT" - if fieldType == gotypes.Float64Type { - colType = "DOUBLE" - } - col := NewFloatColumn(fieldname, colType, tagmap, isPointer) - return &col } + colType := "FLOAT" + if fieldType == gotypes.Float64Type { + colType = "DOUBLE" + } + col := NewFloatColumn(fieldname, colType, tagmap, isPointer) + return &col } if fieldType.Implements(gotypes.ISerializableType) { col := NewCompoundColumn(fieldname, tagmap, isPointer) @@ -113,11 +112,11 @@ func getFiledTypeCol(fieldType reflect.Type, fieldname string, tagmap map[string func struct2TableSpec(sv reflect.Value, table *STableSpec) { fields := reflectutils.FetchStructFieldValueSet(sv) autoIncCnt := 0 - for i := 0; i < len(fields); i += 1 { + for i := 0; i < len(fields); i++ { column := structField2ColumnSpec(&fields[i]) if column != nil { if intC, ok := column.(*SIntegerColumn); ok && intC.IsAutoIncrement { - autoIncCnt += 1 + autoIncCnt++ if autoIncCnt > 1 { panic(fmt.Sprintf("Table %s contains multiple autoincremental columns!!", table.name)) } diff --git a/vendor/yunion.io/x/sqlchemy/query.go b/vendor/yunion.io/x/sqlchemy/query.go index d725f8f7fa..460fa1f03f 100644 --- a/vendor/yunion.io/x/sqlchemy/query.go +++ b/vendor/yunion.io/x/sqlchemy/query.go @@ -27,81 +27,111 @@ import ( "yunion.io/x/pkg/util/reflectutils" ) +// IQuery is an interface that reprsents a SQL query, e.g. +// SELECT ... FROM ... WHERE ... type IQuery interface { // queryString String(fields ...IQueryField) string - // fields after select + + // fields in the select clause QueryFields() []IQueryField + // variables in statement Variables() []interface{} - // convert to a subquery + + // convert this SQL to a subquery SubQuery() *SSubQuery + // reference to a field by name Field(name string) IQueryField } +// IQuerySource is an interface that represents a data source of a SQL query. the source can be a table or a subquery +// e.g. SELECT ... FROM (SELECT * FROM tbl) AS A type IQuerySource interface { // string in select ... from (expresson here) Expression() string + // alias in select ... from (express) as alias Alias() string + // variables in statement Variables() []interface{} + // reference to a field by name, optionally giving an alias name Field(id string, alias ...string) IQueryField + // return all the fields that this source provides Fields() []IQueryField } +// IQueryField is an interface that represents a select field in a SQL query type IQueryField interface { // the string after select Expression() string + // the name of thie field Name() string - // the string in where clause + + // the reference string in where clause Reference() string + // give this field an alias name Label(label string) IQueryField + // return variables Variables() []interface{} } +// Expression implementation of STable for IQuerySource func (tbl *STable) Expression() string { return tbl.spec.Expression() } +// Alias implementation of STable for IQuerySource func (tbl *STable) Alias() string { return tbl.alias } +// Variables implementation of STable for IQuerySource func (tbl *STable) Variables() []interface{} { return []interface{}{} } +// QueryJoinType is the Join type of SQL query, namely, innerjoin, leftjoin and rightjoin type QueryJoinType string const ( + // INNERJOIN represents innerjoin INNERJOIN QueryJoinType = "JOIN" - LEFTJOIN QueryJoinType = "LEFT JOIN" + + // LEFTJOIN represents left join + LEFTJOIN QueryJoinType = "LEFT JOIN" + + // RIGHTJOIN represents right-join RIGHTJOIN QueryJoinType = "RIGHT JOIN" + // FULLJOIN QueryJoinType = "FULLJOIN" ) -type SQueryJoin struct { +// sQueryJoin represents the state of a Join Query +type sQueryJoin struct { jointype QueryJoinType from IQuerySource condition ICondition } +// SQuery is a data structure represents a SQL query in the form of +// SELECT ... FROM ... JOIN ... ON ... WHERE ... GROUP BY ... ORDER BY ... HAVING ... type SQuery struct { rawSql string fields []IQueryField distinct bool from IQuerySource - joins []SQueryJoin + joins []sQueryJoin where ICondition groupBy []IQueryField - orderBy []SQueryOrder + orderBy []sQueryOrder having ICondition limit int offset int @@ -111,6 +141,9 @@ type SQuery struct { snapshot string } +// SSubQuery represents a subquery. A subquery is a query used as a query source +// SSubQuery should implementation IQuerySource +// At the same time, a subquery can be used in condition. e.g. IN condition type SSubQuery struct { query IQuery alias string @@ -118,32 +151,35 @@ type SSubQuery struct { referedFields map[string]IQueryField } +// SSubQueryField represents a field of subquery, which implements IQueryField type SSubQueryField struct { field IQueryField query *SSubQuery alias string } +// Expression implementation of SSubQueryField for IQueryField func (sqf *SSubQueryField) Expression() string { if len(sqf.alias) > 0 { return fmt.Sprintf("`%s`.`%s` AS `%s`", sqf.query.alias, sqf.field.Name(), sqf.alias) - } else { - return fmt.Sprintf("`%s`.`%s`", sqf.query.alias, sqf.field.Name()) } + return fmt.Sprintf("`%s`.`%s`", sqf.query.alias, sqf.field.Name()) } +// Name implementation of SSubQueryField for IQueryField func (sqf *SSubQueryField) Name() string { if len(sqf.alias) > 0 { return sqf.alias - } else { - return sqf.field.Name() } + return sqf.field.Name() } +// Reference implementation of SSubQueryField for IQueryField func (sqf *SSubQueryField) Reference() string { return fmt.Sprintf("`%s`.`%s`", sqf.query.alias, sqf.Name()) } +// Label implementation of SSubQueryField for IQueryField func (sqf *SSubQueryField) Label(label string) IQueryField { if len(label) > 0 && label != sqf.field.Name() { sqf.alias = label @@ -151,10 +187,12 @@ func (sqf *SSubQueryField) Label(label string) IQueryField { return sqf } +// Variables implementation of SSubQueryField for IQueryField func (sqf *SSubQueryField) Variables() []interface{} { return nil } +// Expression implementation of SSubQuery for IQuerySource func (sq *SSubQuery) Expression() string { fields := make([]IQueryField, 0) for k := range sq.referedFields { @@ -167,10 +205,12 @@ func (sq *SSubQuery) Expression() string { return fmt.Sprintf("(%s)", sq.query.String(fields...)) } +// Alias implementation of SSubQuery for IQuerySource func (sq *SSubQuery) Alias() string { return sq.alias } +// Variables implementation of SSubQuery for IQuerySource func (sq *SSubQuery) Variables() []interface{} { return sq.query.Variables() } @@ -192,6 +232,7 @@ func (sq *SSubQuery) findField(id string) IQueryField { return nil } +// Field implementation of SSubQuery for IQuerySource func (sq *SSubQuery) Field(id string, alias ...string) IQueryField { f := sq.findField(id) if f == nil { @@ -204,6 +245,7 @@ func (sq *SSubQuery) Field(id string, alias ...string) IQueryField { return &sqf } +// Fields implementation of SSubQuery for IQuerySource func (sq *SSubQuery) Fields() []IQueryField { ret := make([]IQueryField, 0) for _, f := range sq.query.QueryFields() { @@ -213,6 +255,7 @@ func (sq *SSubQuery) Fields() []IQueryField { return ret } +// DoQuery returns a SQuery instance that query specified fields from a query source func DoQuery(from IQuerySource, f ...IQueryField) *SQuery { // if len(f) == 0 { // f = from.Fields() @@ -221,57 +264,68 @@ func DoQuery(from IQuerySource, f ...IQueryField) *SQuery { return &tq } -func (q *SQuery) AppendField(f ...IQueryField) *SQuery { - q.fields = append(q.fields, f...) - return q +// AppendField appends query field to a query +func (tq *SQuery) AppendField(f ...IQueryField) *SQuery { + tq.fields = append(tq.fields, f...) + return tq } -func (table *SSubQuery) Query(f ...IQueryField) *SQuery { - return DoQuery(table, f...) +// Query of SSubQuery generates a new query from a subquery +func (sq *SSubQuery) Query(f ...IQueryField) *SQuery { + return DoQuery(sq, f...) } +// Query of STable generates a new query from a table func (tbl *STable) Query(f ...IQueryField) *SQuery { return DoQuery(tbl, f...) } +// Query of STableSpec generates a new query from a STableSpec instance func (ts *STableSpec) Query(f ...IQueryField) *SQuery { return ts.Instance().Query(f...) } +// QueryOrderType indicates the query order type, either ASC or DESC type QueryOrderType string const ( - SQL_ORDER_ASC QueryOrderType = "ASC" + // SQL_ORDER_ASC represents Ascending order + SQL_ORDER_ASC QueryOrderType = "ASC" + + // SQL_ORDER_DESC represents Descending order SQL_ORDER_DESC QueryOrderType = "DESC" ) +// Equals of QueryOrderType determines whether two order type identical func (qot QueryOrderType) Equals(orderType string) bool { if strings.ToUpper(orderType) == string(qot) { return true - } else { - return false } + return false } -type SQueryOrder struct { +// internal structure to store state of query order +type sQueryOrder struct { field IQueryField order QueryOrderType } func (tq *SQuery) _orderBy(order QueryOrderType, fields []IQueryField) *SQuery { if tq.orderBy == nil { - tq.orderBy = make([]SQueryOrder, 0) + tq.orderBy = make([]sQueryOrder, 0) } for i := range fields { - tq.orderBy = append(tq.orderBy, SQueryOrder{field: fields[i], order: order}) + tq.orderBy = append(tq.orderBy, sQueryOrder{field: fields[i], order: order}) } return tq } +// Asc of SQuery does query in ascending order of specified fields func (tq *SQuery) Asc(fields ...interface{}) *SQuery { return tq._orderBy(SQL_ORDER_ASC, convertQueryField(tq, fields)) } +// Desc of SQuery does query in descending order of specified fields func (tq *SQuery) Desc(fields ...interface{}) *SQuery { return tq._orderBy(SQL_ORDER_DESC, convertQueryField(tq, fields)) } @@ -291,6 +345,7 @@ func convertQueryField(tq IQuery, fields []interface{}) []IQueryField { return nFields } +// GroupBy of SQuery does query group by specified fields func (tq *SQuery) GroupBy(f ...interface{}) *SQuery { if tq.groupBy == nil { tq.groupBy = make([]IQueryField, 0) @@ -300,24 +355,27 @@ func (tq *SQuery) GroupBy(f ...interface{}) *SQuery { return tq } +// Limit of SQuery adds limit to a query func (tq *SQuery) Limit(limit int) *SQuery { tq.limit = limit return tq } +// Offset of SQuery adds offset to a query func (tq *SQuery) Offset(offset int) *SQuery { tq.offset = offset return tq } +// QueryFields of SQuery returns fields in SELECT clause of a query func (tq *SQuery) QueryFields() []IQueryField { if len(tq.fields) > 0 { return tq.fields - } else { - return tq.from.Fields() } + return tq.from.Fields() } +// String of SQuery implemetation of SQuery for IQuery func (tq *SQuery) String(fields ...IQueryField) string { sql := queryString(tq, fields...) // log.Debugf("Query: %s", sql) @@ -395,14 +453,17 @@ func queryString(tq *SQuery, tmpFields ...IQueryField) string { return buf.String() } +// Join of SQuery joins query with another IQuerySource on specified condition func (tq *SQuery) Join(from IQuerySource, on ICondition) *SQuery { return tq._join(from, on, INNERJOIN) } +// LeftJoin of SQuery left-joins query with another IQuerySource on specified condition func (tq *SQuery) LeftJoin(from IQuerySource, on ICondition) *SQuery { return tq._join(from, on, LEFTJOIN) } +// RightJoin of SQuery right-joins query with another IQuerySource on specified condition func (tq *SQuery) RightJoin(from IQuerySource, on ICondition) *SQuery { return tq._join(from, on, RIGHTJOIN) } @@ -413,13 +474,14 @@ func (tq *SQuery) RightJoin(from IQuerySource, on ICondition) *SQuery { func (tq *SQuery) _join(from IQuerySource, on ICondition, joinType QueryJoinType) *SQuery { if tq.joins == nil { - tq.joins = make([]SQueryJoin, 0) + tq.joins = make([]sQueryJoin, 0) } - qj := SQueryJoin{jointype: joinType, from: from, condition: on} + qj := sQueryJoin{jointype: joinType, from: from, condition: on} tq.joins = append(tq.joins, qj) return tq } +// Variables implementation of SQuery for IQuery func (tq *SQuery) Variables() []interface{} { vars := make([]interface{}, 0) var fromvars []interface{} @@ -449,34 +511,40 @@ func (tq *SQuery) Variables() []interface{} { return vars } +// Distinct of SQuery indicates a distinct query results func (tq *SQuery) Distinct() *SQuery { tq.distinct = true return tq } +// SubQuery of SQuery generates a SSubQuery from a Query func (tq *SQuery) SubQuery() *SSubQuery { sq := SSubQuery{query: tq, alias: getTableAliasName()} return &sq } +// Row of SQuery returns an instance of sql.Row for native data fetching func (tq *SQuery) Row() *sql.Row { sqlstr := tq.String() vars := tq.Variables() if DEBUG_SQLCHEMY { - log.Debugf("SQuery %s with vars: %s", sqlstr, vars) + sqlDebug(sqlstr, vars) } return _db.QueryRow(sqlstr, vars...) } +// Rows of SQuery returns an instance of sql.Rows for native data fetching func (tq *SQuery) Rows() (*sql.Rows, error) { sqlstr := tq.String() vars := tq.Variables() if DEBUG_SQLCHEMY { - log.Debugf("SQuery %s with vars: %s", sqlstr, vars) + sqlDebug(sqlstr, vars) } return _db.Query(sqlstr, vars...) } +// Count of SQuery returns the count of a query +// use CountWithError instead // deprecated func (tq *SQuery) Count() int { cnt, _ := tq.CountWithError() @@ -496,6 +564,7 @@ func (tq *SQuery) countQuery() *SQuery { return cq } +// CountWithError of SQuery returns the row count of a query func (tq *SQuery) CountWithError() (int, error) { cq := tq.countQuery() count := 0 @@ -507,6 +576,7 @@ func (tq *SQuery) CountWithError() (int, error) { return -1, err } +// Field implementation of SQuery for IQuery func (tq *SQuery) Field(name string) IQueryField { f := tq.findField(name) if DEBUG_SQLCHEMY && f == nil { @@ -562,6 +632,7 @@ func (tq *SQuery) internalFindField(name string) IQueryField { return nil } +// IRowScanner is an interface for sql data fetching type IRowScanner interface { Scan(desc ...interface{}) error } @@ -590,8 +661,8 @@ func rowScan2StringMap(fields []string, row IRowScanner) (map[string]string, err return results, nil } -func (q *SQuery) rowScan2StringMap(row IRowScanner) (map[string]string, error) { - queryFields := q.QueryFields() +func (tq *SQuery) rowScan2StringMap(row IRowScanner) (map[string]string, error) { + queryFields := tq.QueryFields() fields := make([]string, len(queryFields)) for i, f := range queryFields { fields[i] = f.Name() @@ -599,19 +670,21 @@ func (q *SQuery) rowScan2StringMap(row IRowScanner) (map[string]string, error) { return rowScan2StringMap(fields, row) } -func (q *SQuery) FirstStringMap() (map[string]string, error) { - return q.rowScan2StringMap(q.Row()) +// FirstStringMap returns query result of the first row in a stringmap(map[string]string) +func (tq *SQuery) FirstStringMap() (map[string]string, error) { + return tq.rowScan2StringMap(tq.Row()) } -func (q *SQuery) AllStringMap() ([]map[string]string, error) { - rows, err := q.Rows() +// AllStringMap returns query result of all rows in an array of stringmap(map[string]string) +func (tq *SQuery) AllStringMap() ([]map[string]string, error) { + rows, err := tq.Rows() if err != nil { return nil, err } defer rows.Close() results := make([]map[string]string, 0) for rows.Next() { - result, err := q.rowScan2StringMap(rows) + result, err := tq.rowScan2StringMap(rows) if err != nil { return nil, err } @@ -644,8 +717,9 @@ func callAfterQuery(val reflect.Value) { } } -func (q *SQuery) First(dest interface{}) error { - mapResult, err := q.FirstStringMap() +// First return query result of first row and store the result in a data struct +func (tq *SQuery) First(dest interface{}) error { + mapResult, err := tq.FirstStringMap() if err != nil { return err } @@ -662,7 +736,8 @@ func (q *SQuery) First(dest interface{}) error { return nil } -func (q *SQuery) All(dest interface{}) error { +// All return query results of all rows and store the result in an array of data struct +func (tq *SQuery) All(dest interface{}) error { arrayType := reflect.TypeOf(dest).Elem() if arrayType.Kind() != reflect.Array && arrayType.Kind() != reflect.Slice { @@ -670,7 +745,7 @@ func (q *SQuery) All(dest interface{}) error { } elemType := arrayType.Elem() - mapResults, err := q.AllStringMap() + mapResults, err := tq.AllStringMap() if err != nil { return err } @@ -690,11 +765,13 @@ func (q *SQuery) All(dest interface{}) error { return err } -func (q *SQuery) Row2Map(row IRowScanner) (map[string]string, error) { - return q.rowScan2StringMap(row) +// Row2Map is a utility function that fetch stringmap(map[string]string) from a native sql.Row or sql.Rows +func (tq *SQuery) Row2Map(row IRowScanner) (map[string]string, error) { + return tq.rowScan2StringMap(row) } -func (q *SQuery) RowMap2Struct(result map[string]string, dest interface{}) error { +// RowMap2Struct is a utility function that fetch struct from a native sql.Row or sql.Rows +func (tq *SQuery) RowMap2Struct(result map[string]string, dest interface{}) error { destPtrValue := reflect.ValueOf(dest) if destPtrValue.Kind() != reflect.Ptr { return errors.Wrap(ErrNeedsPointer, "input must be a pointer") @@ -709,22 +786,25 @@ func (q *SQuery) RowMap2Struct(result map[string]string, dest interface{}) error return nil } -func (q *SQuery) Row2Struct(row IRowScanner, dest interface{}) error { - result, err := q.rowScan2StringMap(row) +// Row2Struct is a utility function that fill a struct with the value of a sql.Row or sql.Rows +func (tq *SQuery) Row2Struct(row IRowScanner, dest interface{}) error { + result, err := tq.rowScan2StringMap(row) if err != nil { return err } - return q.RowMap2Struct(result, dest) + return tq.RowMap2Struct(result, dest) } -func (q *SQuery) Snapshot() *SQuery { - q.snapshot = q.String() - return q +// Snapshot of SQuery take a snapshot of the query, so we can tell wether the query is modified later by comparing the SQL with snapshot +func (tq *SQuery) Snapshot() *SQuery { + tq.snapshot = tq.String() + return tq } -func (q *SQuery) IsAltered() bool { - if len(q.snapshot) == 0 { - panic(fmt.Sprintf("Query %s has never been snapshot when IsAltered called", q.String())) +// IsAltered of SQuery indicates whether a query was altered. By comparing with the saved query snapshot, we can tell whether a query is altered +func (tq *SQuery) IsAltered() bool { + if len(tq.snapshot) == 0 { + panic(fmt.Sprintf("Query %s has never been snapshot when IsAltered called", tq.String())) } - return q.String() != q.snapshot + return tq.String() != tq.snapshot } diff --git a/vendor/yunion.io/x/sqlchemy/rawquery.go b/vendor/yunion.io/x/sqlchemy/rawquery.go index 50e9840a5d..a466ec17c8 100644 --- a/vendor/yunion.io/x/sqlchemy/rawquery.go +++ b/vendor/yunion.io/x/sqlchemy/rawquery.go @@ -14,30 +14,40 @@ package sqlchemy +// SRawQueryField is a struct represents a field of a raw SQL query +// a raw query is a query that not follow standard SELECT ... FROM ... pattern +// e.g. show tables +// the struct implements IQueryField interface type SRawQueryField struct { name string } +// Expression implementation of SRawQueryField for IQueryField func (rqf *SRawQueryField) Expression() string { return rqf.name } +// Name implementation of SRawQueryField for IQueryField func (rqf *SRawQueryField) Name() string { return rqf.name } +// Reference implementation of SRawQueryField for IQueryField func (rqf *SRawQueryField) Reference() string { return rqf.name } +// Label implementation of SRawQueryField for IQueryField func (rqf *SRawQueryField) Label(label string) IQueryField { return rqf } +// Variables implementation of SRawQueryField for IQueryField func (rqf *SRawQueryField) Variables() []interface{} { return nil } +// NewRawQuery returns an instance of SQuery with raw SQL query. e.g. show tables func NewRawQuery(sqlStr string, fields ...string) *SQuery { qfs := make([]IQueryField, len(fields)) for i, f := range fields { diff --git a/vendor/yunion.io/x/sqlchemy/reflect.go b/vendor/yunion.io/x/sqlchemy/reflect.go index 6568e45b4d..0e2ddaa829 100644 --- a/vendor/yunion.io/x/sqlchemy/reflect.go +++ b/vendor/yunion.io/x/sqlchemy/reflect.go @@ -73,9 +73,8 @@ func getStringValue(dat interface{}) string { case reflect.Bool: if value.Bool() { return "true" - } else { - return "false" } + return "false" case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return fmt.Sprintf("%d", value.Int()) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: diff --git a/vendor/yunion.io/x/sqlchemy/sql.go b/vendor/yunion.io/x/sqlchemy/sql.go index 695ec15f18..bf6ea29697 100644 --- a/vendor/yunion.io/x/sqlchemy/sql.go +++ b/vendor/yunion.io/x/sqlchemy/sql.go @@ -20,16 +20,20 @@ import ( "yunion.io/x/log" ) +// the global DB connection var _db *sql.DB +// SetDB sets global DB instance func SetDB(db *sql.DB) { _db = db } +// GetDB get DB instance func GetDB() *sql.DB { return _db } +// CloseDB close DB connection func CloseDB() { _db.Close() _db = nil @@ -39,6 +43,7 @@ type tableName struct { Name string } +// GetTables get all tables' name in database func GetTables() []string { tables := make([]tableName, 0) q := NewRawQuery("SHOW TABLES", "name") @@ -54,6 +59,7 @@ func GetTables() []string { return ret } +// Exec execute a raw SQL query func Exec(sql string, args ...interface{}) (sql.Result, error) { return _db.Exec(sql, args...) } diff --git a/vendor/yunion.io/x/sqlchemy/sync.go b/vendor/yunion.io/x/sqlchemy/sync.go index cf397c98e0..3fdc0e5e6a 100644 --- a/vendor/yunion.io/x/sqlchemy/sync.go +++ b/vendor/yunion.io/x/sqlchemy/sync.go @@ -27,7 +27,7 @@ import ( "yunion.io/x/pkg/utils" ) -type SSqlColumnInfo struct { +type sSqlColumnInfo struct { Field string Type string Collation string @@ -44,13 +44,12 @@ func decodeSqlTypeString(typeStr string) []string { matches := typeReg.FindStringSubmatch(typeStr) if len(matches) >= 3 { return matches[1:] - } else { - parts := strings.Split(typeStr, " ") - return []string{parts[0]} } + parts := strings.Split(typeStr, " ") + return []string{parts[0]} } -func (info *SSqlColumnInfo) toColumnSpec() IColumnSpec { +func (info *sSqlColumnInfo) toColumnSpec() IColumnSpec { tagmap := make(map[string]string) matches := decodeSqlTypeString(info.Type) @@ -151,7 +150,7 @@ func (info *SSqlColumnInfo) toColumnSpec() IColumnSpec { func (ts *STableSpec) fetchColumnDefs() ([]IColumnSpec, error) { sql := fmt.Sprintf("SHOW FULL COLUMNS IN `%s`", ts.name) query := NewRawQuery(sql, "field", "type", "collation", "null", "key", "default", "extra", "privileges", "comment") - infos := make([]SSqlColumnInfo, 0) + infos := make([]sSqlColumnInfo, 0) err := query.All(&infos) if err != nil { return nil, err @@ -163,7 +162,7 @@ func (ts *STableSpec) fetchColumnDefs() ([]IColumnSpec, error) { return specs, nil } -func (ts *STableSpec) fetchIndexesAndConstraints() ([]STableIndex, []STableConstraint, error) { +func (ts *STableSpec) fetchIndexesAndConstraints() ([]sTableIndex, []sTableConstraint, error) { sql := fmt.Sprintf("SHOW CREATE TABLE `%s`", ts.name) query := NewRawQuery(sql, "table", "create table") row := query.Row() @@ -218,31 +217,31 @@ func diffCols(tableName string, cols1 []IColumnSpec, cols2 []IColumnSpec) ([]ICo newCol: cols2[j], }) } - i += 1 - j += 1 + i++ + j++ } else if comp > 0 { add = append(add, cols2[j]) - j += 1 + j++ } else { remove = append(remove, cols1[i]) - i += 1 + i++ } } else if i < len(cols1) { remove = append(remove, cols1[i]) - i += 1 + i++ } else if j < len(cols2) { add = append(add, cols2[j]) - j += 1 + j++ } } return remove, update, add } -func diffIndexes2(exists []STableIndex, defs []STableIndex) (diff []STableIndex) { - diff = make([]STableIndex, 0) - for i := 0; i < len(exists); i += 1 { +func diffIndexes2(exists []sTableIndex, defs []sTableIndex) (diff []sTableIndex) { + diff = make([]sTableIndex, 0) + for i := 0; i < len(exists); i++ { findDef := false - for j := 0; j < len(defs); j += 1 { + for j := 0; j < len(defs); j++ { if defs[j].IsIdentical(exists[i].columns...) { findDef = true break @@ -255,10 +254,11 @@ func diffIndexes2(exists []STableIndex, defs []STableIndex) (diff []STableIndex) return } -func diffIndexes(exists []STableIndex, defs []STableIndex) (added []STableIndex, removed []STableIndex) { +func diffIndexes(exists []sTableIndex, defs []sTableIndex) (added []sTableIndex, removed []sTableIndex) { return diffIndexes2(defs, exists), diffIndexes2(exists, defs) } +// DropForeignKeySQL returns the SQL statements to do droping foreignkey for a TableSpec func (ts *STableSpec) DropForeignKeySQL() []string { _, constraints, err := ts.fetchIndexesAndConstraints() if err != nil { @@ -278,12 +278,15 @@ func (ts *STableSpec) DropForeignKeySQL() []string { return ret } +// Exists checks wheter a table exists func (ts *STableSpec) Exists() bool { tables := GetTables() in, _ := utils.InStringArray(ts.name, tables) return in } +// SyncSQL returns SQL statements that make table in database consistent with TableSpec definitions +// by comparing table definition derived from TableSpec and that in database func (ts *STableSpec) SyncSQL() []string { if !ts.Exists() { log.Debugf("table %s not created yet", ts.name) @@ -408,6 +411,8 @@ func (ts *STableSpec) SyncSQL() []string { return ret } +// Sync executes the SQLs to synchronize the DB definion of s SQL database +// by applying the SQL statements generated by SyncSQL() func (ts *STableSpec) Sync() error { sqls := ts.SyncSQL() if sqls != nil { @@ -422,6 +427,7 @@ func (ts *STableSpec) Sync() error { return nil } +// CheckSync checks whether the table in database consistent with TableSpec func (ts *STableSpec) CheckSync() error { sqls := ts.SyncSQL() if len(sqls) > 0 { diff --git a/vendor/yunion.io/x/sqlchemy/table.go b/vendor/yunion.io/x/sqlchemy/table.go index 193199f7d7..0c0884dc05 100644 --- a/vendor/yunion.io/x/sqlchemy/table.go +++ b/vendor/yunion.io/x/sqlchemy/table.go @@ -23,48 +23,80 @@ import ( "yunion.io/x/pkg/utils" ) +// ITableSpec is the interface represents a table type ITableSpec interface { + // Insert performs an insert operation that insert one record at a time Insert(dt interface{}) error + + // InsertOrUpdate performs an atomic insert or update operation that insert a new record to update the record with current value InsertOrUpdate(dt interface{}) error + + // Update performs an update operation Update(dt interface{}, onUpdate func() error) (UpdateDiffs, error) + + // Increment performs a special update that do an atomic incremental update of the numeric fields Increment(diff, target interface{}) error + + // Decrement performs a special update that do an atomic decremental update of the numeric fields Decrement(diff, target interface{}) error + // DataType returns the data type corresponding to the table DataType() reflect.Type + + // ColumnSpec returns the column definition of a spcific column ColumnSpec(name string) IColumnSpec + + // Name returns the name of the table Name() string + + // Columns returns the array of columns definitions Columns() []IColumnSpec + + // PrimaryColumns returns the array of columns of primary keys PrimaryColumns() []IColumnSpec + + // Expression returns expression of the table Expression() string + // Instance returns an instance of STable for this spec Instance() *STable + // DropForeignKeySQL returns the SQL statements to drop foreignkeys for this table DropForeignKeySQL() []string + + // AddIndex adds index to table AddIndex(unique bool, cols ...string) bool + // SyncSQL forces synchronize the data definition and model definition of the table SyncSQL() []string + + // Fetch query a struct Fetch(dt interface{}) error } +// STableSpec defines the table specification, which implements ITableSpec type STableSpec struct { structType reflect.Type name string columns []IColumnSpec - indexes []STableIndex - contraints []STableConstraint + indexes []sTableIndex + contraints []sTableConstraint } +// STable is an instance of table for query, system will automatically give a alias to this table type STable struct { spec ITableSpec alias string } +// STableField represents a field in a table, implements IQueryField type STableField struct { table *STable spec IColumnSpec alias string } +// NewTableSpecFromStruct generates STableSpec based on the information of a struct model func NewTableSpecFromStruct(s interface{}, name string) *STableSpec { val := reflect.Indirect(reflect.ValueOf(s)) st := val.Type() @@ -80,14 +112,17 @@ func NewTableSpecFromStruct(s interface{}, name string) *STableSpec { return table } +// Name implementation of STableSpec for ITableSpec func (ts *STableSpec) Name() string { return ts.name } +// Expression implementation of STableSpec for ITableSpec func (ts *STableSpec) Expression() string { return fmt.Sprintf("`%s`", ts.name) } +// Clone makes a clone of a table, so we may create a new table of the same schema func (ts *STableSpec) Clone(name string, autoIncOffset int64) *STableSpec { newCols := make([]IColumnSpec, len(ts.columns)) for i := range newCols { @@ -109,10 +144,12 @@ func (ts *STableSpec) Clone(name string, autoIncOffset int64) *STableSpec { } } +// Columns implementation of STableSpec for ITableSpec func (ts *STableSpec) Columns() []IColumnSpec { return ts.columns } +// PrimaryColumns implementation of STableSpec for ITableSpec func (ts *STableSpec) PrimaryColumns() []IColumnSpec { ret := make([]IColumnSpec, 0) for i := range ts.columns { @@ -123,10 +160,12 @@ func (ts *STableSpec) PrimaryColumns() []IColumnSpec { return ret } +// DataType implementation of STableSpec for ITableSpec func (ts *STableSpec) DataType() reflect.Type { return ts.structType } +// CreateSQL returns the SQL for creating this table func (ts *STableSpec) CreateSQL() string { cols := make([]string, 0) primaries := make([]string, 0) @@ -153,15 +192,18 @@ func (ts *STableSpec) CreateSQL() string { return fmt.Sprintf("CREATE TABLE IF NOT EXISTS `%s` (\n%s\n) ENGINE=InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci%s", ts.name, strings.Join(cols, ",\n"), autoInc) } +// NewTableInstance return an new table instance from an ITableSpec func NewTableInstance(ts ITableSpec) *STable { table := STable{spec: ts, alias: getTableAliasName()} return &table } +// Instance return an new table instance from an instance of STableSpec func (ts *STableSpec) Instance() *STable { return NewTableInstance(ts) } +// ColumnSpec implementation of STableSpec for ITableSpec func (ts *STableSpec) ColumnSpec(name string) IColumnSpec { for _, c := range ts.Columns() { if c.Name() == name { @@ -171,6 +213,7 @@ func (ts *STableSpec) ColumnSpec(name string) IColumnSpec { return nil } +// Field implementation of STableSpec for IQuerySource func (tbl *STable) Field(name string, alias ...string) IQueryField { // name = reflectutils.StructFieldName(name) name = utils.CamelSplit(name, "_") @@ -186,6 +229,7 @@ func (tbl *STable) Field(name string, alias ...string) IQueryField { return &col } +// Fields implementation of STable for IQuerySource func (tbl *STable) Fields() []IQueryField { ret := make([]IQueryField, 0) for _, c := range tbl.spec.Columns() { @@ -194,26 +238,28 @@ func (tbl *STable) Fields() []IQueryField { return ret } +// Expression implementation of STableField for IQueryField func (c *STableField) Expression() string { if len(c.alias) > 0 { - return fmt.Sprintf("%s.%s as `%s`", c.table.Alias(), c.spec.Name(), c.alias) - } else { - return fmt.Sprintf("%s.%s", c.table.Alias(), c.spec.Name()) + return fmt.Sprintf("`%s`.`%s` as `%s`", c.table.Alias(), c.spec.Name(), c.alias) } + return fmt.Sprintf("`%s`.`%s`", c.table.Alias(), c.spec.Name()) } +// Name implementation of STableField for IQueryField func (c *STableField) Name() string { if len(c.alias) > 0 { return c.alias - } else { - return c.spec.Name() } + return c.spec.Name() } +// Reference implementation of STableField for IQueryField func (c *STableField) Reference() string { return fmt.Sprintf("`%s`.`%s`", c.table.Alias(), c.Name()) } +// Label implementation of STableField for IQueryField func (c *STableField) Label(label string) IQueryField { if len(label) > 0 && label != c.spec.Name() { c.alias = label @@ -221,6 +267,7 @@ func (c *STableField) Label(label string) IQueryField { return c } +// Variables implementation of STableField for IQueryField func (c *STableField) Variables() []interface{} { return nil } diff --git a/vendor/yunion.io/x/sqlchemy/tablealias.go b/vendor/yunion.io/x/sqlchemy/tablealias.go index 60763b2fde..96b14f118b 100644 --- a/vendor/yunion.io/x/sqlchemy/tablealias.go +++ b/vendor/yunion.io/x/sqlchemy/tablealias.go @@ -27,6 +27,6 @@ var ( func getTableAliasName() string { tableIDLock.Lock() defer tableIDLock.Unlock() - tableID += 1 + tableID++ return fmt.Sprintf("t%d", tableID) } diff --git a/vendor/yunion.io/x/sqlchemy/union.go b/vendor/yunion.io/x/sqlchemy/union.go index b755ba8cd6..fb23d0c2d5 100644 --- a/vendor/yunion.io/x/sqlchemy/union.go +++ b/vendor/yunion.io/x/sqlchemy/union.go @@ -23,28 +23,35 @@ import ( "yunion.io/x/pkg/errors" ) +// SUnionQueryField represents a field of a union query type SUnionQueryField struct { union *SUnion name string alias string } +// Expression implementation of SUnionQueryField for IQueryField func (sqf *SUnionQueryField) Expression() string { - return sqf.name -} - -func (sqf *SUnionQueryField) Name() string { if len(sqf.alias) > 0 { - return sqf.alias - } else { - return sqf.name + return fmt.Sprintf("`%s`.`%s` as `%s`", sqf.union.Alias(), sqf.name, sqf.alias) } -} - -func (sqf *SUnionQueryField) Reference() string { return fmt.Sprintf("`%s`.`%s`", sqf.union.Alias(), sqf.name) } +// Name implementation of SUnionQueryField for IQueryField +func (sqf *SUnionQueryField) Name() string { + if len(sqf.alias) > 0 { + return sqf.alias + } + return sqf.name +} + +// Reference implementation of SUnionQueryField for IQueryField +func (sqf *SUnionQueryField) Reference() string { + return fmt.Sprintf("`%s`.`%s`", sqf.union.Alias(), sqf.Name()) +} + +// Label implementation of SUnionQueryField for IQueryField func (sqf *SUnionQueryField) Label(label string) IQueryField { if len(label) > 0 && label != sqf.name { sqf.alias = label @@ -52,23 +59,27 @@ func (sqf *SUnionQueryField) Label(label string) IQueryField { return sqf } +// Variables implementation of SUnionQueryField for IQueryField func (sqf *SUnionQueryField) Variables() []interface{} { return nil } +// SUnion is the struct to store state of a Union query, which implementation the interface of IQuerySource type SUnion struct { alias string queries []IQuery fields []IQueryField - orderBy []SQueryOrder + orderBy []sQueryOrder limit int offset int } +// Alias implementation of SUnion for IQuerySource func (uq *SUnion) Alias() string { return uq.alias } +// Expression implementation of SUnion for IQuerySource func (uq *SUnion) Expression() string { var buf strings.Builder buf.WriteByte('(') @@ -118,20 +129,24 @@ func (tq *SUnion) Desc(fields ...interface{}) *SUnion { } */ +// Limit adds limit to a union query func (uq *SUnion) Limit(limit int) *SUnion { uq.limit = limit return uq } +// Offset adds offset to a union query func (uq *SUnion) Offset(offset int) *SUnion { uq.offset = offset return uq } +// Fields implementation of SUnion for IQuerySource func (uq *SUnion) Fields() []IQueryField { return uq.fields } +// Field implementation of SUnion for IQuerySource func (uq *SUnion) Field(name string, alias ...string) IQueryField { for i := range uq.fields { if name == uq.fields[i].Name() { @@ -144,6 +159,7 @@ func (uq *SUnion) Field(name string, alias ...string) IQueryField { return nil } +// Variables implementation of SUnion for IQuerySource func (uq *SUnion) Variables() []interface{} { ret := make([]interface{}, 0) for i := range uq.queries { @@ -152,6 +168,8 @@ func (uq *SUnion) Variables() []interface{} { return ret } +// Union method returns union query of several queries. +// Require the fields of all queries should exactly match // deprecated func Union(query ...IQuery) *SUnion { u, err := UnionWithError(query...) @@ -161,6 +179,8 @@ func Union(query ...IQuery) *SUnion { return u } +// UnionWithError constructs union query of several Queries +// Require the fields of all queries should exactly match func UnionWithError(query ...IQuery) (*SUnion, error) { if len(query) == 0 { return nil, errors.Wrap(sql.ErrNoRows, "empty union query") @@ -171,14 +191,14 @@ func UnionWithError(query ...IQuery) (*SUnion, error) { fieldNames = append(fieldNames, f.Name()) } - for i := 1; i < len(query); i += 1 { + for i := 1; i < len(query); i++ { qfields := query[i].QueryFields() if len(fieldNames) != len(qfields) { - return nil, fmt.Errorf("cannot union, number of fields not match!") + return nil, errors.Wrap(ErrUnionFieldsNotMatch, "number not match") } for i := range qfields { if fieldNames[i] != qfields[i].Name() { - return nil, fmt.Errorf("cannot union, name of fields not match!") + return nil, errors.Wrapf(ErrUnionFieldsNotMatch, "name %s:%s not match", fieldNames[i], qfields[i].Name()) } } } @@ -198,6 +218,7 @@ func UnionWithError(query ...IQuery) (*SUnion, error) { return uq, nil } +// Query of SUnion returns a SQuery of a union query func (uq *SUnion) Query(f ...IQueryField) *SQuery { return DoQuery(uq, f...) } diff --git a/vendor/yunion.io/x/sqlchemy/update.go b/vendor/yunion.io/x/sqlchemy/update.go index cd3f9225d0..9f8b38feb3 100644 --- a/vendor/yunion.io/x/sqlchemy/update.go +++ b/vendor/yunion.io/x/sqlchemy/update.go @@ -28,6 +28,7 @@ import ( "yunion.io/x/pkg/utils" ) +// SUpdateSession is a struct to store the state of a update session type SUpdateSession struct { oValue reflect.Value tableSpec *STableSpec @@ -62,12 +63,14 @@ func (ts *STableSpec) prepareUpdate(dt interface{}) (*SUpdateSession, error) { return &us, nil } +// SUpdateDiff is a struct to store the differences for an update of a column type SUpdateDiff struct { old interface{} new interface{} col IColumnSpec } +// String of SUpdateDiff returns the string representation of a SUpdateDiff func (ud *SUpdateDiff) String() string { return fmt.Sprintf("%s->%s", utils.TruncateString(ud.old, 32), @@ -81,8 +84,10 @@ func (ud SUpdateDiff) jsonObj() jsonutils.JSONObject { return r } +// UpdateDiffs is a map of SUpdateDiff whose key is the column name type UpdateDiffs map[string]SUpdateDiff +// String of UpdateDiffs returns the string representation of UpdateDiffs func (uds UpdateDiffs) String() string { obj := jsonutils.NewDict() for k := range uds { @@ -206,6 +211,9 @@ func (us *SUpdateSession) saveUpdate(dt interface{}) (UpdateDiffs, error) { return setters, nil } +// Update method of STableSpec updates a record of a table, +// dt is the point to the struct storing the record +// doUpdate provides method to update the field of the record func (ts *STableSpec) Update(dt interface{}, doUpdate func() error) (UpdateDiffs, error) { session, err := ts.prepareUpdate(dt) if err != nil {