mirror of
https://gitee.com/johng/gf
synced 2026-06-12 20:23:22 +08:00
Compare commits
341 Commits
v2.0.3
...
v2.1.0-rc4
| Author | SHA1 | Date | |
|---|---|---|---|
| 0639becccc | |||
| 88844649eb | |||
| 31c5d5a5f5 | |||
| 6abbc57c96 | |||
| 39af6e51c4 | |||
| ef04c8a09e | |||
| 4505d61604 | |||
| 04d32e7a91 | |||
| 26066965c3 | |||
| 7f199527f8 | |||
| ea79b3cbb8 | |||
| 0ca81bd11a | |||
| 4d13ffdc26 | |||
| 331a29024e | |||
| 6aa5c2b2ef | |||
| 8c969b2a84 | |||
| 0d7e28ee75 | |||
| ab5062663e | |||
| 896b9fa105 | |||
| 6a01275499 | |||
| 61bf0a0092 | |||
| d7c5a08d20 | |||
| 350ee9f0a2 | |||
| 7753fc6fe1 | |||
| 24f5b2782d | |||
| 853d7aaf8f | |||
| 07509e9847 | |||
| ab82599ee2 | |||
| 10e2b60ad9 | |||
| 965476c7f4 | |||
| 9536b33a6a | |||
| 61271e4f7b | |||
| 57941b6df9 | |||
| 1102de5a66 | |||
| 6d33a73617 | |||
| cdcb0cdc14 | |||
| 6176028176 | |||
| c871bb3a1e | |||
| 3430cf1f17 | |||
| 4556dda038 | |||
| 49042d480c | |||
| b7295a1558 | |||
| 62d91438f2 | |||
| c4c3620c5f | |||
| ec0cbab47e | |||
| 8e3c66584d | |||
| 84e75129a5 | |||
| 26d460241d | |||
| ede54b392e | |||
| d12542d78e | |||
| 3a014dcb09 | |||
| cb27f26e64 | |||
| a3ad294d6a | |||
| cf57ea3ef0 | |||
| 94dd590fc4 | |||
| 27836feb47 | |||
| 96e48e1de6 | |||
| d5c06664b5 | |||
| e4edbe25b2 | |||
| 31bc30bb27 | |||
| a2905977ec | |||
| b63e01adf6 | |||
| 2680666f52 | |||
| f82f53f5f6 | |||
| e27ca17b0e | |||
| 066b1026a2 | |||
| c7cf72e7bc | |||
| 0e2a0075ef | |||
| 6dccaf802c | |||
| de5224689a | |||
| f9ec01c647 | |||
| 4902eb73b7 | |||
| 513c8605fb | |||
| 84148bbbb0 | |||
| c2e91edca8 | |||
| 17fc1ce174 | |||
| be9377a496 | |||
| c40a4d8a66 | |||
| 6d0b4faeb0 | |||
| 3297924992 | |||
| 059c62a6c0 | |||
| bef942b19f | |||
| 30140fb229 | |||
| df3ae386cb | |||
| baf4cc1d1c | |||
| 9fcd3374c1 | |||
| d5d56e51d7 | |||
| 3b8853736d | |||
| 16b22e7505 | |||
| da7eac03ad | |||
| 060f67c2c8 | |||
| 273b81d60f | |||
| 72b58ff8a1 | |||
| 900e0b2751 | |||
| 9026fd2c13 | |||
| f6f0c8fd1e | |||
| 4bdaacab91 | |||
| 60ca7d7246 | |||
| e4e312c4f8 | |||
| 7bcdbae7b8 | |||
| b16cd2dc85 | |||
| 0826f8ba35 | |||
| ead284e20b | |||
| 59023f9f09 | |||
| 17e48ba9f2 | |||
| e60b42470e | |||
| 9c42ba187d | |||
| c6f14dc1b1 | |||
| 02e3240bb1 | |||
| 54f0968f86 | |||
| 0e75d39811 | |||
| 6cf6414da2 | |||
| 89f77a2412 | |||
| a400d8b2f3 | |||
| dc6a9237d7 | |||
| 2c73ba2f76 | |||
| 2cbfdf43cf | |||
| 5e0e6f356b | |||
| cbff244d88 | |||
| 2e405342ca | |||
| 583d576cdb | |||
| 3db97ba0dd | |||
| e81d6a859b | |||
| 534abb7f17 | |||
| 7198eb3b66 | |||
| 32f33b9f8c | |||
| 03ad6a5728 | |||
| c1308475f3 | |||
| e4ec1be948 | |||
| c90f91dcbe | |||
| 5332ce4c79 | |||
| eaae7f46d2 | |||
| 8c40a53b80 | |||
| 25c091df7f | |||
| ec3a4532b8 | |||
| ad04adccea | |||
| cfd2636f13 | |||
| 7e854f88ca | |||
| 3628b1e9d2 | |||
| 68e75c589b | |||
| 9ad9292321 | |||
| 7fcf7d31a0 | |||
| 0cf28c0f07 | |||
| abbc96a873 | |||
| b7201e111d | |||
| a31553468c | |||
| ce89b440bb | |||
| 3a72c4a507 | |||
| c82e612258 | |||
| ae5891068e | |||
| f326dc4eaa | |||
| 48fddcd5e7 | |||
| 33c9204d58 | |||
| 99f1e69469 | |||
| ed0b3c039a | |||
| eef25c28b4 | |||
| a32847f0c5 | |||
| 0fc193faa3 | |||
| 65077a224c | |||
| c256d2d4af | |||
| 215a50675e | |||
| 023c4a19ae | |||
| ac5d399906 | |||
| 7fd0e5b3bc | |||
| 64ff651d57 | |||
| d260de15ba | |||
| be77779aff | |||
| e119f2a534 | |||
| a09c8497bc | |||
| ebad3eb93e | |||
| e4e4534c7c | |||
| b412fc6516 | |||
| f9c9750108 | |||
| 5dee3bb4d9 | |||
| 1e3d8cdadd | |||
| c5bf45f1ae | |||
| bf674060c0 | |||
| 878dbe4ab9 | |||
| d8b383719a | |||
| 9ff5f39701 | |||
| 5144cc0e08 | |||
| ee29b28575 | |||
| 7785082f19 | |||
| edf40ba430 | |||
| a228495ced | |||
| ed9dc70769 | |||
| e8581d4fd5 | |||
| 2d6fcf5d06 | |||
| 55e0262c37 | |||
| d5e5a48170 | |||
| d0f2928cec | |||
| 190a53647e | |||
| f9a3fa3c23 | |||
| f1fee72d6d | |||
| 0b4ae6b116 | |||
| a1ec7cb896 | |||
| 1935412db9 | |||
| c90a9d45ee | |||
| a594592151 | |||
| 119d8bf98c | |||
| 1e141d9f64 | |||
| 587af6dec8 | |||
| 793e862e5a | |||
| 09c3425dd3 | |||
| 4ca168412b | |||
| 66f24db6da | |||
| c39a58f812 | |||
| 5034f231a9 | |||
| 1a271ce627 | |||
| 64afd5f64c | |||
| 0e0d2e1c45 | |||
| 52d8371ba9 | |||
| 1d74b58d36 | |||
| 66803fd664 | |||
| 87609a3424 | |||
| b4184e4523 | |||
| 05508e4fcb | |||
| 372bae4799 | |||
| c7f51b8e77 | |||
| 21f48d3750 | |||
| b57cbacc82 | |||
| 126a81d89a | |||
| 707dc6b346 | |||
| c1c86c026f | |||
| 5c4982cb0c | |||
| fed38ea7ab | |||
| 4d6ef1c52d | |||
| c6aba6da4d | |||
| ec92d2b7f4 | |||
| 6810e71220 | |||
| f4192d695c | |||
| 6664437b06 | |||
| 96a135834a | |||
| 09ba1bf1fb | |||
| cc01629b57 | |||
| 2d586859c3 | |||
| a5e20e4939 | |||
| 0e3f4f45e0 | |||
| 045c3e132f | |||
| 80c068ae05 | |||
| 6574b8cbfe | |||
| 20c48b1712 | |||
| ee16b6df88 | |||
| 325887fa18 | |||
| 73ca527b0a | |||
| 439350836e | |||
| 5ee387672b | |||
| f670c24e2c | |||
| f2e1f63396 | |||
| 6dacdd60dc | |||
| 87ccc27ee4 | |||
| 147348e0d1 | |||
| ad202ea735 | |||
| 950695664c | |||
| d1f76f3834 | |||
| 66e6a05e5f | |||
| 0f430c66ae | |||
| 8357b0f649 | |||
| 7fc75bfeff | |||
| d7bd1b74e8 | |||
| d7764e2968 | |||
| f865d6fa6a | |||
| e6bbead4e6 | |||
| 5f3a525d11 | |||
| c5d80a2192 | |||
| 97b8f0f781 | |||
| bceb5fc7de | |||
| b3e66d8023 | |||
| e06f831205 | |||
| 60340a7348 | |||
| dccfc1c8cd | |||
| d58186372f | |||
| d32246275a | |||
| 2eec1bc61a | |||
| bbab9f3934 | |||
| 09a3f23e3d | |||
| 329f6b90f7 | |||
| a4ab9c284f | |||
| 9e056dfac8 | |||
| d8d9996464 | |||
| 43992a137e | |||
| 7767bf4d5d | |||
| acd1989fa1 | |||
| afa1f78a02 | |||
| 87b1433473 | |||
| 5813979479 | |||
| ba7cbfe3d9 | |||
| 546b6b1724 | |||
| eca3583845 | |||
| 2471130f59 | |||
| f5693c4393 | |||
| 12eb3ac63e | |||
| e3f0163092 | |||
| 213392640c | |||
| 4382a6e7bc | |||
| c200177af4 | |||
| 465100ae41 | |||
| 3d6867c321 | |||
| 3d5ff3b250 | |||
| be47203732 | |||
| 1625fc6f7e | |||
| fa57634505 | |||
| ac71658b4b | |||
| 61db7d96b7 | |||
| 5ee297d999 | |||
| 6301403777 | |||
| 95881d7616 | |||
| 85d8f90d81 | |||
| f6054ab37f | |||
| 5537930210 | |||
| 920dbbef5e | |||
| 2510e0412d | |||
| 2302f88847 | |||
| 4f95d0a07a | |||
| f08c18594b | |||
| b5855037f3 | |||
| 38a7055017 | |||
| 4d5b41434a | |||
| cb69fbcbd6 | |||
| 992a986d12 | |||
| eb533f3344 | |||
| 436931b560 | |||
| 0516159ae3 | |||
| 5e3c0bd9aa | |||
| a6bbb8424c | |||
| 00daeb318c | |||
| 65341141fe | |||
| fe353c5fe3 | |||
| 008e5ea196 | |||
| 157e936f24 | |||
| 455d724c01 | |||
| ea60f7e054 | |||
| daf2b649ef | |||
| aa87d234e3 | |||
| 658ca8c0fd | |||
| d30862373e | |||
| ee4ca43bd5 | |||
| 0dc1adb672 | |||
| 61c9d5fb3f | |||
| 47cefbf6d7 | |||
| b39b2374c4 |
9
.github/ISSUE_TEMPLATE.MD
vendored
9
.github/ISSUE_TEMPLATE.MD
vendored
@ -1,12 +1,11 @@
|
||||
<!-- Please answer these questions before submitting your issue. Thanks! -->
|
||||
|
||||
<!-- 为高效处理您的疑问,如果觉得是BUG类问题,请您务必提供可复现该问题的最小可运行代码! -->
|
||||
<!-- 为高效处理您的疑问,如果觉得是BUG类问题,请您务必提供可复现该问题的最小可运行代码! -->
|
||||
<!-- 为高效处理您的疑问,如果觉得是BUG类问题,请您务必提供可复现该问题的最小可运行代码! -->
|
||||
<!-- 为高效处理您的疑问,如果觉得是BUG类问题,请您务必提供可复现该问题的最小可运行代码!否则issue可能会被延期处理! -->
|
||||
<!-- 为高效处理您的疑问,如果觉得是BUG类问题,请您务必提供可复现该问题的最小可运行代码!否则issue可能会被延期处理! -->
|
||||
<!-- 为高效处理您的疑问,如果觉得是BUG类问题,请您务必提供可复现该问题的最小可运行代码!否则issue可能会被延期处理! -->
|
||||
<!-- 重要的事情说三遍! -->
|
||||
|
||||
### 1. What version of `Go` and system type/arch are you using?
|
||||
|
||||
<!--
|
||||
Please paste the output of command `go version` from your terminal.
|
||||
What expect to see is like: `go 1.12, linux/amd64`
|
||||
@ -14,7 +13,6 @@ What expect to see is like: `go 1.12, linux/amd64`
|
||||
|
||||
|
||||
### 2. What version of `GoFrame` are you using?
|
||||
|
||||
<!-- You can find the GF version from your `go.mod`, or from the `version.go` in `GF` -->
|
||||
|
||||
|
||||
@ -23,7 +21,6 @@ What expect to see is like: `go 1.12, linux/amd64`
|
||||
|
||||
|
||||
### 4. What did you do?
|
||||
|
||||
<!--
|
||||
If possible, provide a copy of shortest codes for reproducing the error.
|
||||
A complete runnable program is best.
|
||||
|
||||
6
.github/workflows/cli.yml
vendored
6
.github/workflows/cli.yml
vendored
@ -40,8 +40,10 @@ jobs:
|
||||
run: |
|
||||
cd cmd/gf/temp
|
||||
for OS in *;do for FILE in $OS/*;\
|
||||
do mv $FILE gf_$OS && rm -rf $OS;\
|
||||
done;done
|
||||
do if [[ ${OS} =~ 'windows' ]];\
|
||||
then mv $FILE gf_$OS.exe && rm -rf $OS;\
|
||||
else mv $FILE gf_$OS && rm -rf $OS;\
|
||||
fi;done;done
|
||||
|
||||
- name: Create Github Release
|
||||
id: create_release
|
||||
|
||||
99
.github/workflows/gf.yml
vendored
99
.github/workflows/gf.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: GoFrame CI
|
||||
name: GoFrame Main CI
|
||||
|
||||
|
||||
on:
|
||||
@ -6,11 +6,15 @@ on:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
- feature/**
|
||||
- fix/**
|
||||
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- develop
|
||||
|
||||
- feature/**
|
||||
- fix/**
|
||||
|
||||
env:
|
||||
GF_DEBUG: 0
|
||||
@ -20,11 +24,11 @@ jobs:
|
||||
code-test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
|
||||
# Service containers to run with `code-test`
|
||||
services:
|
||||
# Redis backend server.
|
||||
redis:
|
||||
image : redis
|
||||
image : loads/redis:latest
|
||||
options: >-
|
||||
--health-cmd "redis-cli ping"
|
||||
--health-interval 10s
|
||||
@ -34,8 +38,9 @@ jobs:
|
||||
# Maps tcp port 6379 on service container to the host
|
||||
- 6379:6379
|
||||
|
||||
# MySQL backend server.
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
image: loads/mysql:5.7
|
||||
env:
|
||||
MYSQL_DATABASE : test
|
||||
MYSQL_ROOT_PASSWORD: 12345678
|
||||
@ -43,8 +48,9 @@ jobs:
|
||||
# Maps tcp port 3306 on service container to the host
|
||||
- 3306:3306
|
||||
|
||||
# PostgreSQL backend server.
|
||||
postgres:
|
||||
image: postgres:13
|
||||
image: loads/postgres:13
|
||||
env:
|
||||
POSTGRES_PASSWORD: 12345678
|
||||
POSTGRES_USER: root
|
||||
@ -59,8 +65,9 @@ jobs:
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
|
||||
# MSSQL backend server.
|
||||
mssql:
|
||||
image: mcmoe/mssqldocker:latest
|
||||
image: loads/mssqldocker:latest
|
||||
env:
|
||||
ACCEPT_EULA: Y
|
||||
SA_PASSWORD: LoremIpsum86
|
||||
@ -76,11 +83,37 @@ jobs:
|
||||
--health-timeout 5s
|
||||
--health-retries 10
|
||||
|
||||
# ClickHouse backend server.
|
||||
clickhouse-server:
|
||||
image: loads/clickhouse-server:latest
|
||||
ports:
|
||||
- 9000:9000
|
||||
- 8123:8123
|
||||
- 9001:9001
|
||||
|
||||
polaris:
|
||||
image: houseme/polaris-server-with-config:latest
|
||||
ports:
|
||||
- 8090:8090
|
||||
- 8091:8091
|
||||
|
||||
#oracle 11g server
|
||||
oracle-server:
|
||||
image: loads/oracle-xe-11g-r2:latest
|
||||
env:
|
||||
ORACLE_ALLOW_REMOTE: true
|
||||
ORACLE_SID: XE
|
||||
ORACLE_DB_USER_NAME: system
|
||||
ORACLE_DB_PASSWORD: oracle
|
||||
ports:
|
||||
- 1521:1521
|
||||
|
||||
|
||||
|
||||
# strategy set
|
||||
strategy:
|
||||
matrix:
|
||||
go: ["1.15", "1.16", "1.17"]
|
||||
go: [ "1.15", "1.16", "1.17" ]
|
||||
goarch: [ "386", "amd64" ]
|
||||
|
||||
|
||||
steps:
|
||||
@ -89,7 +122,7 @@ jobs:
|
||||
with:
|
||||
timezoneLinux: "Asia/Shanghai"
|
||||
|
||||
- name: Checkout Repositary
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set Up Go
|
||||
@ -104,46 +137,30 @@ jobs:
|
||||
echo "gofmt check pass."
|
||||
sudo echo "127.0.0.1 local" | sudo tee -a /etc/hosts
|
||||
|
||||
- name: CLI Build & Test
|
||||
- name: Build & Test
|
||||
run: |
|
||||
cd cmd/gf
|
||||
go mod tidy
|
||||
go build ./...
|
||||
go test ./...
|
||||
|
||||
- name: Example Build & Test
|
||||
run: |
|
||||
cd example
|
||||
go mod tidy
|
||||
go build ./...
|
||||
go test ./...
|
||||
|
||||
- name: Contrib Build & Test
|
||||
run: |
|
||||
cd contrib
|
||||
GOARCH=${{ matrix.goarch }}
|
||||
for file in `find . -name go.mod`; do
|
||||
path=$(dirname $file)
|
||||
# Ignore oracle database driver build&test.
|
||||
if [ "oracle" = $(basename $path) ]; then
|
||||
continue 1
|
||||
dirpath=$(dirname $file)
|
||||
|
||||
if [ "oracle" = $(basename $dirpath) ]; then
|
||||
if ! go version|grep -q "1.17"; then
|
||||
continue 1
|
||||
fi
|
||||
fi
|
||||
cd $path
|
||||
|
||||
cd $dirpath
|
||||
go mod tidy
|
||||
go build ./...
|
||||
go test ./...
|
||||
go test ./... -race -coverprofile=coverage.out -covermode=atomic -coverpkg=./...,github.com/gogf/gf/... || exit 1
|
||||
if grep -q "/gogf/gf/.*/v2" go.mod; then
|
||||
sed -i "s/gogf\/gf\(\/.*\)\/v2/gogf\/gf\/v2\1/g" coverage.out
|
||||
fi
|
||||
cd -
|
||||
done
|
||||
|
||||
- name: Run i386 Arch Test
|
||||
run: |
|
||||
GOARCH=386 go test -v ./... || exit 1
|
||||
|
||||
- name: Run amd64 Arch Test
|
||||
run: |
|
||||
GOARCH=amd64 go test -v ./... -race -coverprofile=coverage.txt -covermode=atomic
|
||||
|
||||
- name: Report Coverage
|
||||
uses: codecov/codecov-action@v2
|
||||
with:
|
||||
flags: go-${{ matrix.go }}
|
||||
flags: go-${{ matrix.go }}-${{ matrix.goarch }}
|
||||
|
||||
|
||||
30
.github/workflows/tag.yml
vendored
Normal file
30
.github/workflows/tag.yml
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
name: GoFrame AutoCreating SubMod Tags
|
||||
|
||||
on:
|
||||
push:
|
||||
# Sequence of patterns matched against refs/tags
|
||||
tags:
|
||||
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
||||
|
||||
env:
|
||||
TZ: Asia/Shanghai
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Auto Creating Tags
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Github Code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Auto Creating Tags
|
||||
run: |
|
||||
git config --global user.email "tagrobot@goframe.org"
|
||||
git config --global user.name "TagRobot"
|
||||
for file in `find contrib -name go.mod`; do
|
||||
tag=$(dirname $file)/$GITHUB_REF_NAME
|
||||
git tag $tag
|
||||
git push origin $tag
|
||||
done
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@ -13,7 +13,5 @@ pkg/
|
||||
bin/
|
||||
cbuild
|
||||
**/.DS_Store
|
||||
.vscode/
|
||||
.test/
|
||||
main
|
||||
gf
|
||||
cmd/gf/main
|
||||
|
||||
991
.golangci.yml
991
.golangci.yml
File diff suppressed because it is too large
Load Diff
13
Makefile
Normal file
13
Makefile
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
.PHONY: tidy
|
||||
tidy:
|
||||
$(eval files=$(shell find . -name go.mod))
|
||||
@set -e; \
|
||||
for file in ${files}; do \
|
||||
goModPath=$$(dirname $$file); \
|
||||
cd $$goModPath; \
|
||||
go mod tidy; \
|
||||
cd -; \
|
||||
done
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
|
||||
## 1. Install
|
||||
|
||||
## 1) PreCompiled Binary
|
||||
You can also install `gf` tool using pre-built binaries: https://github.com/gogf/gf/releases
|
||||
|
||||
1. `Mac` & `Linux`
|
||||
@ -19,6 +20,13 @@ You can also install `gf` tool using pre-built binaries: https://github.com/gogf
|
||||
|
||||
3. Database `sqlite` and `oracle` are not support in `gf gen` command in default as it needs `cgo` and `gcc`, you can manually make some changes to the source codes and do the building.
|
||||
|
||||
## 2) Manually Install
|
||||
|
||||
```shell
|
||||
git clone https://github.com/gogf/gf && cd gf/cmd/gf && go install
|
||||
```
|
||||
|
||||
|
||||
## 2. Commands
|
||||
```html
|
||||
$ gf
|
||||
|
||||
@ -3,15 +3,16 @@ module github.com/gogf/gf/cmd/gf/v2
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.0.0-rc2
|
||||
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.0.0-rc2
|
||||
github.com/gogf/gf/contrib/drivers/sqlite/v2 v2.0.0-rc2
|
||||
github.com/gogf/gf/v2 v2.0.0-rc
|
||||
github.com/gogf/gf/contrib/drivers/mssql/v2 v2.0.6
|
||||
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.0.6
|
||||
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.0.6
|
||||
github.com/gogf/gf/v2 v2.0.6
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
)
|
||||
|
||||
replace (
|
||||
github.com/gogf/gf/contrib/drivers/mssql/v2 => ../../contrib/drivers/mssql/
|
||||
github.com/gogf/gf/contrib/drivers/mysql/v2 => ../../contrib/drivers/mysql/
|
||||
github.com/gogf/gf/contrib/drivers/pgsql/v2 => ../../contrib/drivers/pgsql/
|
||||
github.com/gogf/gf/contrib/drivers/sqlite/v2 => ../../contrib/drivers/sqlite/
|
||||
github.com/gogf/gf/v2 => ../../
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
|
||||
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E=
|
||||
github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -15,10 +18,15 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
|
||||
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
|
||||
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
@ -38,15 +46,19 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0=
|
||||
github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
|
||||
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
|
||||
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
@ -54,8 +66,6 @@ github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.14.10 h1:MLn+5bFRlWMGoSRmJour3CL1w/qL96mvipqpwQW/Sfk=
|
||||
github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
@ -63,26 +73,30 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ=
|
||||
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
|
||||
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.opentelemetry.io/otel v1.0.0 h1:qTTn6x71GVBvoafHK/yaRUmFzI4LcONZD0/kXxl5PHI=
|
||||
go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
|
||||
go.opentelemetry.io/otel/sdk v1.0.0 h1:BNPMYUONPNbLneMttKSjQhOTlFLOD9U22HNG1KrIN2Y=
|
||||
go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM=
|
||||
go.opentelemetry.io/otel/trace v1.0.0 h1:TSBr8GTEtKevYMG/2d21M989r5WJYVimhTHBKVEZuh4=
|
||||
go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
|
||||
go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM=
|
||||
go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk=
|
||||
go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0=
|
||||
go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU=
|
||||
go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o=
|
||||
go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@ -109,6 +123,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -118,8 +133,10 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
||||
@ -25,7 +25,7 @@ import (
|
||||
var (
|
||||
Build = cBuild{
|
||||
nodeNameInConfigFile: "gfcli.build",
|
||||
packedGoFileName: "build_pack_data.go",
|
||||
packedGoFileName: "internal/packed/build_pack_data.go",
|
||||
}
|
||||
)
|
||||
|
||||
@ -108,20 +108,21 @@ func init() {
|
||||
}
|
||||
|
||||
type cBuildInput struct {
|
||||
g.Meta `name:"build" config:"gfcli.build"`
|
||||
File string `name:"FILE" arg:"true" brief:"building file path"`
|
||||
Name string `short:"n" name:"name" brief:"output binary name"`
|
||||
Version string `short:"v" name:"version" brief:"output binary version"`
|
||||
Arch string `short:"a" name:"arch" brief:"output binary architecture, multiple arch separated with ','"`
|
||||
System string `short:"s" name:"system" brief:"output binary system, multiple os separated with ','"`
|
||||
Output string `short:"o" name:"output" brief:"output binary path, used when building single binary file"`
|
||||
Path string `short:"p" name:"path" brief:"output binary directory path, default is './temp'" d:"./temp"`
|
||||
Extra string `short:"e" name:"extra" brief:"extra custom \"go build\" options"`
|
||||
Mod string `short:"m" name:"mod" brief:"like \"-mod\" option of \"go build\", use \"-m none\" to disable go module"`
|
||||
Cgo bool `short:"c" name:"cgo" brief:"enable or disable cgo feature, it's disabled in default" orphan:"true"`
|
||||
VarMap g.Map `short:"r" name:"varMap" brief:"custom built embedded variable into binary"`
|
||||
Exit bool `name:"exit" brief:"exit building when any error occurs, default is false" orphan:"true"`
|
||||
Pack string `name:"pack" brief:"pack specified folder into temporary go file before building and removes it after built"`
|
||||
g.Meta `name:"build" config:"gfcli.build"`
|
||||
File string `name:"FILE" arg:"true" brief:"building file path"`
|
||||
Name string `short:"n" name:"name" brief:"output binary name"`
|
||||
Version string `short:"v" name:"version" brief:"output binary version"`
|
||||
Arch string `short:"a" name:"arch" brief:"output binary architecture, multiple arch separated with ','"`
|
||||
System string `short:"s" name:"system" brief:"output binary system, multiple os separated with ','"`
|
||||
Output string `short:"o" name:"output" brief:"output binary path, used when building single binary file"`
|
||||
Path string `short:"p" name:"path" brief:"output binary directory path, default is './temp'" d:"./temp"`
|
||||
Extra string `short:"e" name:"extra" brief:"extra custom \"go build\" options"`
|
||||
Mod string `short:"m" name:"mod" brief:"like \"-mod\" option of \"go build\", use \"-m none\" to disable go module"`
|
||||
Cgo bool `short:"c" name:"cgo" brief:"enable or disable cgo feature, it's disabled in default" orphan:"true"`
|
||||
VarMap g.Map `short:"r" name:"varMap" brief:"custom built embedded variable into binary"`
|
||||
PackSrc string `short:"ps" name:"packSrc" brief:"pack one or more folders into one go file before building"`
|
||||
PackDst string `short:"pd" name:"packDst" brief:"temporary go file path for pack, this go file will be automatically removed after built" d:"internal/packed/build_pack_data.go"`
|
||||
ExitWhenError bool `short:"ew" name:"exitWhenError" brief:"exit building when any error occurs, default is false" orphan:"true"`
|
||||
}
|
||||
type cBuildOutput struct{}
|
||||
|
||||
@ -189,16 +190,21 @@ func (c cBuild) Index(ctx context.Context, in cBuildInput) (out *cBuildOutput, e
|
||||
platformMap[system][arch] = true
|
||||
}
|
||||
// Auto packing.
|
||||
if len(in.Pack) > 0 {
|
||||
dataFilePath := fmt.Sprintf(`packed/%s`, c.packedGoFileName)
|
||||
if !gfile.Exists(dataFilePath) {
|
||||
if in.PackSrc != "" {
|
||||
if in.PackDst == "" {
|
||||
mlog.Fatal(`parameter "packDst" should not be empty when "packSrc" is used`)
|
||||
}
|
||||
if gfile.Exists(in.PackDst) && !gfile.IsFile(in.PackDst) {
|
||||
mlog.Fatalf(`parameter "packDst" path "%s" should be type of file not directory`, in.PackDst)
|
||||
}
|
||||
if !gfile.Exists(in.PackDst) {
|
||||
// Remove the go file that is automatically packed resource.
|
||||
defer func() {
|
||||
_ = gfile.Remove(dataFilePath)
|
||||
mlog.Printf(`remove the automatically generated resource go file: %s`, dataFilePath)
|
||||
_ = gfile.Remove(in.PackDst)
|
||||
mlog.Printf(`remove the automatically generated resource go file: %s`, in.PackDst)
|
||||
}()
|
||||
}
|
||||
packCmd := fmt.Sprintf(`gf pack %s %s`, in.Pack, dataFilePath)
|
||||
packCmd := fmt.Sprintf(`gf pack %s %s`, in.PackSrc, in.PackDst)
|
||||
mlog.Print(packCmd)
|
||||
gproc.MustShellRun(packCmd)
|
||||
}
|
||||
@ -261,7 +267,7 @@ func (c cBuild) Index(ctx context.Context, in cBuildInput) (out *cBuildOutput, e
|
||||
system, arch, gstr.Trim(result),
|
||||
`you may use command option "--debug" to enable debug info and check the details`,
|
||||
)
|
||||
if in.Exit {
|
||||
if in.ExitWhenError {
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -3,11 +3,13 @@ package cmd
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
)
|
||||
|
||||
@ -37,40 +39,43 @@ It runs "gf build" firstly to compile the project to binary file.
|
||||
It then runs "docker build" command automatically to generate the docker image.
|
||||
You should have docker installed, and there must be a Dockerfile in the root of the project.
|
||||
`
|
||||
cDockerMainBrief = `main file path for "gf build", it's "main.go" in default. empty string for no binary build`
|
||||
cDockerBuildBrief = `binary build options before docker image build, it's "-a amd64 -s linux" in default`
|
||||
cDockerFileBrief = `file path of the Dockerfile. it's "manifest/docker/Dockerfile" in default`
|
||||
cDockerShellBrief = `path of the shell file which is executed before docker build`
|
||||
cDockerPushBrief = `auto push the docker image to docker registry if "-t" option passed`
|
||||
cDockerTagBrief = `tag name for this docker, which is usually used for docker push`
|
||||
cDockerExtraBrief = `extra build options passed to "docker image"`
|
||||
cDockerMainBrief = `main file path for "gf build", it's "main.go" in default. empty string for no binary build`
|
||||
cDockerBuildBrief = `binary build options before docker image build, it's "-a amd64 -s linux" in default`
|
||||
cDockerFileBrief = `file path of the Dockerfile. it's "manifest/docker/Dockerfile" in default`
|
||||
cDockerShellBrief = `path of the shell file which is executed before docker build`
|
||||
cDockerPushBrief = `auto push the docker image to docker registry if "-t" option passed`
|
||||
cDockerTagNameBrief = `tag name for this docker, pattern like "image:tag". this option is required with TagPrefixes`
|
||||
cDockerTagPrefixesBrief = `tag prefixes for this docker, which are used for docker push. this option is required with TagName`
|
||||
cDockerExtraBrief = `extra build options passed to "docker image"`
|
||||
)
|
||||
|
||||
func init() {
|
||||
gtag.Sets(g.MapStrStr{
|
||||
`cDockerUsage`: cDockerUsage,
|
||||
`cDockerBrief`: cDockerBrief,
|
||||
`cDockerEg`: cDockerEg,
|
||||
`cDockerDc`: cDockerDc,
|
||||
`cDockerMainBrief`: cDockerMainBrief,
|
||||
`cDockerFileBrief`: cDockerFileBrief,
|
||||
`cDockerShellBrief`: cDockerShellBrief,
|
||||
`cDockerBuildBrief`: cDockerBuildBrief,
|
||||
`cDockerPushBrief`: cDockerPushBrief,
|
||||
`cDockerTagBrief`: cDockerTagBrief,
|
||||
`cDockerExtraBrief`: cDockerExtraBrief,
|
||||
`cDockerUsage`: cDockerUsage,
|
||||
`cDockerBrief`: cDockerBrief,
|
||||
`cDockerEg`: cDockerEg,
|
||||
`cDockerDc`: cDockerDc,
|
||||
`cDockerMainBrief`: cDockerMainBrief,
|
||||
`cDockerFileBrief`: cDockerFileBrief,
|
||||
`cDockerShellBrief`: cDockerShellBrief,
|
||||
`cDockerBuildBrief`: cDockerBuildBrief,
|
||||
`cDockerPushBrief`: cDockerPushBrief,
|
||||
`cDockerTagNameBrief`: cDockerTagNameBrief,
|
||||
`cDockerTagPrefixesBrief`: cDockerTagPrefixesBrief,
|
||||
`cDockerExtraBrief`: cDockerExtraBrief,
|
||||
})
|
||||
}
|
||||
|
||||
type cDockerInput struct {
|
||||
g.Meta `name:"docker" config:"gfcli.docker"`
|
||||
Main string `name:"MAIN" arg:"true" brief:"{cDockerMainBrief}" d:"main.go"`
|
||||
File string `name:"file" short:"f" brief:"{cDockerFileBrief}" d:"manifest/docker/Dockerfile"`
|
||||
Shell string `name:"shell" short:"s" brief:"{cDockerShellBrief}" d:"manifest/docker/docker.sh"`
|
||||
Build string `name:"build" short:"b" brief:"{cDockerBuildBrief}" d:"-a amd64 -s linux"`
|
||||
Tag string `name:"tag" short:"t" brief:"{cDockerTagBrief}"`
|
||||
Push bool `name:"push" short:"p" brief:"{cDockerPushBrief}" orphan:"true"`
|
||||
Extra string `name:"extra" short:"e" brief:"{cDockerExtraBrief}"`
|
||||
g.Meta `name:"docker" config:"gfcli.docker"`
|
||||
Main string `name:"MAIN" arg:"true" brief:"{cDockerMainBrief}" d:"main.go"`
|
||||
File string `name:"file" short:"f" brief:"{cDockerFileBrief}" d:"manifest/docker/Dockerfile"`
|
||||
Shell string `name:"shell" short:"s" brief:"{cDockerShellBrief}" d:"manifest/docker/docker.sh"`
|
||||
Build string `name:"build" short:"b" brief:"{cDockerBuildBrief}" d:"-a amd64 -s linux"`
|
||||
TagName string `name:"tagName" short:"tn" brief:"{cDockerTagNameBrief}" v:"required-with:TagPrefixes"`
|
||||
TagPrefixes []string `name:"tagPrefixes" short:"tp" brief:"{cDockerTagPrefixesBrief}" v:"required-with:TagName"`
|
||||
Push bool `name:"push" short:"p" brief:"{cDockerPushBrief}" orphan:"true"`
|
||||
Extra string `name:"extra" short:"e" brief:"{cDockerExtraBrief}"`
|
||||
}
|
||||
type cDockerOutput struct{}
|
||||
|
||||
@ -89,28 +94,68 @@ func (c cDocker) Index(ctx context.Context, in cDockerInput) (out *cDockerOutput
|
||||
}
|
||||
|
||||
// Shell executing.
|
||||
if gfile.Exists(in.Shell) {
|
||||
if err = gproc.ShellRun(gfile.GetContents(in.Shell)); err != nil {
|
||||
if in.Shell != "" && gfile.Exists(in.Shell) {
|
||||
if err = c.exeDockerShell(in.Shell); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
// Docker build.
|
||||
dockerBuildOptions := ""
|
||||
if in.Tag != "" {
|
||||
dockerBuildOptions = fmt.Sprintf(`-t %s`, in.Tag)
|
||||
var (
|
||||
dockerBuildOptions string
|
||||
dockerTags []string
|
||||
dockerTagBase string
|
||||
)
|
||||
if len(in.TagPrefixes) > 0 {
|
||||
for _, tagPrefix := range in.TagPrefixes {
|
||||
tagPrefix = gstr.TrimRight(tagPrefix, "/")
|
||||
dockerTags = append(dockerTags, fmt.Sprintf(`%s/%s`, tagPrefix, in.TagName))
|
||||
}
|
||||
}
|
||||
if in.Extra != "" {
|
||||
dockerBuildOptions = fmt.Sprintf(`%s %s`, dockerBuildOptions, in.Extra)
|
||||
if len(dockerTags) == 0 {
|
||||
dockerTags = []string{""}
|
||||
}
|
||||
if err = gproc.ShellRun(fmt.Sprintf(`docker build -f %s . %s`, in.File, dockerBuildOptions)); err != nil {
|
||||
return
|
||||
for i, dockerTag := range dockerTags {
|
||||
if i > 0 {
|
||||
err = gproc.ShellRun(fmt.Sprintf(`docker tag %s %s`, dockerTagBase, dockerTag))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
continue
|
||||
}
|
||||
dockerTagBase = dockerTag
|
||||
dockerBuildOptions = ""
|
||||
if dockerTag != "" {
|
||||
dockerBuildOptions = fmt.Sprintf(`-t %s`, dockerTag)
|
||||
}
|
||||
if in.Extra != "" {
|
||||
dockerBuildOptions = fmt.Sprintf(`%s %s`, dockerBuildOptions, in.Extra)
|
||||
}
|
||||
err = gproc.ShellRun(fmt.Sprintf(`docker build -f %s . %s`, in.File, dockerBuildOptions))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Docker push.
|
||||
if in.Tag == "" || !in.Push {
|
||||
if !in.Push {
|
||||
return
|
||||
}
|
||||
if err = gproc.ShellRun(fmt.Sprintf(`docker push %s`, in.Tag)); err != nil {
|
||||
return
|
||||
for _, dockerTag := range dockerTags {
|
||||
if dockerTag == "" {
|
||||
continue
|
||||
}
|
||||
err = gproc.ShellRun(fmt.Sprintf(`docker push %s`, dockerTag))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c cDocker) exeDockerShell(shellFilePath string) error {
|
||||
if gfile.ExtName(shellFilePath) == "sh" && runtime.GOOS == "windows" {
|
||||
mlog.Debugf(`ignore shell file "%s", as it cannot be run on windows system`, shellFilePath)
|
||||
return nil
|
||||
}
|
||||
return gproc.ShellRun(gfile.GetContents(shellFilePath))
|
||||
}
|
||||
|
||||
@ -20,22 +20,20 @@ import (
|
||||
"github.com/olekukonko/tablewriter"
|
||||
|
||||
_ "github.com/gogf/gf/contrib/drivers/mssql/v2"
|
||||
_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
|
||||
_ "github.com/gogf/gf/contrib/drivers/pgsql/v2"
|
||||
_ "github.com/gogf/gf/contrib/drivers/sqlite/v2"
|
||||
//_ "github.com/gogf/gf/contrib/drivers/sqlite/v2"
|
||||
//_ "github.com/gogf/gf/contrib/drivers/oracle/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultDaoPath = `service/internal/dao`
|
||||
defaultDoPath = `service/internal/do`
|
||||
defaultEntityPath = `model/entity`
|
||||
cGenDaoConfig = `gfcli.gen.dao`
|
||||
cGenDaoUsage = `gf gen dao [OPTION]`
|
||||
cGenDaoBrief = `automatically generate go files for dao/do/entity`
|
||||
cGenDaoEg = `
|
||||
cGenDaoConfig = `gfcli.gen.dao`
|
||||
cGenDaoUsage = `gf gen dao [OPTION]`
|
||||
cGenDaoBrief = `automatically generate go files for dao/do/entity`
|
||||
cGenDaoEg = `
|
||||
gf gen dao
|
||||
gf gen dao -l "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
|
||||
gf gen dao -p ./model -c config.yaml -g user-center -t user,user_detail,user_login
|
||||
gf gen dao -p ./model -g user-center -t user,user_detail,user_login
|
||||
gf gen dao -r user_
|
||||
`
|
||||
|
||||
@ -66,6 +64,9 @@ CONFIGURATION SUPPORT
|
||||
cGenDaoBriefWithTime = `add created time for auto produced go files`
|
||||
cGenDaoBriefGJsonSupport = `use gJsonSupport to use *gjson.Json instead of string for generated json fields of tables`
|
||||
cGenDaoBriefImportPrefix = `custom import prefix for generated go files`
|
||||
cGenDaoBriefDaoPath = `directory path for storing generated dao files under path`
|
||||
cGenDaoBriefDoPath = `directory path for storing generated do files under path`
|
||||
cGenDaoBriefEntityPath = `directory path for storing generated entity files under path`
|
||||
cGenDaoBriefOverwriteDao = `overwrite all dao files both inside/outside internal folder`
|
||||
cGenDaoBriefModelFile = `custom file name for storing generated model content`
|
||||
cGenDaoBriefModelFileForDao = `custom file name generating model for DAO operations like Where/Data. It's empty in default`
|
||||
@ -120,6 +121,9 @@ func init() {
|
||||
`cGenDaoBriefRemovePrefix`: cGenDaoBriefRemovePrefix,
|
||||
`cGenDaoBriefStdTime`: cGenDaoBriefStdTime,
|
||||
`cGenDaoBriefWithTime`: cGenDaoBriefWithTime,
|
||||
`cGenDaoBriefDaoPath`: cGenDaoBriefDaoPath,
|
||||
`cGenDaoBriefDoPath`: cGenDaoBriefDoPath,
|
||||
`cGenDaoBriefEntityPath`: cGenDaoBriefEntityPath,
|
||||
`cGenDaoBriefGJsonSupport`: cGenDaoBriefGJsonSupport,
|
||||
`cGenDaoBriefImportPrefix`: cGenDaoBriefImportPrefix,
|
||||
`cGenDaoBriefOverwriteDao`: cGenDaoBriefOverwriteDao,
|
||||
@ -136,22 +140,25 @@ func init() {
|
||||
type (
|
||||
cGenDaoInput struct {
|
||||
g.Meta `name:"dao" config:"{cGenDaoConfig}" usage:"{cGenDaoUsage}" brief:"{cGenDaoBrief}" eg:"{cGenDaoEg}" ad:"{cGenDaoAd}"`
|
||||
Path string `name:"path" short:"p" brief:"{cGenDaoBriefPath}" d:"internal"`
|
||||
Link string `name:"link" short:"l" brief:"{cGenDaoBriefLink}"`
|
||||
Tables string `name:"tables" short:"t" brief:"{cGenDaoBriefTables}"`
|
||||
TablesEx string `name:"tablesEx" short:"e" brief:"{cGenDaoBriefTablesEx}"`
|
||||
Group string `name:"group" short:"g" brief:"{cGenDaoBriefGroup}" d:"default"`
|
||||
Prefix string `name:"prefix" short:"f" brief:"{cGenDaoBriefPrefix}"`
|
||||
RemovePrefix string `name:"removePrefix" short:"r" brief:"{cGenDaoBriefRemovePrefix}"`
|
||||
JsonCase string `name:"jsonCase" short:"j" brief:"{cGenDaoBriefJsonCase}" d:"CamelLower"`
|
||||
ImportPrefix string `name:"importPrefix" short:"i" brief:"{cGenDaoBriefImportPrefix}"`
|
||||
StdTime bool `name:"stdTime" short:"s" brief:"{cGenDaoBriefStdTime}" orphan:"true"`
|
||||
WithTime bool `name:"withTime" short:"c" brief:"{cGenDaoBriefWithTime}" orphan:"true"`
|
||||
GJsonSupport bool `name:"gJsonSupport" short:"n" brief:"{cGenDaoBriefGJsonSupport}" orphan:"true"`
|
||||
OverwriteDao bool `name:"overwriteDao" short:"o" brief:"{cGenDaoBriefOverwriteDao}" orphan:"true"`
|
||||
DescriptionTag bool `name:"descriptionTag" short:"d" brief:"{cGenDaoBriefDescriptionTag}" orphan:"true"`
|
||||
NoJsonTag bool `name:"noJsonTag" short:"k" brief:"{cGenDaoBriefNoJsonTag" orphan:"true"`
|
||||
NoModelComment bool `name:"noModelComment" short:"m" brief:"{cGenDaoBriefNoModelComment}" orphan:"true"`
|
||||
Path string `name:"path" short:"p" brief:"{cGenDaoBriefPath}" d:"internal"`
|
||||
Link string `name:"link" short:"l" brief:"{cGenDaoBriefLink}"`
|
||||
Tables string `name:"tables" short:"t" brief:"{cGenDaoBriefTables}"`
|
||||
TablesEx string `name:"tablesEx" short:"x" brief:"{cGenDaoBriefTablesEx}"`
|
||||
Group string `name:"group" short:"g" brief:"{cGenDaoBriefGroup}" d:"default"`
|
||||
Prefix string `name:"prefix" short:"f" brief:"{cGenDaoBriefPrefix}"`
|
||||
RemovePrefix string `name:"removePrefix" short:"r" brief:"{cGenDaoBriefRemovePrefix}"`
|
||||
JsonCase string `name:"jsonCase" short:"j" brief:"{cGenDaoBriefJsonCase}" d:"CamelLower"`
|
||||
ImportPrefix string `name:"importPrefix" short:"i" brief:"{cGenDaoBriefImportPrefix}"`
|
||||
DaoPath string `name:"daoPath" short:"d" brief:"{cGenDaoBriefDaoPath}" d:"dao"`
|
||||
DoPath string `name:"doPath" short:"o" brief:"{cGenDaoBriefDoPath}" d:"model/do"`
|
||||
EntityPath string `name:"entityPath" short:"e" brief:"{cGenDaoBriefEntityPath}" d:"model/entity"`
|
||||
StdTime bool `name:"stdTime" short:"s" brief:"{cGenDaoBriefStdTime}" orphan:"true"`
|
||||
WithTime bool `name:"withTime" short:"w" brief:"{cGenDaoBriefWithTime}" orphan:"true"`
|
||||
GJsonSupport bool `name:"gJsonSupport" short:"n" brief:"{cGenDaoBriefGJsonSupport}" orphan:"true"`
|
||||
OverwriteDao bool `name:"overwriteDao" short:"v" brief:"{cGenDaoBriefOverwriteDao}" orphan:"true"`
|
||||
DescriptionTag bool `name:"descriptionTag" short:"c" brief:"{cGenDaoBriefDescriptionTag}" orphan:"true"`
|
||||
NoJsonTag bool `name:"noJsonTag" short:"k" brief:"{cGenDaoBriefNoJsonTag" orphan:"true"`
|
||||
NoModelComment bool `name:"noModelComment" short:"m" brief:"{cGenDaoBriefNoModelComment}" orphan:"true"`
|
||||
}
|
||||
cGenDaoOutput struct{}
|
||||
|
||||
@ -295,7 +302,7 @@ func generateDao(ctx context.Context, db gdb.DB, in cGenDaoInternalInput) {
|
||||
}
|
||||
var (
|
||||
dirRealPath = gfile.RealPath(in.Path)
|
||||
dirPathDao = gfile.Join(in.Path, defaultDaoPath)
|
||||
dirPathDao = gfile.Join(in.Path, in.DaoPath)
|
||||
tableNameCamelCase = gstr.CaseCamel(in.NewTableName)
|
||||
tableNameCamelLowerCase = gstr.CaseCamelLower(in.NewTableName)
|
||||
tableNameSnakeCase = gstr.CaseSnake(in.NewTableName)
|
||||
@ -310,8 +317,10 @@ func generateDao(ctx context.Context, db gdb.DB, in cGenDaoInternalInput) {
|
||||
importPrefix = gstr.Replace(dirRealPath, gfile.Pwd(), "")
|
||||
}
|
||||
importPrefix = gstr.Replace(importPrefix, gfile.Separator, "/")
|
||||
importPrefix = gstr.Join(g.SliceStr{in.ModName, importPrefix, defaultDaoPath}, "/")
|
||||
importPrefix = gstr.Join(g.SliceStr{in.ModName, importPrefix, in.DaoPath}, "/")
|
||||
importPrefix, _ = gregex.ReplaceString(`\/{2,}`, `/`, gstr.Trim(importPrefix, "/"))
|
||||
} else {
|
||||
importPrefix = gstr.Join(g.SliceStr{importPrefix, in.DaoPath}, "/")
|
||||
}
|
||||
|
||||
fileName := gstr.Trim(tableNameSnakeCase, "-_.")
|
||||
@ -330,7 +339,7 @@ func generateDao(ctx context.Context, db gdb.DB, in cGenDaoInternalInput) {
|
||||
|
||||
func generateDo(ctx context.Context, db gdb.DB, tableNames, newTableNames []string, in cGenDaoInternalInput) {
|
||||
var (
|
||||
doDirPath = gfile.Join(in.Path, defaultDoPath)
|
||||
doDirPath = gfile.Join(in.Path, in.DoPath)
|
||||
)
|
||||
in.NoJsonTag = true
|
||||
in.DescriptionTag = false
|
||||
@ -382,7 +391,7 @@ func generateDo(ctx context.Context, db gdb.DB, tableNames, newTableNames []stri
|
||||
|
||||
func generateEntity(ctx context.Context, db gdb.DB, tableNames, newTableNames []string, in cGenDaoInternalInput) {
|
||||
var (
|
||||
entityDirPath = gfile.Join(in.Path, defaultEntityPath)
|
||||
entityDirPath = gfile.Join(in.Path, in.EntityPath)
|
||||
)
|
||||
|
||||
// Model content.
|
||||
|
||||
318
cmd/gf/internal/cmd/cmd_gen_service.go
Normal file
318
cmd/gf/internal/cmd/cmd_gen_service.go
Normal file
@ -0,0 +1,318 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/consts"
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/utils"
|
||||
"github.com/gogf/gf/v2/container/garray"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
type (
|
||||
cGenServiceInput struct {
|
||||
g.Meta `name:"service" config:"gfcli.gen.service" brief:"parse struct and associated functions from packages to generate service go file"`
|
||||
SrcFolder string `short:"s" name:"srcFolder" brief:"source folder path to be parsed. default: internal/logic" d:"internal/logic"`
|
||||
DstFolder string `short:"d" name:"dstFolder" brief:"destination folder path storing automatically generated go files. default: internal/service" d:"internal/service"`
|
||||
WatchFile string `short:"w" name:"watchFile" brief:"used in file watcher, it generates service go files only if given file is under srcFolder"`
|
||||
StPattern string `short:"a" name:"stPattern" brief:"regular expression matching struct name for generating service. default: s([A-Z]\\w+)" d:"s([A-Z]\\w+)"`
|
||||
Packages string `short:"p" name:"packages" brief:"produce go files only for given source packages, multiple packages joined with char ','"`
|
||||
ImportPrefix string `short:"i" name:"importPrefix" brief:"custom import prefix to calculate import path for generated importing go file of logic"`
|
||||
OverWrite bool `short:"o" name:"overwrite" brief:"overwrite service go files that already exist in generating folder. default: true" d:"true" orphan:"true"`
|
||||
}
|
||||
cGenServiceOutput struct{}
|
||||
)
|
||||
|
||||
const (
|
||||
genServiceFileLockSeconds = 10
|
||||
)
|
||||
|
||||
func (c cGen) Service(ctx context.Context, in cGenServiceInput) (out *cGenServiceOutput, err error) {
|
||||
// File lock to avoid multiple processes.
|
||||
var (
|
||||
flockFilePath = gfile.Temp("gf.cli.gen.service.lock")
|
||||
flockContent = gfile.GetContents(flockFilePath)
|
||||
)
|
||||
if flockContent != "" {
|
||||
if gtime.Timestamp()-gconv.Int64(flockContent) < genServiceFileLockSeconds {
|
||||
// If another "gen service" process is running, it just exits.
|
||||
mlog.Debug(`another "gen service" process is running, exit`)
|
||||
return
|
||||
}
|
||||
}
|
||||
defer gfile.Remove(flockFilePath)
|
||||
_ = gfile.PutContents(flockFilePath, gtime.TimestampStr())
|
||||
|
||||
in.SrcFolder = gstr.TrimRight(in.SrcFolder, `\/`)
|
||||
in.SrcFolder = gstr.Replace(in.SrcFolder, "\\", "/")
|
||||
in.WatchFile = gstr.TrimRight(in.WatchFile, `\/`)
|
||||
in.WatchFile = gstr.Replace(in.WatchFile, "\\", "/")
|
||||
|
||||
// Watch file handling.
|
||||
if in.WatchFile != "" {
|
||||
// It works only if given WatchFile is in SrcFolder.
|
||||
var (
|
||||
watchFileDir = gfile.Dir(in.WatchFile)
|
||||
srcFolderDir = gfile.Dir(watchFileDir)
|
||||
)
|
||||
mlog.Debug("watchFileDir:", watchFileDir)
|
||||
mlog.Debug("logicFolderDir:", srcFolderDir)
|
||||
if !gstr.HasSuffix(srcFolderDir, in.SrcFolder) {
|
||||
mlog.Printf(`ignore watch file "%s", not in source path "%s"`, in.WatchFile, in.SrcFolder)
|
||||
return
|
||||
}
|
||||
var newWorkingDir = gfile.Dir(gfile.Dir(srcFolderDir))
|
||||
if err = gfile.Chdir(newWorkingDir); err != nil {
|
||||
mlog.Fatalf(`%+v`, err)
|
||||
}
|
||||
mlog.Debug("Chdir:", newWorkingDir)
|
||||
_ = gfile.Remove(flockFilePath)
|
||||
var command = fmt.Sprintf(
|
||||
`%s gen service -packages=%s`,
|
||||
gfile.SelfName(), gfile.Basename(watchFileDir),
|
||||
)
|
||||
err = gproc.ShellRun(command)
|
||||
return
|
||||
}
|
||||
|
||||
if !gfile.Exists(in.SrcFolder) {
|
||||
mlog.Fatalf(`source folder path "%s" does not exist`, in.SrcFolder)
|
||||
}
|
||||
|
||||
if in.ImportPrefix == "" {
|
||||
if !gfile.Exists("go.mod") {
|
||||
mlog.Fatal("ImportPrefix is empty and go.mod does not exist in current working directory")
|
||||
}
|
||||
var (
|
||||
goModContent = gfile.GetContents("go.mod")
|
||||
match, _ = gregex.MatchString(`^module\s+(.+)\s*`, goModContent)
|
||||
)
|
||||
if len(match) > 1 {
|
||||
in.ImportPrefix = fmt.Sprintf(`%s/%s`, gstr.Trim(match[1]), gstr.Replace(in.SrcFolder, `\`, `/`))
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
isDirty bool
|
||||
files []string
|
||||
fileContent string
|
||||
matches [][]string
|
||||
importSrcPackages []string
|
||||
inputPackages = gstr.SplitAndTrim(in.Packages, ",")
|
||||
dstPackageName = gstr.ToLower(gfile.Basename(in.DstFolder))
|
||||
)
|
||||
srcFolders, err := gfile.ScanDir(in.SrcFolder, "*", false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, srcFolder := range srcFolders {
|
||||
if !gfile.IsDir(srcFolder) {
|
||||
continue
|
||||
}
|
||||
if files, err = gfile.ScanDir(srcFolder, "*.go", false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(files) == 0 {
|
||||
continue
|
||||
}
|
||||
var (
|
||||
// StructName => FunctionDefinitions
|
||||
srcPkgInterfaceMap = make(map[string]*garray.StrArray)
|
||||
srcPkgInterfaceFuncArray *garray.StrArray
|
||||
ok bool
|
||||
)
|
||||
for _, file := range files {
|
||||
fileContent = gfile.GetContents(file)
|
||||
matches, err = gregex.MatchAllString(`func \((.+?)\) ([\s\S]+?) {`, fileContent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, match := range matches {
|
||||
var (
|
||||
structName string
|
||||
structMatch []string
|
||||
funcReceiver = gstr.Trim(match[1])
|
||||
receiverArray = gstr.SplitAndTrim(funcReceiver, " ")
|
||||
functionHead = gstr.Trim(gstr.Replace(match[2], "\n", ""))
|
||||
)
|
||||
if len(receiverArray) > 1 {
|
||||
structName = receiverArray[1]
|
||||
} else {
|
||||
structName = receiverArray[0]
|
||||
}
|
||||
structName = gstr.Trim(structName, "*")
|
||||
|
||||
// Xxx(\n ctx context.Context, req *v1.XxxReq,\n) -> Xxx(ctx context.Context, req *v1.XxxReq)
|
||||
functionHead = gstr.Replace(functionHead, `,)`, `)`)
|
||||
functionHead, _ = gregex.ReplaceString(`\(\s+`, `(`, functionHead)
|
||||
functionHead, _ = gregex.ReplaceString(`\s{2,}`, ` `, functionHead)
|
||||
if !gstr.IsLetterUpper(functionHead[0]) {
|
||||
continue
|
||||
}
|
||||
if structMatch, err = gregex.MatchString(in.StPattern, structName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(structMatch) < 1 {
|
||||
continue
|
||||
}
|
||||
structName = gstr.CaseCamel(structMatch[1])
|
||||
if srcPkgInterfaceFuncArray, ok = srcPkgInterfaceMap[structName]; !ok {
|
||||
srcPkgInterfaceMap[structName] = garray.NewStrArray()
|
||||
srcPkgInterfaceFuncArray = srcPkgInterfaceMap[structName]
|
||||
}
|
||||
// Remove package name calls of `dstPackageName` in produced codes.
|
||||
functionHead, _ = gregex.ReplaceString(fmt.Sprintf(`\*{0,1}%s\.`, dstPackageName), ``, functionHead)
|
||||
srcPkgInterfaceFuncArray.Append(functionHead)
|
||||
}
|
||||
}
|
||||
importSrcPackages = append(
|
||||
importSrcPackages,
|
||||
fmt.Sprintf(`%s/%s`, in.ImportPrefix, gfile.Basename(srcFolder)),
|
||||
)
|
||||
// Ignore source packages if input packages given.
|
||||
if len(inputPackages) > 0 && !gstr.InArray(inputPackages, gfile.Basename(srcFolder)) {
|
||||
mlog.Debugf(
|
||||
`ignore source package "%s" as it is not in desired packages: %+v`,
|
||||
gfile.Basename(srcFolder), inputPackages,
|
||||
)
|
||||
continue
|
||||
}
|
||||
// Generating go files for service.
|
||||
if ok, err = c.generateServiceFiles(in, srcPkgInterfaceMap, dstPackageName); err != nil {
|
||||
return
|
||||
}
|
||||
if ok {
|
||||
isDirty = true
|
||||
}
|
||||
}
|
||||
|
||||
if isDirty {
|
||||
// Generate initialization go file.
|
||||
if len(importSrcPackages) > 0 {
|
||||
if err = c.generateInitializationFile(in, importSrcPackages); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Go imports updating.
|
||||
mlog.Printf(`goimports go files in "%s", it may take seconds...`, in.DstFolder)
|
||||
utils.GoImports(in.DstFolder)
|
||||
|
||||
// Replica v1 to v2 for GoFrame.
|
||||
if err = c.replaceGeneratedServiceContentGFV2(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mlog.Printf(`gofmt go files in "%s"`, in.DstFolder)
|
||||
utils.GoFmt(in.DstFolder)
|
||||
}
|
||||
|
||||
mlog.Print(`done!`)
|
||||
return
|
||||
}
|
||||
|
||||
func (c cGen) generateServiceFiles(
|
||||
in cGenServiceInput, srcPkgInterfaceMap map[string]*garray.StrArray, dstPackageName string,
|
||||
) (ok bool, err error) {
|
||||
for structName, funcArray := range srcPkgInterfaceMap {
|
||||
var (
|
||||
filePath = gfile.Join(in.DstFolder, gstr.ToLower(structName)+".go")
|
||||
generatedContent = gstr.ReplaceByMap(consts.TemplateGenServiceContent, g.MapStrStr{
|
||||
"{StructName}": structName,
|
||||
"{PackageName}": dstPackageName,
|
||||
"{FuncDefinition}": funcArray.Join("\n\t"),
|
||||
})
|
||||
)
|
||||
if gfile.Exists(filePath) {
|
||||
if !in.OverWrite {
|
||||
mlog.Printf(`not overwrite, ignore generating service go file: %s`, filePath)
|
||||
continue
|
||||
}
|
||||
if !c.isToGenerateServiceGoFile(filePath, funcArray) {
|
||||
mlog.Printf(`not dirty, ignore generating service go file: %s`, filePath)
|
||||
continue
|
||||
}
|
||||
}
|
||||
ok = true
|
||||
mlog.Printf(`generating service go file: %s`, filePath)
|
||||
if err = gfile.PutContents(filePath, generatedContent); err != nil {
|
||||
return ok, err
|
||||
}
|
||||
}
|
||||
return ok, nil
|
||||
}
|
||||
|
||||
// isToGenerateServiceGoFile checks and returns whether the service content dirty.
|
||||
func (c cGen) isToGenerateServiceGoFile(filePath string, funcArray *garray.StrArray) bool {
|
||||
if !utils.IsFileDoNotEdit(filePath) {
|
||||
mlog.Debugf(`ignore file as it is manually maintained: %s`, filePath)
|
||||
return false
|
||||
}
|
||||
var (
|
||||
fileContent = gfile.GetContents(filePath)
|
||||
generatedFuncArray = garray.NewSortedStrArrayFrom(funcArray.Slice())
|
||||
contentFuncArray = garray.NewSortedStrArray()
|
||||
)
|
||||
if fileContent == "" {
|
||||
return true
|
||||
}
|
||||
match, _ := gregex.MatchString(`interface\s+{([\s\S]+?)}`, fileContent)
|
||||
if len(match) != 2 {
|
||||
return false
|
||||
}
|
||||
contentFuncArray.Append(gstr.SplitAndTrim(match[1], "\n")...)
|
||||
if generatedFuncArray.Len() != contentFuncArray.Len() {
|
||||
return true
|
||||
}
|
||||
for i := 0; i < generatedFuncArray.Len(); i++ {
|
||||
if generatedFuncArray.At(i) != contentFuncArray.At(i) {
|
||||
mlog.Debugf(`dirty, %s != %s`, generatedFuncArray.At(i), contentFuncArray.At(i))
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c cGen) generateInitializationFile(in cGenServiceInput, importSrcPackages []string) (err error) {
|
||||
var (
|
||||
srcPackageName = gstr.ToLower(gfile.Basename(in.SrcFolder))
|
||||
srcFilePath = gfile.Join(in.SrcFolder, srcPackageName+".go")
|
||||
srcImports string
|
||||
generatedContent string
|
||||
)
|
||||
if !utils.IsFileDoNotEdit(srcFilePath) {
|
||||
mlog.Debugf(`ignore file as it is manually maintained: %s`, srcFilePath)
|
||||
return nil
|
||||
}
|
||||
for _, importSrcPackage := range importSrcPackages {
|
||||
srcImports += fmt.Sprintf(`%s_ "%s"%s`, "\t", importSrcPackage, "\n")
|
||||
}
|
||||
generatedContent = gstr.ReplaceByMap(consts.TemplateGenServiceLogicContent, g.MapStrStr{
|
||||
"{PackageName}": srcPackageName,
|
||||
"{Imports}": srcImports,
|
||||
})
|
||||
mlog.Printf(`generating init go file: %s`, srcFilePath)
|
||||
if err = gfile.PutContents(srcFilePath, generatedContent); err != nil {
|
||||
return err
|
||||
}
|
||||
utils.GoFmt(srcFilePath)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c cGen) replaceGeneratedServiceContentGFV2(in cGenServiceInput) (err error) {
|
||||
return gfile.ReplaceDirFunc(func(path, content string) string {
|
||||
if gstr.Contains(content, `"github.com/gogf/gf`) && !gstr.Contains(content, `"github.com/gogf/gf/v2`) {
|
||||
content = gstr.Replace(content, `"github.com/gogf/gf"`, `"github.com/gogf/gf/v2"`)
|
||||
content = gstr.Replace(content, `"github.com/gogf/gf/`, `"github.com/gogf/gf/v2/`)
|
||||
return content
|
||||
}
|
||||
return content
|
||||
}, in.DstFolder, "*.go", false)
|
||||
}
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/os/gtimer"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gtag"
|
||||
)
|
||||
|
||||
@ -149,9 +150,9 @@ func (app *cRunApp) Run() {
|
||||
if runtime.GOOS == "windows" {
|
||||
// Special handling for windows platform.
|
||||
// DO NOT USE "cmd /c" command.
|
||||
process = gproc.NewProcess(runCommand, nil)
|
||||
process = gproc.NewProcess(outputPath, gstr.SplitAndTrim(" ", app.Args))
|
||||
} else {
|
||||
process = gproc.NewProcessCmd(runCommand, nil)
|
||||
process = gproc.NewProcessCmd(outputPath, gstr.SplitAndTrim(" ", app.Args))
|
||||
}
|
||||
if pid, err := process.Start(); err != nil {
|
||||
mlog.Printf("build running error: %s", err.Error())
|
||||
|
||||
@ -1 +1,7 @@
|
||||
package consts
|
||||
|
||||
const (
|
||||
// DoNotEditKey is used in generated files,
|
||||
// which marks the files will be overwritten by CLI tool.
|
||||
DoNotEditKey = `DO NOT EDIT`
|
||||
)
|
||||
|
||||
@ -11,10 +11,13 @@ import (
|
||||
"{TplImportPrefix}/internal"
|
||||
)
|
||||
|
||||
// internal{TplTableNameCamelCase}Dao is internal type for wrapping internal DAO implements.
|
||||
type internal{TplTableNameCamelCase}Dao = *internal.{TplTableNameCamelCase}Dao
|
||||
|
||||
// {TplTableNameCamelLowerCase}Dao is the data access object for table {TplTableName}.
|
||||
// You can define custom methods on it to extend its functionality as you wish.
|
||||
type {TplTableNameCamelLowerCase}Dao struct {
|
||||
*internal.{TplTableNameCamelCase}Dao
|
||||
internal{TplTableNameCamelCase}Dao
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
26
cmd/gf/internal/consts/consts_gen_service_template.go
Normal file
26
cmd/gf/internal/consts/consts_gen_service_template.go
Normal file
@ -0,0 +1,26 @@
|
||||
package consts
|
||||
|
||||
const TemplateGenServiceContent = `
|
||||
// ==========================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package {PackageName}
|
||||
|
||||
type I{StructName} interface {
|
||||
{FuncDefinition}
|
||||
}
|
||||
|
||||
var local{StructName} I{StructName}
|
||||
|
||||
func {StructName}() I{StructName} {
|
||||
if local{StructName} == nil {
|
||||
panic("implement not found for interface I{StructName}, forgot register?")
|
||||
}
|
||||
return local{StructName}
|
||||
}
|
||||
|
||||
func Register{StructName}(i I{StructName}) {
|
||||
local{StructName} = i
|
||||
}
|
||||
`
|
||||
13
cmd/gf/internal/consts/consts_gen_service_template_logic.go
Normal file
13
cmd/gf/internal/consts/consts_gen_service_template_logic.go
Normal file
@ -0,0 +1,13 @@
|
||||
package consts
|
||||
|
||||
const TemplateGenServiceLogicContent = `
|
||||
// ==========================================================================
|
||||
// Code generated by GoFrame CLI tool. DO NOT EDIT.
|
||||
// ==========================================================================
|
||||
|
||||
package {PackageName}
|
||||
|
||||
import(
|
||||
{Imports}
|
||||
)
|
||||
`
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -2,17 +2,57 @@ package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/consts"
|
||||
"github.com/gogf/gf/cmd/gf/v2/internal/utility/mlog"
|
||||
"github.com/gogf/gf/v2/os/gfile"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
)
|
||||
|
||||
var (
|
||||
// gofmtPath is the binary path of command `gofmt`.
|
||||
gofmtPath = gproc.SearchBinaryPath("gofmt")
|
||||
gofmtPath = gproc.SearchBinaryPath("gofmt") // gofmtPath is the binary path of command `gofmt`.
|
||||
goimportsPath = gproc.SearchBinaryPath("goimports") // gofmtPath is the binary path of command `goimports`.
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Wraps the command binary path with char '"' if there's space char in the path.
|
||||
if gstr.Contains(gofmtPath, " ") {
|
||||
gofmtPath = fmt.Sprintf(`"%s"`, gofmtPath)
|
||||
}
|
||||
if gstr.Contains(goimportsPath, " ") {
|
||||
goimportsPath = fmt.Sprintf(`"%s"`, goimportsPath)
|
||||
}
|
||||
}
|
||||
|
||||
// GoFmt formats the source file using command `gofmt -w -s PATH`.
|
||||
func GoFmt(path string) {
|
||||
if gofmtPath != "" {
|
||||
gproc.ShellExec(fmt.Sprintf(`%s -w -s %s`, gofmtPath, path))
|
||||
if gofmtPath == "" {
|
||||
mlog.Fatal(`command "gofmt" not found`)
|
||||
}
|
||||
var command = fmt.Sprintf(`%s -w %s`, gofmtPath, path)
|
||||
result, err := gproc.ShellExec(command)
|
||||
if err != nil {
|
||||
mlog.Fatalf(`error executing command "%s": %s`, command, result)
|
||||
}
|
||||
}
|
||||
|
||||
// GoImports formats the source file using command `goimports -w PATH`.
|
||||
func GoImports(path string) {
|
||||
if goimportsPath == "" {
|
||||
mlog.Fatal(`command "goimports" not found`)
|
||||
}
|
||||
var command = fmt.Sprintf(`%s -w %s`, goimportsPath, path)
|
||||
result, err := gproc.ShellExec(command)
|
||||
if err != nil {
|
||||
mlog.Fatalf(`error executing command "%s": %s`, command, result)
|
||||
}
|
||||
}
|
||||
|
||||
// IsFileDoNotEdit checks and returns whether file contains `do not edit` key.
|
||||
func IsFileDoNotEdit(filePath string) bool {
|
||||
if !gfile.Exists(filePath) {
|
||||
return true
|
||||
}
|
||||
return gstr.Contains(gfile.GetContents(filePath), consts.DoNotEditKey)
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/internal/deepcopy"
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/rwmutex"
|
||||
@ -503,16 +504,25 @@ func (a *Array) Search(value interface{}) int {
|
||||
// Example: [1,1,2,3,2] -> [1,2,3]
|
||||
func (a *Array) Unique() *Array {
|
||||
a.mu.Lock()
|
||||
for i := 0; i < len(a.array)-1; i++ {
|
||||
for j := i + 1; j < len(a.array); {
|
||||
if a.array[i] == a.array[j] {
|
||||
a.array = append(a.array[:j], a.array[j+1:]...)
|
||||
} else {
|
||||
j++
|
||||
}
|
||||
}
|
||||
defer a.mu.Unlock()
|
||||
if len(a.array) == 0 {
|
||||
return a
|
||||
}
|
||||
a.mu.Unlock()
|
||||
var (
|
||||
ok bool
|
||||
temp interface{}
|
||||
uniqueSet = make(map[interface{}]struct{})
|
||||
uniqueArray = make([]interface{}, 0, len(a.array))
|
||||
)
|
||||
for i := 0; i < len(a.array); i++ {
|
||||
temp = a.array[i]
|
||||
if _, ok = uniqueSet[temp]; ok {
|
||||
continue
|
||||
}
|
||||
uniqueSet[temp] = struct{}{}
|
||||
uniqueArray = append(uniqueArray, temp)
|
||||
}
|
||||
a.array = uniqueArray
|
||||
return a
|
||||
}
|
||||
|
||||
@ -711,6 +721,9 @@ func (a *Array) IteratorDesc(f func(k int, v interface{}) bool) {
|
||||
|
||||
// String returns current array as a string, which implements like json.Marshal does.
|
||||
func (a *Array) String() string {
|
||||
if a == nil {
|
||||
return ""
|
||||
}
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
@ -808,3 +821,14 @@ func (a *Array) Walk(f func(value interface{}) interface{}) *Array {
|
||||
func (a *Array) IsEmpty() bool {
|
||||
return a.Len() == 0
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (a *Array) DeepCopy() interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
newSlice := make([]interface{}, len(a.array))
|
||||
for i, v := range a.array {
|
||||
newSlice[i] = deepcopy.Copy(v)
|
||||
}
|
||||
return NewArrayFrom(newSlice, a.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -514,16 +514,25 @@ func (a *IntArray) Search(value int) int {
|
||||
// Example: [1,1,2,3,2] -> [1,2,3]
|
||||
func (a *IntArray) Unique() *IntArray {
|
||||
a.mu.Lock()
|
||||
for i := 0; i < len(a.array)-1; i++ {
|
||||
for j := i + 1; j < len(a.array); {
|
||||
if a.array[i] == a.array[j] {
|
||||
a.array = append(a.array[:j], a.array[j+1:]...)
|
||||
} else {
|
||||
j++
|
||||
}
|
||||
}
|
||||
defer a.mu.Unlock()
|
||||
if len(a.array) == 0 {
|
||||
return a
|
||||
}
|
||||
a.mu.Unlock()
|
||||
var (
|
||||
ok bool
|
||||
temp int
|
||||
uniqueSet = make(map[int]struct{})
|
||||
uniqueArray = make([]int, 0, len(a.array))
|
||||
)
|
||||
for i := 0; i < len(a.array); i++ {
|
||||
temp = a.array[i]
|
||||
if _, ok = uniqueSet[temp]; ok {
|
||||
continue
|
||||
}
|
||||
uniqueSet[temp] = struct{}{}
|
||||
uniqueArray = append(uniqueArray, temp)
|
||||
}
|
||||
a.array = uniqueArray
|
||||
return a
|
||||
}
|
||||
|
||||
@ -722,6 +731,9 @@ func (a *IntArray) IteratorDesc(f func(k int, v int) bool) {
|
||||
|
||||
// String returns current array as a string, which implements like json.Marshal does.
|
||||
func (a *IntArray) String() string {
|
||||
if a == nil {
|
||||
return ""
|
||||
}
|
||||
return "[" + a.Join(",") + "]"
|
||||
}
|
||||
|
||||
@ -787,3 +799,12 @@ func (a *IntArray) Walk(f func(value int) int) *IntArray {
|
||||
func (a *IntArray) IsEmpty() bool {
|
||||
return a.Len() == 0
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (a *IntArray) DeepCopy() interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
newSlice := make([]int, len(a.array))
|
||||
copy(newSlice, a.array)
|
||||
return NewIntArrayFrom(newSlice, a.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -516,16 +516,25 @@ func (a *StrArray) Search(value string) int {
|
||||
// Example: [1,1,2,3,2] -> [1,2,3]
|
||||
func (a *StrArray) Unique() *StrArray {
|
||||
a.mu.Lock()
|
||||
for i := 0; i < len(a.array)-1; i++ {
|
||||
for j := i + 1; j < len(a.array); {
|
||||
if a.array[i] == a.array[j] {
|
||||
a.array = append(a.array[:j], a.array[j+1:]...)
|
||||
} else {
|
||||
j++
|
||||
}
|
||||
}
|
||||
defer a.mu.Unlock()
|
||||
if len(a.array) == 0 {
|
||||
return a
|
||||
}
|
||||
a.mu.Unlock()
|
||||
var (
|
||||
ok bool
|
||||
temp string
|
||||
uniqueSet = make(map[string]struct{})
|
||||
uniqueArray = make([]string, 0, len(a.array))
|
||||
)
|
||||
for i := 0; i < len(a.array); i++ {
|
||||
temp = a.array[i]
|
||||
if _, ok = uniqueSet[temp]; ok {
|
||||
continue
|
||||
}
|
||||
uniqueSet[temp] = struct{}{}
|
||||
uniqueArray = append(uniqueArray, temp)
|
||||
}
|
||||
a.array = uniqueArray
|
||||
return a
|
||||
}
|
||||
|
||||
@ -724,6 +733,9 @@ func (a *StrArray) IteratorDesc(f func(k int, v string) bool) {
|
||||
|
||||
// String returns current array as a string, which implements like json.Marshal does.
|
||||
func (a *StrArray) String() string {
|
||||
if a == nil {
|
||||
return ""
|
||||
}
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
@ -800,3 +812,12 @@ func (a *StrArray) Walk(f func(value string) string) *StrArray {
|
||||
func (a *StrArray) IsEmpty() bool {
|
||||
return a.Len() == 0
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (a *StrArray) DeepCopy() interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
newSlice := make([]string, len(a.array))
|
||||
copy(newSlice, a.array)
|
||||
return NewStrArrayFrom(newSlice, a.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/deepcopy"
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/rwmutex"
|
||||
@ -36,9 +37,9 @@ type SortedArray struct {
|
||||
// NewSortedArray creates and returns an empty sorted array.
|
||||
// The parameter `safe` is used to specify whether using array in concurrent-safety, which is false in default.
|
||||
// The parameter `comparator` used to compare values to sort in array,
|
||||
// if it returns value < 0, means v1 < v2; the v1 will be inserted before v2;
|
||||
// if it returns value = 0, means v1 = v2; the v1 will be replaced by v2;
|
||||
// if it returns value > 0, means v1 > v2; the v1 will be inserted after v2;
|
||||
// if it returns value < 0, means `a` < `b`; the `a` will be inserted before `b`;
|
||||
// if it returns value = 0, means `a` = `b`; the `a` will be replaced by `b`;
|
||||
// if it returns value > 0, means `a` > `b`; the `a` will be inserted after `b`;
|
||||
func NewSortedArray(comparator func(a, b interface{}) int, safe ...bool) *SortedArray {
|
||||
return NewSortedArraySize(0, comparator, safe...)
|
||||
}
|
||||
@ -653,6 +654,9 @@ func (a *SortedArray) IteratorDesc(f func(k int, v interface{}) bool) {
|
||||
|
||||
// String returns current array as a string, which implements like json.Marshal does.
|
||||
func (a *SortedArray) String() string {
|
||||
if a == nil {
|
||||
return ""
|
||||
}
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
@ -793,3 +797,14 @@ func (a *SortedArray) getComparator() func(a, b interface{}) int {
|
||||
}
|
||||
return a.comparator
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (a *SortedArray) DeepCopy() interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
newSlice := make([]interface{}, len(a.array))
|
||||
for i, v := range a.array {
|
||||
newSlice[i] = deepcopy.Copy(v)
|
||||
}
|
||||
return NewSortedArrayFrom(newSlice, a.comparator, a.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -646,6 +646,9 @@ func (a *SortedIntArray) IteratorDesc(f func(k int, v int) bool) {
|
||||
|
||||
// String returns current array as a string, which implements like json.Marshal does.
|
||||
func (a *SortedIntArray) String() string {
|
||||
if a == nil {
|
||||
return ""
|
||||
}
|
||||
return "[" + a.Join(",") + "]"
|
||||
}
|
||||
|
||||
@ -741,3 +744,12 @@ func (a *SortedIntArray) getComparator() func(a, b int) int {
|
||||
}
|
||||
return a.comparator
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (a *SortedIntArray) DeepCopy() interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
newSlice := make([]int, len(a.array))
|
||||
copy(newSlice, a.array)
|
||||
return NewSortedIntArrayFrom(newSlice, a.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -648,6 +648,9 @@ func (a *SortedStrArray) IteratorDesc(f func(k int, v string) bool) {
|
||||
|
||||
// String returns current array as a string, which implements like json.Marshal does.
|
||||
func (a *SortedStrArray) String() string {
|
||||
if a == nil {
|
||||
return ""
|
||||
}
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
buffer := bytes.NewBuffer(nil)
|
||||
@ -754,3 +757,12 @@ func (a *SortedStrArray) getComparator() func(a, b string) int {
|
||||
}
|
||||
return a.comparator
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (a *SortedStrArray) DeepCopy() interface{} {
|
||||
a.mu.RLock()
|
||||
defer a.mu.RUnlock()
|
||||
newSlice := make([]string, len(a.array))
|
||||
copy(newSlice, a.array)
|
||||
return NewSortedStrArrayFrom(newSlice, a.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -576,7 +576,7 @@ func TestArray_Json(t *testing.T) {
|
||||
|
||||
var a3 garray.Array
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Slice(), s1)
|
||||
})
|
||||
// value.
|
||||
@ -595,7 +595,7 @@ func TestArray_Json(t *testing.T) {
|
||||
|
||||
var a3 garray.Array
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Slice(), s1)
|
||||
})
|
||||
// pointer
|
||||
@ -609,11 +609,11 @@ func TestArray_Json(t *testing.T) {
|
||||
"Scores": []int{99, 100, 98},
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
user := new(User)
|
||||
err = json.UnmarshalUseNumber(b, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Name, data["Name"])
|
||||
t.Assert(user.Scores, data["Scores"])
|
||||
})
|
||||
@ -628,11 +628,11 @@ func TestArray_Json(t *testing.T) {
|
||||
"Scores": []int{99, 100, 98},
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
user := new(User)
|
||||
err = json.UnmarshalUseNumber(b, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Name, data["Name"])
|
||||
t.Assert(user.Scores, data["Scores"])
|
||||
})
|
||||
@ -720,7 +720,7 @@ func TestArray_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"array": g.Slice{1, 2, 3},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
|
||||
})
|
||||
|
||||
@ -619,7 +619,7 @@ func TestIntArray_Json(t *testing.T) {
|
||||
|
||||
var a3 garray.IntArray
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Slice(), s1)
|
||||
})
|
||||
// array value
|
||||
@ -637,7 +637,7 @@ func TestIntArray_Json(t *testing.T) {
|
||||
|
||||
var a3 garray.IntArray
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Slice(), s1)
|
||||
})
|
||||
// array pointer
|
||||
@ -651,11 +651,11 @@ func TestIntArray_Json(t *testing.T) {
|
||||
"Scores": []int{99, 100, 98},
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
user := new(User)
|
||||
err = json.UnmarshalUseNumber(b, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Name, data["Name"])
|
||||
t.Assert(user.Scores, data["Scores"])
|
||||
})
|
||||
@ -670,11 +670,11 @@ func TestIntArray_Json(t *testing.T) {
|
||||
"Scores": []int{99, 100, 98},
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
user := new(User)
|
||||
err = json.UnmarshalUseNumber(b, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Name, data["Name"])
|
||||
t.Assert(user.Scores, data["Scores"])
|
||||
})
|
||||
@ -752,7 +752,7 @@ func TestIntArray_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"array": []byte(`[1,2,3]`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
|
||||
})
|
||||
@ -763,7 +763,7 @@ func TestIntArray_UnmarshalValue(t *testing.T) {
|
||||
// "name": "john",
|
||||
// "array": g.Slice{1, 2, 3},
|
||||
// }, &v)
|
||||
// t.Assert(err, nil)
|
||||
// t.AssertNil(err)
|
||||
// t.Assert(v.Name, "john")
|
||||
// t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
|
||||
// })
|
||||
|
||||
@ -619,7 +619,7 @@ func TestStrArray_Json(t *testing.T) {
|
||||
|
||||
var a3 garray.StrArray
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Slice(), s1)
|
||||
})
|
||||
// array value
|
||||
@ -637,7 +637,7 @@ func TestStrArray_Json(t *testing.T) {
|
||||
|
||||
var a3 garray.StrArray
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Slice(), s1)
|
||||
})
|
||||
// array pointer
|
||||
@ -651,11 +651,11 @@ func TestStrArray_Json(t *testing.T) {
|
||||
"Scores": []string{"A+", "A", "A"},
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
user := new(User)
|
||||
err = json.UnmarshalUseNumber(b, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Name, data["Name"])
|
||||
t.Assert(user.Scores, data["Scores"])
|
||||
})
|
||||
@ -670,11 +670,11 @@ func TestStrArray_Json(t *testing.T) {
|
||||
"Scores": []string{"A+", "A", "A"},
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
user := new(User)
|
||||
err = json.UnmarshalUseNumber(b, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Name, data["Name"])
|
||||
t.Assert(user.Scores, data["Scores"])
|
||||
})
|
||||
@ -751,7 +751,7 @@ func TestStrArray_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"array": []byte(`["1","2","3"]`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Array.Slice(), g.SliceStr{"1", "2", "3"})
|
||||
})
|
||||
@ -762,7 +762,7 @@ func TestStrArray_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"array": g.SliceStr{"1", "2", "3"},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Array.Slice(), g.SliceStr{"1", "2", "3"})
|
||||
})
|
||||
|
||||
@ -661,7 +661,7 @@ func TestSortedArray_Json(t *testing.T) {
|
||||
|
||||
var a3 garray.SortedArray
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Slice(), s1)
|
||||
t.Assert(a3.Interfaces(), s1)
|
||||
})
|
||||
@ -681,7 +681,7 @@ func TestSortedArray_Json(t *testing.T) {
|
||||
|
||||
var a3 garray.SortedArray
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Slice(), s1)
|
||||
t.Assert(a3.Interfaces(), s1)
|
||||
})
|
||||
@ -696,11 +696,11 @@ func TestSortedArray_Json(t *testing.T) {
|
||||
"Scores": []int{99, 100, 98},
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
user := new(User)
|
||||
err = json.UnmarshalUseNumber(b, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Name, data["Name"])
|
||||
t.AssertNE(user.Scores, nil)
|
||||
t.Assert(user.Scores.Len(), 3)
|
||||
@ -732,11 +732,11 @@ func TestSortedArray_Json(t *testing.T) {
|
||||
"Scores": []int{99, 100, 98},
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
user := new(User)
|
||||
err = json.UnmarshalUseNumber(b, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Name, data["Name"])
|
||||
t.AssertNE(user.Scores, nil)
|
||||
t.Assert(user.Scores.Len(), 3)
|
||||
@ -830,7 +830,7 @@ func TestSortedArray_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"array": []byte(`[2,3,1]`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
|
||||
})
|
||||
@ -841,7 +841,7 @@ func TestSortedArray_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"array": g.Slice{2, 3, 1},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
|
||||
})
|
||||
|
||||
@ -561,7 +561,7 @@ func TestSortedIntArray_Json(t *testing.T) {
|
||||
|
||||
var a3 garray.SortedIntArray
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Slice(), s1)
|
||||
})
|
||||
// array value
|
||||
@ -580,7 +580,7 @@ func TestSortedIntArray_Json(t *testing.T) {
|
||||
|
||||
var a3 garray.SortedIntArray
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Slice(), s1)
|
||||
})
|
||||
// array pointer
|
||||
@ -594,11 +594,11 @@ func TestSortedIntArray_Json(t *testing.T) {
|
||||
"Scores": []int{99, 100, 98},
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
user := new(User)
|
||||
err = json.UnmarshalUseNumber(b, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Name, data["Name"])
|
||||
t.Assert(user.Scores, []int{98, 99, 100})
|
||||
})
|
||||
@ -613,11 +613,11 @@ func TestSortedIntArray_Json(t *testing.T) {
|
||||
"Scores": []int{99, 100, 98},
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
user := new(User)
|
||||
err = json.UnmarshalUseNumber(b, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Name, data["Name"])
|
||||
t.Assert(user.Scores, []int{98, 99, 100})
|
||||
})
|
||||
@ -695,7 +695,7 @@ func TestSortedIntArray_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"array": []byte(`[2,3,1]`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
|
||||
})
|
||||
@ -706,7 +706,7 @@ func TestSortedIntArray_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"array": g.Slice{2, 3, 1},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Array.Slice(), g.Slice{1, 2, 3})
|
||||
})
|
||||
|
||||
@ -583,7 +583,7 @@ func TestSortedStrArray_Json(t *testing.T) {
|
||||
|
||||
var a3 garray.SortedStrArray
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Slice(), s1)
|
||||
t.Assert(a3.Interfaces(), s1)
|
||||
})
|
||||
@ -604,7 +604,7 @@ func TestSortedStrArray_Json(t *testing.T) {
|
||||
|
||||
var a3 garray.SortedStrArray
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Slice(), s1)
|
||||
t.Assert(a3.Interfaces(), s1)
|
||||
})
|
||||
@ -619,11 +619,11 @@ func TestSortedStrArray_Json(t *testing.T) {
|
||||
"Scores": []string{"A+", "A", "A"},
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
user := new(User)
|
||||
err = json.UnmarshalUseNumber(b, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Name, data["Name"])
|
||||
t.Assert(user.Scores, []string{"A", "A", "A+"})
|
||||
})
|
||||
@ -638,11 +638,11 @@ func TestSortedStrArray_Json(t *testing.T) {
|
||||
"Scores": []string{"A+", "A", "A"},
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
user := new(User)
|
||||
err = json.UnmarshalUseNumber(b, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Name, data["Name"])
|
||||
t.Assert(user.Scores, []string{"A", "A", "A+"})
|
||||
})
|
||||
@ -719,7 +719,7 @@ func TestSortedStrArray_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"array": []byte(`["1","3","2"]`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Array.Slice(), g.SliceStr{"1", "2", "3"})
|
||||
})
|
||||
@ -730,7 +730,7 @@ func TestSortedStrArray_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"array": g.SliceStr{"1", "3", "2"},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Array.Slice(), g.SliceStr{"1", "2", "3"})
|
||||
})
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"bytes"
|
||||
"container/list"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/deepcopy"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/rwmutex"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
@ -503,6 +504,9 @@ func (l *List) Join(glue string) string {
|
||||
|
||||
// String returns current list as a string.
|
||||
func (l *List) String() string {
|
||||
if l == nil {
|
||||
return ""
|
||||
}
|
||||
return "[" + l.Join(",") + "]"
|
||||
}
|
||||
|
||||
@ -543,3 +547,23 @@ func (l *List) UnmarshalValue(value interface{}) (err error) {
|
||||
l.PushBacks(array)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (l *List) DeepCopy() interface{} {
|
||||
l.mu.RLock()
|
||||
defer l.mu.RUnlock()
|
||||
|
||||
if l.list == nil {
|
||||
return nil
|
||||
}
|
||||
var (
|
||||
length = l.list.Len()
|
||||
values = make([]interface{}, length)
|
||||
)
|
||||
if length > 0 {
|
||||
for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
|
||||
values[i] = deepcopy.Copy(e.Value)
|
||||
}
|
||||
}
|
||||
return NewFrom(values, l.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -709,20 +709,20 @@ func TestList_Json(t *testing.T) {
|
||||
a := []interface{}{"a", "b", "c"}
|
||||
l := New()
|
||||
b, err := json.Marshal(a)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
err = json.UnmarshalUseNumber(b, l)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(l.FrontAll(), a)
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
var l List
|
||||
a := []interface{}{"a", "b", "c"}
|
||||
b, err := json.Marshal(a)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
err = json.UnmarshalUseNumber(b, &l)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(l.FrontAll(), a)
|
||||
})
|
||||
}
|
||||
@ -739,7 +739,7 @@ func TestList_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"list": []byte(`[1,2,3]`),
|
||||
}, &tlist)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(tlist.Name, "john")
|
||||
t.Assert(tlist.List.FrontAll(), []interface{}{1, 2, 3})
|
||||
})
|
||||
@ -750,7 +750,7 @@ func TestList_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"list": []interface{}{1, 2, 3},
|
||||
}, &tlist)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(tlist.Name, "john")
|
||||
t.Assert(tlist.List.FrontAll(), []interface{}{1, 2, 3})
|
||||
})
|
||||
|
||||
@ -8,6 +8,7 @@ package gmap
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
"github.com/gogf/gf/v2/internal/deepcopy"
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/rwmutex"
|
||||
@ -72,7 +73,7 @@ func (m *AnyAnyMap) Map() map[interface{}]interface{} {
|
||||
return data
|
||||
}
|
||||
|
||||
// MapCopy returns a copy of the underlying data of the hash map.
|
||||
// MapCopy returns a shallow copy of the underlying data of the hash map.
|
||||
func (m *AnyAnyMap) MapCopy() map[interface{}]interface{} {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
@ -456,6 +457,9 @@ func (m *AnyAnyMap) Merge(other *AnyAnyMap) {
|
||||
|
||||
// String returns the map as a string.
|
||||
func (m *AnyAnyMap) String() string {
|
||||
if m == nil {
|
||||
return ""
|
||||
}
|
||||
b, _ := m.MarshalJSON()
|
||||
return string(b)
|
||||
}
|
||||
@ -494,3 +498,14 @@ func (m *AnyAnyMap) UnmarshalValue(value interface{}) (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (m *AnyAnyMap) DeepCopy() interface{} {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
data := make(map[interface{}]interface{}, len(m.data))
|
||||
for k, v := range m.data {
|
||||
data[k] = deepcopy.Copy(v)
|
||||
}
|
||||
return NewFrom(data, m.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ package gmap
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
"github.com/gogf/gf/v2/internal/deepcopy"
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/rwmutex"
|
||||
@ -455,6 +456,9 @@ func (m *IntAnyMap) Merge(other *IntAnyMap) {
|
||||
|
||||
// String returns the map as a string.
|
||||
func (m *IntAnyMap) String() string {
|
||||
if m == nil {
|
||||
return ""
|
||||
}
|
||||
b, _ := m.MarshalJSON()
|
||||
return string(b)
|
||||
}
|
||||
@ -496,3 +500,14 @@ func (m *IntAnyMap) UnmarshalValue(value interface{}) (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (m *IntAnyMap) DeepCopy() interface{} {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
data := make(map[int]interface{}, len(m.data))
|
||||
for k, v := range m.data {
|
||||
data[k] = deepcopy.Copy(v)
|
||||
}
|
||||
return NewIntAnyMapFrom(data, m.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -426,6 +426,9 @@ func (m *IntIntMap) Merge(other *IntIntMap) {
|
||||
|
||||
// String returns the map as a string.
|
||||
func (m *IntIntMap) String() string {
|
||||
if m == nil {
|
||||
return ""
|
||||
}
|
||||
b, _ := m.MarshalJSON()
|
||||
return string(b)
|
||||
}
|
||||
@ -467,3 +470,14 @@ func (m *IntIntMap) UnmarshalValue(value interface{}) (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (m *IntIntMap) DeepCopy() interface{} {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
data := make(map[int]int, len(m.data))
|
||||
for k, v := range m.data {
|
||||
data[k] = v
|
||||
}
|
||||
return NewIntIntMapFrom(data, m.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -426,6 +426,9 @@ func (m *IntStrMap) Merge(other *IntStrMap) {
|
||||
|
||||
// String returns the map as a string.
|
||||
func (m *IntStrMap) String() string {
|
||||
if m == nil {
|
||||
return ""
|
||||
}
|
||||
b, _ := m.MarshalJSON()
|
||||
return string(b)
|
||||
}
|
||||
@ -467,3 +470,14 @@ func (m *IntStrMap) UnmarshalValue(value interface{}) (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (m *IntStrMap) DeepCopy() interface{} {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
data := make(map[int]string, len(m.data))
|
||||
for k, v := range m.data {
|
||||
data[k] = v
|
||||
}
|
||||
return NewIntStrMapFrom(data, m.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ package gmap
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
"github.com/gogf/gf/v2/internal/deepcopy"
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/rwmutex"
|
||||
@ -451,6 +452,9 @@ func (m *StrAnyMap) Merge(other *StrAnyMap) {
|
||||
|
||||
// String returns the map as a string.
|
||||
func (m *StrAnyMap) String() string {
|
||||
if m == nil {
|
||||
return ""
|
||||
}
|
||||
b, _ := m.MarshalJSON()
|
||||
return string(b)
|
||||
}
|
||||
@ -482,3 +486,14 @@ func (m *StrAnyMap) UnmarshalValue(value interface{}) (err error) {
|
||||
m.data = gconv.Map(value)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (m *StrAnyMap) DeepCopy() interface{} {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
data := make(map[string]interface{}, len(m.data))
|
||||
for k, v := range m.data {
|
||||
data[k] = deepcopy.Copy(v)
|
||||
}
|
||||
return NewStrAnyMapFrom(data, m.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -430,6 +430,9 @@ func (m *StrIntMap) Merge(other *StrIntMap) {
|
||||
|
||||
// String returns the map as a string.
|
||||
func (m *StrIntMap) String() string {
|
||||
if m == nil {
|
||||
return ""
|
||||
}
|
||||
b, _ := m.MarshalJSON()
|
||||
return string(b)
|
||||
}
|
||||
@ -471,3 +474,14 @@ func (m *StrIntMap) UnmarshalValue(value interface{}) (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (m *StrIntMap) DeepCopy() interface{} {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
data := make(map[string]int, len(m.data))
|
||||
for k, v := range m.data {
|
||||
data[k] = v
|
||||
}
|
||||
return NewStrIntMapFrom(data, m.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -429,6 +429,9 @@ func (m *StrStrMap) Merge(other *StrStrMap) {
|
||||
|
||||
// String returns the map as a string.
|
||||
func (m *StrStrMap) String() string {
|
||||
if m == nil {
|
||||
return ""
|
||||
}
|
||||
b, _ := m.MarshalJSON()
|
||||
return string(b)
|
||||
}
|
||||
@ -460,3 +463,14 @@ func (m *StrStrMap) UnmarshalValue(value interface{}) (err error) {
|
||||
m.data = gconv.MapStrStr(value)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (m *StrStrMap) DeepCopy() interface{} {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
data := make(map[string]string, len(m.data))
|
||||
for k, v := range m.data {
|
||||
data[k] = v
|
||||
}
|
||||
return NewStrStrMapFrom(data, m.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/gogf/gf/v2/container/glist"
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
"github.com/gogf/gf/v2/internal/deepcopy"
|
||||
"github.com/gogf/gf/v2/internal/empty"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/internal/rwmutex"
|
||||
@ -521,6 +522,9 @@ func (m *ListMap) Merge(other *ListMap) {
|
||||
|
||||
// String returns the map as a string.
|
||||
func (m *ListMap) String() string {
|
||||
if m == nil {
|
||||
return ""
|
||||
}
|
||||
b, _ := m.MarshalJSON()
|
||||
return string(b)
|
||||
}
|
||||
@ -587,3 +591,19 @@ func (m *ListMap) UnmarshalValue(value interface{}) (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (m *ListMap) DeepCopy() interface{} {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
data := make(map[interface{}]interface{}, len(m.data))
|
||||
if m.list != nil {
|
||||
var node *gListMapNode
|
||||
m.list.IteratorAsc(func(e *glist.Element) bool {
|
||||
node = e.Value.(*gListMapNode)
|
||||
data[node.key] = deepcopy.Copy(node.value)
|
||||
return true
|
||||
})
|
||||
}
|
||||
return NewListMapFrom(data, m.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -253,11 +253,11 @@ func Test_AnyAnyMap_Json(t *testing.T) {
|
||||
"k2": "v2",
|
||||
}
|
||||
b, err := json.Marshal(gconv.Map(data))
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
m := gmap.New()
|
||||
err = json.UnmarshalUseNumber(b, m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get("k1"), data["k1"])
|
||||
t.Assert(m.Get("k2"), data["k2"])
|
||||
})
|
||||
@ -267,11 +267,11 @@ func Test_AnyAnyMap_Json(t *testing.T) {
|
||||
"k2": "v2",
|
||||
}
|
||||
b, err := json.Marshal(gconv.Map(data))
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
var m gmap.Map
|
||||
err = json.UnmarshalUseNumber(b, &m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get("k1"), data["k1"])
|
||||
t.Assert(m.Get("k2"), data["k2"])
|
||||
})
|
||||
@ -342,7 +342,7 @@ func TestAnyAnyMap_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"map": []byte(`{"k1":"v1","k2":"v2"}`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get("k1"), "v1")
|
||||
@ -358,7 +358,7 @@ func TestAnyAnyMap_UnmarshalValue(t *testing.T) {
|
||||
"k2": "v2",
|
||||
},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get("k1"), "v1")
|
||||
|
||||
@ -242,11 +242,11 @@ func Test_IntAnyMap_Json(t *testing.T) {
|
||||
2: "v2",
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
m := gmap.NewIntAnyMap()
|
||||
err = json.UnmarshalUseNumber(b, m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get(1), data[1])
|
||||
t.Assert(m.Get(2), data[2])
|
||||
})
|
||||
@ -317,7 +317,7 @@ func TestIntAnyMap_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"map": []byte(`{"1":"v1","2":"v2"}`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get(1), "v1")
|
||||
@ -333,7 +333,7 @@ func TestIntAnyMap_UnmarshalValue(t *testing.T) {
|
||||
2: "v2",
|
||||
},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get(1), "v1")
|
||||
|
||||
@ -248,11 +248,11 @@ func Test_IntIntMap_Json(t *testing.T) {
|
||||
2: 20,
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
m := gmap.NewIntIntMap()
|
||||
err = json.UnmarshalUseNumber(b, m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get(1), data[1])
|
||||
t.Assert(m.Get(2), data[2])
|
||||
})
|
||||
@ -323,7 +323,7 @@ func TestIntIntMap_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"map": []byte(`{"1":1,"2":2}`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get(1), "1")
|
||||
@ -339,7 +339,7 @@ func TestIntIntMap_UnmarshalValue(t *testing.T) {
|
||||
2: 2,
|
||||
},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get(1), "1")
|
||||
|
||||
@ -246,11 +246,11 @@ func Test_IntStrMap_Json(t *testing.T) {
|
||||
2: "v2",
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
m := gmap.NewIntStrMap()
|
||||
err = json.UnmarshalUseNumber(b, m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get(1), data[1])
|
||||
t.Assert(m.Get(2), data[2])
|
||||
})
|
||||
@ -321,7 +321,7 @@ func TestIntStrMap_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"map": []byte(`{"1":"v1","2":"v2"}`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get(1), "v1")
|
||||
@ -337,7 +337,7 @@ func TestIntStrMap_UnmarshalValue(t *testing.T) {
|
||||
2: "v2",
|
||||
},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get(1), "v1")
|
||||
|
||||
@ -240,11 +240,11 @@ func Test_StrAnyMap_Json(t *testing.T) {
|
||||
"k2": "v2",
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
m := gmap.NewStrAnyMap()
|
||||
err = json.UnmarshalUseNumber(b, m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get("k1"), data["k1"])
|
||||
t.Assert(m.Get("k2"), data["k2"])
|
||||
})
|
||||
@ -254,11 +254,11 @@ func Test_StrAnyMap_Json(t *testing.T) {
|
||||
"k2": "v2",
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
var m gmap.StrAnyMap
|
||||
err = json.UnmarshalUseNumber(b, &m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get("k1"), data["k1"])
|
||||
t.Assert(m.Get("k2"), data["k2"])
|
||||
})
|
||||
@ -329,7 +329,7 @@ func TestStrAnyMap_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"map": []byte(`{"k1":"v1","k2":"v2"}`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get("k1"), "v1")
|
||||
@ -345,7 +345,7 @@ func TestStrAnyMap_UnmarshalValue(t *testing.T) {
|
||||
"k2": "v2",
|
||||
},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get("k1"), "v1")
|
||||
|
||||
@ -244,11 +244,11 @@ func Test_StrIntMap_Json(t *testing.T) {
|
||||
"k2": 2,
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
m := gmap.NewStrIntMap()
|
||||
err = json.UnmarshalUseNumber(b, m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get("k1"), data["k1"])
|
||||
t.Assert(m.Get("k2"), data["k2"])
|
||||
})
|
||||
@ -258,11 +258,11 @@ func Test_StrIntMap_Json(t *testing.T) {
|
||||
"k2": 2,
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
var m gmap.StrIntMap
|
||||
err = json.UnmarshalUseNumber(b, &m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get("k1"), data["k1"])
|
||||
t.Assert(m.Get("k2"), data["k2"])
|
||||
})
|
||||
@ -333,7 +333,7 @@ func TestStrIntMap_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"map": []byte(`{"k1":1,"k2":2}`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get("k1"), 1)
|
||||
@ -349,7 +349,7 @@ func TestStrIntMap_UnmarshalValue(t *testing.T) {
|
||||
"k2": 2,
|
||||
},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get("k1"), 1)
|
||||
|
||||
@ -241,11 +241,11 @@ func Test_StrStrMap_Json(t *testing.T) {
|
||||
"k2": "v2",
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
m := gmap.NewStrStrMap()
|
||||
err = json.UnmarshalUseNumber(b, m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get("k1"), data["k1"])
|
||||
t.Assert(m.Get("k2"), data["k2"])
|
||||
})
|
||||
@ -255,11 +255,11 @@ func Test_StrStrMap_Json(t *testing.T) {
|
||||
"k2": "v2",
|
||||
}
|
||||
b, err := json.Marshal(data)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
var m gmap.StrStrMap
|
||||
err = json.UnmarshalUseNumber(b, &m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get("k1"), data["k1"])
|
||||
t.Assert(m.Get("k2"), data["k2"])
|
||||
})
|
||||
@ -330,7 +330,7 @@ func TestStrStrMap_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"map": []byte(`{"k1":"v1","k2":"v2"}`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get("k1"), "v1")
|
||||
@ -346,7 +346,7 @@ func TestStrStrMap_UnmarshalValue(t *testing.T) {
|
||||
"k2": "v2",
|
||||
},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get("k1"), "v1")
|
||||
|
||||
@ -201,11 +201,11 @@ func Test_ListMap_Json(t *testing.T) {
|
||||
"k2": "v2",
|
||||
}
|
||||
b, err := json.Marshal(gconv.Map(data))
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
m := gmap.NewListMap()
|
||||
err = json.UnmarshalUseNumber(b, m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get("k1"), data["k1"])
|
||||
t.Assert(m.Get("k2"), data["k2"])
|
||||
})
|
||||
@ -216,11 +216,11 @@ func Test_ListMap_Json(t *testing.T) {
|
||||
"k2": "v2",
|
||||
}
|
||||
b, err := json.Marshal(gconv.Map(data))
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
var m gmap.ListMap
|
||||
err = json.UnmarshalUseNumber(b, &m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get("k1"), data["k1"])
|
||||
t.Assert(m.Get("k2"), data["k2"])
|
||||
})
|
||||
@ -312,7 +312,7 @@ func TestListMap_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"map": []byte(`{"1":"v1","2":"v2"}`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get("1"), "v1")
|
||||
@ -328,7 +328,7 @@ func TestListMap_UnmarshalValue(t *testing.T) {
|
||||
2: "v2",
|
||||
},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get("1"), "v1")
|
||||
|
||||
@ -185,11 +185,11 @@ func Test_TreeMap_Json(t *testing.T) {
|
||||
"k2": "v2",
|
||||
}
|
||||
b, err := json.Marshal(gconv.Map(data))
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
m := gmap.NewTreeMap(gutil.ComparatorString)
|
||||
err = json.UnmarshalUseNumber(b, m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get("k1"), data["k1"])
|
||||
t.Assert(m.Get("k2"), data["k2"])
|
||||
})
|
||||
@ -199,11 +199,11 @@ func Test_TreeMap_Json(t *testing.T) {
|
||||
"k2": "v2",
|
||||
}
|
||||
b, err := json.Marshal(gconv.Map(data))
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
var m gmap.TreeMap
|
||||
err = json.UnmarshalUseNumber(b, &m)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(m.Get("k1"), data["k1"])
|
||||
t.Assert(m.Get("k2"), data["k2"])
|
||||
})
|
||||
@ -221,7 +221,7 @@ func TestTreeMap_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"map": []byte(`{"k1":"v1","k2":"v2"}`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get("k1"), "v1")
|
||||
@ -237,7 +237,7 @@ func TestTreeMap_UnmarshalValue(t *testing.T) {
|
||||
"k2": "v2",
|
||||
},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Map.Size(), 2)
|
||||
t.Assert(v.Map.Get("k1"), "v1")
|
||||
|
||||
@ -223,6 +223,9 @@ func (set *Set) Join(glue string) string {
|
||||
|
||||
// String returns items as a string, which implements like json.Marshal does.
|
||||
func (set *Set) String() string {
|
||||
if set == nil {
|
||||
return ""
|
||||
}
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
var (
|
||||
@ -507,3 +510,14 @@ func (set *Set) UnmarshalValue(value interface{}) (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (set *Set) DeepCopy() interface{} {
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
data := make(map[interface{}]struct{}, len(set.data))
|
||||
for k, v := range set.data {
|
||||
data[k] = v
|
||||
}
|
||||
return NewFrom(data, set.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -204,6 +204,9 @@ func (set *IntSet) Join(glue string) string {
|
||||
|
||||
// String returns items as a string, which implements like json.Marshal does.
|
||||
func (set *IntSet) String() string {
|
||||
if set == nil {
|
||||
return ""
|
||||
}
|
||||
return "[" + set.Join(",") + "]"
|
||||
}
|
||||
|
||||
@ -466,3 +469,18 @@ func (set *IntSet) UnmarshalValue(value interface{}) (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (set *IntSet) DeepCopy() interface{} {
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
var (
|
||||
slice = make([]int, len(set.data))
|
||||
index = 0
|
||||
)
|
||||
for k := range set.data {
|
||||
slice[index] = k
|
||||
index++
|
||||
}
|
||||
return NewIntSetFrom(slice, set.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -218,6 +218,9 @@ func (set *StrSet) Join(glue string) string {
|
||||
|
||||
// String returns items as a string, which implements like json.Marshal does.
|
||||
func (set *StrSet) String() string {
|
||||
if set == nil {
|
||||
return ""
|
||||
}
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
var (
|
||||
@ -225,6 +228,7 @@ func (set *StrSet) String() string {
|
||||
i = 0
|
||||
buffer = bytes.NewBuffer(nil)
|
||||
)
|
||||
buffer.WriteByte('[')
|
||||
for k, _ := range set.data {
|
||||
buffer.WriteString(`"` + gstr.QuoteMeta(k, `"\`) + `"`)
|
||||
if i != l-1 {
|
||||
@ -232,6 +236,7 @@ func (set *StrSet) String() string {
|
||||
}
|
||||
i++
|
||||
}
|
||||
buffer.WriteByte(']')
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
@ -494,3 +499,18 @@ func (set *StrSet) UnmarshalValue(value interface{}) (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (set *StrSet) DeepCopy() interface{} {
|
||||
set.mu.RLock()
|
||||
defer set.mu.RUnlock()
|
||||
var (
|
||||
slice = make([]string, len(set.data))
|
||||
index = 0
|
||||
)
|
||||
for k := range set.data {
|
||||
slice[index] = k
|
||||
index++
|
||||
}
|
||||
return NewStrSetFrom(slice, set.mu.IsSafe())
|
||||
}
|
||||
|
||||
@ -336,7 +336,7 @@ func TestSet_Json(t *testing.T) {
|
||||
|
||||
var a3 gset.Set
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Contains("a"), true)
|
||||
t.Assert(a3.Contains("b"), true)
|
||||
t.Assert(a3.Contains("c"), true)
|
||||
@ -438,7 +438,7 @@ func TestSet_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"set": []byte(`["k1","k2","k3"]`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Set.Size(), 3)
|
||||
t.Assert(v.Set.Contains("k1"), true)
|
||||
@ -453,7 +453,7 @@ func TestSet_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"set": g.Slice{"k1", "k2", "k3"},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Set.Size(), 3)
|
||||
t.Assert(v.Set.Contains("k1"), true)
|
||||
|
||||
@ -368,7 +368,7 @@ func TestIntSet_Json(t *testing.T) {
|
||||
|
||||
var a3 gset.IntSet
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a2.Contains(1), true)
|
||||
t.Assert(a2.Contains(2), true)
|
||||
t.Assert(a2.Contains(3), true)
|
||||
@ -402,7 +402,7 @@ func TestIntSet_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"set": []byte(`[1,2,3]`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Set.Size(), 3)
|
||||
t.Assert(v.Set.Contains(1), true)
|
||||
@ -417,7 +417,7 @@ func TestIntSet_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"set": g.Slice{1, 2, 3},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Set.Size(), 3)
|
||||
t.Assert(v.Set.Contains(1), true)
|
||||
|
||||
@ -414,7 +414,7 @@ func TestStrSet_Json(t *testing.T) {
|
||||
|
||||
var a3 gset.StrSet
|
||||
err := json.UnmarshalUseNumber(b2, &a3)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(a3.Contains("a"), true)
|
||||
t.Assert(a3.Contains("b"), true)
|
||||
t.Assert(a3.Contains("c"), true)
|
||||
@ -453,7 +453,7 @@ func TestStrSet_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"set": []byte(`["1","2","3"]`),
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Set.Size(), 3)
|
||||
t.Assert(v.Set.Contains("1"), true)
|
||||
@ -468,7 +468,7 @@ func TestStrSet_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"set": g.SliceStr{"1", "2", "3"},
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Set.Size(), 3)
|
||||
t.Assert(v.Set.Contains("1"), true)
|
||||
|
||||
@ -399,6 +399,9 @@ func (tree *AVLTree) Replace(data map[interface{}]interface{}) {
|
||||
|
||||
// String returns a string representation of container
|
||||
func (tree *AVLTree) String() string {
|
||||
if tree == nil {
|
||||
return ""
|
||||
}
|
||||
tree.mu.RLock()
|
||||
defer tree.mu.RUnlock()
|
||||
str := ""
|
||||
|
||||
@ -367,6 +367,9 @@ func (tree *BTree) Right() *BTreeEntry {
|
||||
|
||||
// String returns a string representation of container (for debugging purposes)
|
||||
func (tree *BTree) String() string {
|
||||
if tree == nil {
|
||||
return ""
|
||||
}
|
||||
tree.mu.RLock()
|
||||
defer tree.mu.RUnlock()
|
||||
var buffer bytes.Buffer
|
||||
|
||||
@ -623,6 +623,9 @@ func (tree *RedBlackTree) Replace(data map[interface{}]interface{}) {
|
||||
|
||||
// String returns a string representation of container.
|
||||
func (tree *RedBlackTree) String() string {
|
||||
if tree == nil {
|
||||
return ""
|
||||
}
|
||||
tree.mu.RLock()
|
||||
defer tree.mu.RUnlock()
|
||||
str := ""
|
||||
|
||||
@ -96,3 +96,8 @@ func (v *Bool) UnmarshalValue(value interface{}) error {
|
||||
v.Set(gconv.Bool(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Bool) DeepCopy() interface{} {
|
||||
return NewBool(v.Val())
|
||||
}
|
||||
|
||||
@ -75,3 +75,8 @@ func (v *Byte) UnmarshalValue(value interface{}) error {
|
||||
v.Set(gconv.Byte(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Byte) DeepCopy() interface{} {
|
||||
return NewByte(v.Val())
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ func NewBytes(value ...[]byte) *Bytes {
|
||||
return t
|
||||
}
|
||||
|
||||
// Clone clones and returns a new concurrent-safe object for []byte type.
|
||||
// Clone clones and returns a new shallow copy object for []byte type.
|
||||
func (v *Bytes) Clone() *Bytes {
|
||||
return NewBytes(v.Val())
|
||||
}
|
||||
@ -83,3 +83,11 @@ func (v *Bytes) UnmarshalValue(value interface{}) error {
|
||||
v.Set(gconv.Bytes(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Bytes) DeepCopy() interface{} {
|
||||
oldBytes := v.Val()
|
||||
newBytes := make([]byte, len(oldBytes))
|
||||
copy(newBytes, oldBytes)
|
||||
return NewBytes(newBytes)
|
||||
}
|
||||
|
||||
@ -87,3 +87,8 @@ func (v *Float32) UnmarshalValue(value interface{}) error {
|
||||
v.Set(gconv.Float32(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Float32) DeepCopy() interface{} {
|
||||
return NewFloat32(v.Val())
|
||||
}
|
||||
|
||||
@ -87,3 +87,8 @@ func (v *Float64) UnmarshalValue(value interface{}) error {
|
||||
v.Set(gconv.Float64(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Float64) DeepCopy() interface{} {
|
||||
return NewFloat64(v.Val())
|
||||
}
|
||||
|
||||
@ -75,3 +75,8 @@ func (v *Int) UnmarshalValue(value interface{}) error {
|
||||
v.Set(gconv.Int(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Int) DeepCopy() interface{} {
|
||||
return NewInt(v.Val())
|
||||
}
|
||||
|
||||
@ -75,3 +75,8 @@ func (v *Int32) UnmarshalValue(value interface{}) error {
|
||||
v.Set(gconv.Int32(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Int32) DeepCopy() interface{} {
|
||||
return NewInt32(v.Val())
|
||||
}
|
||||
|
||||
@ -75,3 +75,8 @@ func (v *Int64) UnmarshalValue(value interface{}) error {
|
||||
v.Set(gconv.Int64(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Int64) DeepCopy() interface{} {
|
||||
return NewInt64(v.Val())
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ package gtype
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/gogf/gf/v2/internal/deepcopy"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
@ -71,3 +72,8 @@ func (v *Interface) UnmarshalValue(value interface{}) error {
|
||||
v.Set(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Interface) DeepCopy() interface{} {
|
||||
return NewInterface(deepcopy.Copy(v.Val()))
|
||||
}
|
||||
|
||||
@ -75,3 +75,8 @@ func (v *Uint) UnmarshalValue(value interface{}) error {
|
||||
v.Set(gconv.Uint(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Uint) DeepCopy() interface{} {
|
||||
return NewUint(v.Val())
|
||||
}
|
||||
|
||||
@ -75,3 +75,8 @@ func (v *Uint32) UnmarshalValue(value interface{}) error {
|
||||
v.Set(gconv.Uint32(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Uint32) DeepCopy() interface{} {
|
||||
return NewUint32(v.Val())
|
||||
}
|
||||
|
||||
@ -75,3 +75,8 @@ func (v *Uint64) UnmarshalValue(value interface{}) error {
|
||||
v.Set(gconv.Uint64(value))
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Uint64) DeepCopy() interface{} {
|
||||
return NewUint64(v.Val())
|
||||
}
|
||||
|
||||
@ -56,16 +56,16 @@ func Test_Bool_JSON(t *testing.T) {
|
||||
var err error
|
||||
i := gtype.NewBool()
|
||||
err = json.UnmarshalUseNumber([]byte("true"), &i)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i.Val(), true)
|
||||
err = json.UnmarshalUseNumber([]byte("false"), &i)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i.Val(), false)
|
||||
err = json.UnmarshalUseNumber([]byte("1"), &i)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i.Val(), true)
|
||||
err = json.UnmarshalUseNumber([]byte("0"), &i)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i.Val(), false)
|
||||
})
|
||||
|
||||
@ -79,7 +79,7 @@ func Test_Bool_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.NewBool()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), i.Val())
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
@ -92,7 +92,7 @@ func Test_Bool_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.NewBool()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), i.Val())
|
||||
})
|
||||
}
|
||||
@ -108,7 +108,7 @@ func Test_Bool_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "true",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), true)
|
||||
})
|
||||
@ -118,7 +118,7 @@ func Test_Bool_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "false",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), false)
|
||||
})
|
||||
|
||||
@ -54,7 +54,7 @@ func Test_Byte_JSON(t *testing.T) {
|
||||
var err error
|
||||
i := gtype.NewByte()
|
||||
err = json.UnmarshalUseNumber([]byte("49"), &i)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i.Val(), "49")
|
||||
})
|
||||
}
|
||||
@ -70,7 +70,7 @@ func Test_Byte_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "2",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), "2")
|
||||
})
|
||||
|
||||
@ -40,7 +40,7 @@ func Test_Bytes_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.NewBytes()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), b)
|
||||
})
|
||||
}
|
||||
@ -56,7 +56,7 @@ func Test_Bytes_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "123",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), "123")
|
||||
})
|
||||
|
||||
@ -42,7 +42,7 @@ func Test_Float32_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.NewFloat32()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), v)
|
||||
})
|
||||
}
|
||||
@ -58,7 +58,7 @@ func Test_Float32_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "123.456",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), "123.456")
|
||||
})
|
||||
|
||||
@ -40,7 +40,7 @@ func Test_Float64_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.NewFloat64()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), v)
|
||||
})
|
||||
}
|
||||
@ -56,7 +56,7 @@ func Test_Float64_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "123.456",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), "123.456")
|
||||
})
|
||||
|
||||
@ -53,7 +53,7 @@ func Test_Int32_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.NewInt32()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), v)
|
||||
})
|
||||
}
|
||||
@ -69,7 +69,7 @@ func Test_Int32_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "123",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), "123")
|
||||
})
|
||||
|
||||
@ -52,7 +52,7 @@ func Test_Int64_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.NewInt64()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), i)
|
||||
})
|
||||
}
|
||||
@ -68,7 +68,7 @@ func Test_Int64_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "123",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), "123")
|
||||
})
|
||||
|
||||
@ -52,7 +52,7 @@ func Test_Int_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.NewInt()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), v)
|
||||
})
|
||||
}
|
||||
@ -68,7 +68,7 @@ func Test_Int_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "123",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), "123")
|
||||
})
|
||||
|
||||
@ -42,7 +42,7 @@ func Test_Interface_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.New()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), s)
|
||||
})
|
||||
}
|
||||
@ -58,7 +58,7 @@ func Test_Interface_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "123",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), "123")
|
||||
})
|
||||
|
||||
@ -40,7 +40,7 @@ func Test_String_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.NewString()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), s)
|
||||
})
|
||||
}
|
||||
@ -56,7 +56,7 @@ func Test_String_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "123",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), "123")
|
||||
})
|
||||
|
||||
@ -52,7 +52,7 @@ func Test_Uint32_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.NewUint32()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), i)
|
||||
})
|
||||
}
|
||||
@ -68,7 +68,7 @@ func Test_Uint32_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "123",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), "123")
|
||||
})
|
||||
|
||||
@ -56,7 +56,7 @@ func Test_Uint64_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.NewUint64()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), i)
|
||||
})
|
||||
}
|
||||
@ -72,7 +72,7 @@ func Test_Uint64_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "123",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), "123")
|
||||
})
|
||||
|
||||
@ -51,7 +51,7 @@ func Test_Uint_JSON(t *testing.T) {
|
||||
|
||||
i2 := gtype.NewUint()
|
||||
err := json.UnmarshalUseNumber(b2, &i2)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(i2.Val(), i)
|
||||
})
|
||||
}
|
||||
@ -67,7 +67,7 @@ func Test_Uint_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "123",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.Val(), "123")
|
||||
})
|
||||
|
||||
@ -11,9 +11,11 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gtype"
|
||||
"github.com/gogf/gf/v2/internal/deepcopy"
|
||||
"github.com/gogf/gf/v2/internal/json"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/gutil"
|
||||
)
|
||||
|
||||
// Var is an universal variable type implementer.
|
||||
@ -37,6 +39,11 @@ func New(value interface{}, safe ...bool) *Var {
|
||||
}
|
||||
}
|
||||
|
||||
// Copy does a deep copy of current Var and returns a pointer to this Var.
|
||||
func (v *Var) Copy() *Var {
|
||||
return New(gutil.Copy(v.Val()), v.safe)
|
||||
}
|
||||
|
||||
// Clone does a shallow copy of current Var and returns a pointer to this Var.
|
||||
func (v *Var) Clone() *Var {
|
||||
return New(v.Val(), v.safe)
|
||||
@ -188,3 +195,8 @@ func (v *Var) UnmarshalValue(value interface{}) error {
|
||||
v.Set(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopy implements interface for deep copy of current type.
|
||||
func (v *Var) DeepCopy() interface{} {
|
||||
return New(deepcopy.Copy(v.Val()), v.safe)
|
||||
}
|
||||
|
||||
@ -18,10 +18,10 @@ import (
|
||||
// New
|
||||
func ExampleVarNew() {
|
||||
v := gvar.New(400)
|
||||
g.Dump(v)
|
||||
fmt.Println(v)
|
||||
|
||||
// Output:
|
||||
// "400"
|
||||
// 400
|
||||
}
|
||||
|
||||
// Clone
|
||||
|
||||
@ -13,6 +13,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gvar"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
@ -253,7 +254,7 @@ func Test_UnmarshalJson(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "v",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.String(), "v")
|
||||
})
|
||||
@ -267,7 +268,7 @@ func Test_UnmarshalJson(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "v",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.String(), "v")
|
||||
})
|
||||
@ -284,7 +285,7 @@ func Test_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "v",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.String(), "v")
|
||||
})
|
||||
@ -298,8 +299,32 @@ func Test_UnmarshalValue(t *testing.T) {
|
||||
"name": "john",
|
||||
"var": "v",
|
||||
}, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.Name, "john")
|
||||
t.Assert(v.Var.String(), "v")
|
||||
})
|
||||
}
|
||||
|
||||
func Test_Copy(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
src := g.Map{
|
||||
"k1": "v1",
|
||||
"k2": "v2",
|
||||
}
|
||||
srcVar := gvar.New(src)
|
||||
dstVar := srcVar.Copy()
|
||||
t.Assert(srcVar.Map(), src)
|
||||
t.Assert(dstVar.Map(), src)
|
||||
|
||||
dstVar.Map()["k3"] = "v3"
|
||||
t.Assert(srcVar.Map(), g.Map{
|
||||
"k1": "v1",
|
||||
"k2": "v2",
|
||||
})
|
||||
t.Assert(dstVar.Map(), g.Map{
|
||||
"k1": "v1",
|
||||
"k2": "v2",
|
||||
"k3": "v3",
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -40,10 +40,10 @@ func TestVar_Json(t *testing.T) {
|
||||
s := "i love gf"
|
||||
v := gvar.New(nil)
|
||||
b, err := json.Marshal(s)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
err = json.UnmarshalUseNumber(b, v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.String(), s)
|
||||
})
|
||||
|
||||
@ -51,10 +51,10 @@ func TestVar_Json(t *testing.T) {
|
||||
var v gvar.Var
|
||||
s := "i love gf"
|
||||
b, err := json.Marshal(s)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
|
||||
err = json.UnmarshalUseNumber(b, &v)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(v.String(), s)
|
||||
})
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ func TestVar_Var_Attribute_Struct(t *testing.T) {
|
||||
"uid": gvar.New(1),
|
||||
"name": gvar.New("john"),
|
||||
}, user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Uid, 1)
|
||||
t.Assert(user.Name, "john")
|
||||
})
|
||||
@ -70,7 +70,7 @@ func TestVar_Var_Attribute_Struct(t *testing.T) {
|
||||
"uid": gvar.New(1),
|
||||
"name": gvar.New("john"),
|
||||
}, &user)
|
||||
t.Assert(err, nil)
|
||||
t.AssertNil(err)
|
||||
t.Assert(user.Uid, 1)
|
||||
t.Assert(user.Name, "john")
|
||||
})
|
||||
|
||||
@ -1,22 +1,39 @@
|
||||
# drivers
|
||||
Database drivers for package gdb.
|
||||
Powerful database drivers for package gdb.
|
||||
|
||||
# Installation
|
||||
Let's take `pgsql` for example.
|
||||
Let's take `mysql` for example.
|
||||
```
|
||||
go get -u github.com/gogf/gf/contrib/drivers/pgsql/v2
|
||||
go get -u github.com/gogf/gf/contrib/drivers/mysql/v2
|
||||
```
|
||||
|
||||
Choose and import the driver to your project:
|
||||
```
|
||||
import _ "github.com/gogf/gf/contrib/drivers/pgsql/v2"
|
||||
import _ "github.com/gogf/gf/contrib/drivers/mysql/v2"
|
||||
```
|
||||
|
||||
Commonly imported at top of `main.go`:
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "github.com/gogf/gf/contrib/drivers/mysql/v2"
|
||||
|
||||
// Other imported packages.
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Main logics.
|
||||
}
|
||||
```
|
||||
|
||||
# Supported Drivers
|
||||
|
||||
## MySQL
|
||||
## MySQL/MariaDB/TiDB
|
||||
|
||||
BuiltIn supported, nothing todo.
|
||||
```
|
||||
import _ "github.com/gogf/gf/contrib/drivers/mysql/v2"
|
||||
```
|
||||
|
||||
## SQLite
|
||||
```
|
||||
@ -50,6 +67,16 @@ Note:
|
||||
- It does not support `Save/Replace` features.
|
||||
- It does not support `LastInsertId`.
|
||||
|
||||
## ClickHouse
|
||||
```
|
||||
import _ "github.com/gogf/gf/contrib/drivers/clickhouse/v2"
|
||||
```
|
||||
Note:
|
||||
- It does not support `InsertIgnore/InsertGetId` features.
|
||||
- It does not support `Save/Replace` features.
|
||||
- It does not support `Transaction` feature.
|
||||
- It does not support `RowsAffected` feature.
|
||||
|
||||
# Custom Drivers
|
||||
|
||||
It's quick and easy, please refer to current driver source.
|
||||
|
||||
@ -8,5 +8,443 @@
|
||||
package clickhouse
|
||||
|
||||
import (
|
||||
_ "github.com/ClickHouse/clickhouse-go"
|
||||
"context"
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ClickHouse/clickhouse-go/v2"
|
||||
"github.com/gogf/gf/v2/container/gmap"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/text/gregex"
|
||||
"github.com/gogf/gf/v2/text/gstr"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/google/uuid"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Driver is the driver for postgresql database.
|
||||
type Driver struct {
|
||||
*gdb.Core
|
||||
}
|
||||
|
||||
var (
|
||||
// tableFieldsMap caches the table information retrieved from database.
|
||||
tableFieldsMap = gmap.New(true)
|
||||
|
||||
errUnsupportedInsertIgnore = errors.New("unsupported method:InsertIgnore")
|
||||
errUnsupportedInsertGetId = errors.New("unsupported method:InsertGetId")
|
||||
errUnsupportedReplace = errors.New("unsupported method:Replace")
|
||||
errUnsupportedBegin = errors.New("unsupported method:Begin")
|
||||
errUnsupportedTransaction = errors.New("unsupported method:Transaction")
|
||||
)
|
||||
|
||||
const (
|
||||
updateFilterPattern = `(?i)UPDATE[\s]+?(\w+[\.]?\w+)[\s]+?SET`
|
||||
deleteFilterPattern = `(?i)DELETE[\s]+?FROM[\s]+?(\w+[\.]?\w+)`
|
||||
filterTypePattern = `(?i)^UPDATE|DELETE`
|
||||
replaceSchemaPattern = `@(.+?)/([\w\.\-]+)+`
|
||||
needParsedSqlInCtx gctx.StrKey = "NeedParsedSql"
|
||||
OrmTagForStruct = "orm"
|
||||
driverName = "clickhouse"
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := gdb.Register(`clickhouse`, New()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// New create and returns a driver that implements gdb.Driver, which supports operations for clickhouse.
|
||||
func New() gdb.Driver {
|
||||
return &Driver{}
|
||||
}
|
||||
|
||||
// New creates and returns a database object for clickhouse.
|
||||
// It implements the interface of gdb.Driver for extra database driver installation.
|
||||
func (d *Driver) New(core *gdb.Core, node *gdb.ConfigNode) (gdb.DB, error) {
|
||||
return &Driver{
|
||||
Core: core,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Open creates and returns an underlying sql.DB object for clickhouse.
|
||||
func (d *Driver) Open(config *gdb.ConfigNode) (*sql.DB, error) {
|
||||
// clickhouse://username:password@host1:9000,host2:9000/database?dial_timeout=200ms&max_execution_time=60
|
||||
if config.Link != "" {
|
||||
// Custom changing the schema in runtime.
|
||||
if config.Name != "" {
|
||||
config.Link, _ = gregex.ReplaceString(replaceSchemaPattern, "@$1/"+config.Name, config.Link)
|
||||
} else {
|
||||
// If no schema, the link is matched for replacement
|
||||
dbName, _ := gregex.MatchString(replaceSchemaPattern, config.Link)
|
||||
if len(dbName) > 0 {
|
||||
config.Name = dbName[len(dbName)-1]
|
||||
}
|
||||
}
|
||||
} else if config.Pass != "" {
|
||||
config.Link = fmt.Sprintf(
|
||||
"clickhouse://%s:%s@%s:%s/%s?charset=%s&debug=%t",
|
||||
config.User, url.PathEscape(config.Pass), config.Host, config.Port, config.Name, config.Charset, config.Debug)
|
||||
} else {
|
||||
config.Link = fmt.Sprintf(
|
||||
"clickhouse://%s@%s:%s/%s?charset=%s&debug=%t",
|
||||
config.User, config.Host, config.Port, config.Name, config.Charset, config.Debug)
|
||||
}
|
||||
db, err := sql.Open(driverName, config.Link)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
// Tables retrieves and returns the tables of current schema.
|
||||
// It's mainly used in cli tool chain for automatically generating the models.
|
||||
func (d *Driver) Tables(ctx context.Context, schema ...string) (tables []string, err error) {
|
||||
var result gdb.Result
|
||||
link, err := d.SlaveLink(schema...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := fmt.Sprintf("select name from `system`.tables where database = '%s'", d.GetConfig().Name)
|
||||
result, err = d.DoSelect(ctx, link, query)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, m := range result {
|
||||
tables = append(tables, m["name"].String())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TableFields retrieves and returns the fields' information of specified table of current schema.
|
||||
// Also see DriverMysql.TableFields.
|
||||
func (d *Driver) TableFields(
|
||||
ctx context.Context, table string, schema ...string,
|
||||
) (fields map[string]*gdb.TableField, err error) {
|
||||
charL, charR := d.GetChars()
|
||||
table = gstr.Trim(table, charL+charR)
|
||||
if gstr.Contains(table, " ") {
|
||||
return nil, gerror.NewCode(gcode.CodeInvalidParameter, "function TableFields supports only single table operations")
|
||||
}
|
||||
useSchema := d.GetSchema()
|
||||
if len(schema) > 0 && schema[0] != "" {
|
||||
useSchema = schema[0]
|
||||
}
|
||||
v := tableFieldsMap.GetOrSetFuncLock(
|
||||
fmt.Sprintf(`clickhouse_table_fields_%s_%s@group:%s`, table, useSchema, d.GetGroup()),
|
||||
func() interface{} {
|
||||
var (
|
||||
result gdb.Result
|
||||
link gdb.Link
|
||||
)
|
||||
if link, err = d.SlaveLink(useSchema); err != nil {
|
||||
return nil
|
||||
}
|
||||
getColumnsSql := fmt.Sprintf("select name,position,default_expression,comment,type,is_in_partition_key,is_in_sorting_key,is_in_primary_key,is_in_sampling_key from `system`.columns c where database = '%s' and `table` = '%s'", d.GetConfig().Name, table)
|
||||
result, err = d.DoSelect(ctx, link, getColumnsSql)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
fields = make(map[string]*gdb.TableField)
|
||||
for _, m := range result {
|
||||
var (
|
||||
isNull = false
|
||||
fieldType = m["type"].String()
|
||||
)
|
||||
// in clickhouse , filed type like is Nullable(int)
|
||||
fieldsResult, _ := gregex.MatchString(`^Nullable\((.*?)\)`, fieldType)
|
||||
if len(fieldsResult) == 2 {
|
||||
isNull = true
|
||||
fieldType = fieldsResult[1]
|
||||
}
|
||||
fields[m["name"].String()] = &gdb.TableField{
|
||||
Index: m["position"].Int(),
|
||||
Name: m["name"].String(),
|
||||
Default: m["default_expression"].Val(),
|
||||
Comment: m["comment"].String(),
|
||||
//Key: m["Key"].String(),
|
||||
Type: fieldType,
|
||||
Null: isNull,
|
||||
}
|
||||
}
|
||||
return fields
|
||||
},
|
||||
)
|
||||
if v != nil {
|
||||
fields = v.(map[string]*gdb.TableField)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FilteredLink retrieves and returns filtered `linkInfo` that can be using for
|
||||
// logging or tracing purpose.
|
||||
func (d *Driver) FilteredLink() string {
|
||||
linkInfo := d.GetConfig().Link
|
||||
if linkInfo == "" {
|
||||
return ""
|
||||
}
|
||||
s, _ := gregex.ReplaceString(
|
||||
`(.+?):(.+)@tcp(.+)`,
|
||||
`$1:xxx@tcp$3`,
|
||||
linkInfo,
|
||||
)
|
||||
return s
|
||||
}
|
||||
|
||||
// PingMaster pings the master node to check authentication or keeps the connection alive.
|
||||
func (d *Driver) PingMaster() error {
|
||||
conn, err := d.Master()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.ping(conn)
|
||||
}
|
||||
|
||||
// PingSlave pings the slave node to check authentication or keeps the connection alive.
|
||||
func (d *Driver) PingSlave() error {
|
||||
conn, err := d.Slave()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.ping(conn)
|
||||
}
|
||||
|
||||
// ping Returns the Clickhouse specific error.
|
||||
func (d *Driver) ping(conn *sql.DB) error {
|
||||
err := conn.Ping()
|
||||
if exception, ok := err.(*clickhouse.Exception); ok {
|
||||
return errors.New(fmt.Sprintf("[%d]%s", exception.Code, exception.Message))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// DoFilter handles the sql before posts it to database.
|
||||
func (d *Driver) DoFilter(
|
||||
ctx context.Context, link gdb.Link, originSql string, args []interface{},
|
||||
) (newSql string, newArgs []interface{}, err error) {
|
||||
if len(args) == 0 {
|
||||
return originSql, args, nil
|
||||
}
|
||||
|
||||
var index int
|
||||
// Convert placeholder char '?' to string "$x".
|
||||
originSql, _ = gregex.ReplaceStringFunc(`\?`, originSql, func(s string) string {
|
||||
index++
|
||||
return fmt.Sprintf(`$%d`, index)
|
||||
})
|
||||
|
||||
// Only SQL generated through the framework is processed.
|
||||
if !d.getNeedParsedSqlFromCtx(ctx) {
|
||||
return originSql, args, nil
|
||||
}
|
||||
|
||||
// replace STD SQL to Clickhouse SQL grammar
|
||||
modeRes, err := gregex.MatchString(filterTypePattern, strings.TrimSpace(originSql))
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if len(modeRes) == 0 {
|
||||
return originSql, args, nil
|
||||
}
|
||||
|
||||
// Only delete/ UPDATE statements require filter
|
||||
switch strings.ToUpper(modeRes[0]) {
|
||||
case "UPDATE":
|
||||
// MySQL eg: UPDATE table_name SET field1=new-value1, field2=new-value2 [WHERE Clause]
|
||||
// Clickhouse eg: ALTER TABLE [db.]table UPDATE column1 = expr1 [, ...] WHERE filter_expr
|
||||
newSql, err = gregex.ReplaceStringFuncMatch(updateFilterPattern, originSql, func(s []string) string {
|
||||
return fmt.Sprintf("ALTER TABLE %s UPDATE", s[1])
|
||||
})
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return newSql, args, nil
|
||||
|
||||
case "DELETE":
|
||||
// MySQL eg: DELETE FROM table_name [WHERE Clause]
|
||||
// Clickhouse eg: ALTER TABLE [db.]table [ON CLUSTER cluster] DELETE WHERE filter_expr
|
||||
newSql, err = gregex.ReplaceStringFuncMatch(deleteFilterPattern, originSql, func(s []string) string {
|
||||
return fmt.Sprintf("ALTER TABLE %s DELETE", s[1])
|
||||
})
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return newSql, args, nil
|
||||
|
||||
}
|
||||
return originSql, args, nil
|
||||
}
|
||||
|
||||
// DoCommit commits current sql and arguments to underlying sql driver.
|
||||
func (d *Driver) DoCommit(ctx context.Context, in gdb.DoCommitInput) (out gdb.DoCommitOutput, err error) {
|
||||
ctx = d.InjectIgnoreResult(ctx)
|
||||
return d.Core.DoCommit(ctx, in)
|
||||
}
|
||||
|
||||
func (d *Driver) DoInsert(
|
||||
ctx context.Context, link gdb.Link, table string, list gdb.List, option gdb.DoInsertOption,
|
||||
) (result sql.Result, err error) {
|
||||
var (
|
||||
keys []string // Field names.
|
||||
valueHolder = make([]string, 0)
|
||||
)
|
||||
// Handle the field names and placeholders.
|
||||
for k := range list[0] {
|
||||
keys = append(keys, k)
|
||||
valueHolder = append(valueHolder, "?")
|
||||
}
|
||||
// Prepare the batch result pointer.
|
||||
var (
|
||||
charL, charR = d.Core.GetChars()
|
||||
keysStr = charL + strings.Join(keys, charR+","+charL) + charR
|
||||
holderStr = strings.Join(valueHolder, ",")
|
||||
tx = &gdb.TX{}
|
||||
stdSqlResult sql.Result
|
||||
stmt *gdb.Stmt
|
||||
)
|
||||
tx, err = d.Core.Begin(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
stmt, err = tx.Prepare(fmt.Sprintf(
|
||||
"INSERT INTO %s(%s) VALUES (%s)",
|
||||
d.QuotePrefixTableName(table), keysStr,
|
||||
holderStr,
|
||||
))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for i := 0; i < len(list); i++ {
|
||||
params := make([]interface{}, 0) // Values that will be committed to underlying database driver.
|
||||
for _, k := range keys {
|
||||
params = append(params, list[i][k])
|
||||
}
|
||||
// Prepare is allowed to execute only once in a transaction opened by clickhouse
|
||||
stdSqlResult, err = stmt.ExecContext(ctx, params...)
|
||||
if err != nil {
|
||||
return stdSqlResult, err
|
||||
}
|
||||
}
|
||||
return stdSqlResult, tx.Commit()
|
||||
}
|
||||
|
||||
// ConvertDataForRecord converting for any data that will be inserted into table/collection as a record.
|
||||
func (d *Driver) ConvertDataForRecord(ctx context.Context, value interface{}) (map[string]interface{}, error) {
|
||||
m := gconv.Map(value, OrmTagForStruct)
|
||||
|
||||
// transforms a value of a particular type
|
||||
for k, v := range m {
|
||||
switch itemValue := v.(type) {
|
||||
|
||||
case time.Time:
|
||||
m[k] = itemValue
|
||||
// If the time is zero, it then updates it to nil,
|
||||
// which will insert/update the value to database as "null".
|
||||
if itemValue.IsZero() {
|
||||
m[k] = nil
|
||||
}
|
||||
|
||||
case uuid.UUID:
|
||||
m[k] = itemValue
|
||||
|
||||
case *time.Time:
|
||||
m[k] = itemValue
|
||||
// If the time is zero, it then updates it to nil,
|
||||
// which will insert/update the value to database as "null".
|
||||
if itemValue == nil || itemValue.IsZero() {
|
||||
m[k] = nil
|
||||
}
|
||||
|
||||
case gtime.Time:
|
||||
// for gtime type, needs to get time.Time
|
||||
m[k] = itemValue.Time
|
||||
// If the time is zero, it then updates it to nil,
|
||||
// which will insert/update the value to database as "null".
|
||||
if itemValue.IsZero() {
|
||||
m[k] = nil
|
||||
}
|
||||
|
||||
case *gtime.Time:
|
||||
// for gtime type, needs to get time.Time
|
||||
if itemValue != nil {
|
||||
m[k] = itemValue.Time
|
||||
}
|
||||
// If the time is zero, it then updates it to nil,
|
||||
// which will insert/update the value to database as "null".
|
||||
if itemValue == nil || itemValue.IsZero() {
|
||||
m[k] = nil
|
||||
}
|
||||
|
||||
default:
|
||||
// if the other type implements valuer for the driver package
|
||||
// the converted result is used
|
||||
// otherwise the interface data is committed
|
||||
valuer, ok := itemValue.(driver.Valuer)
|
||||
if !ok {
|
||||
m[k] = itemValue
|
||||
continue
|
||||
}
|
||||
convertedValue, err := valuer.Value()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m[k] = convertedValue
|
||||
}
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (d *Driver) DoDelete(ctx context.Context, link gdb.Link, table string, condition string, args ...interface{}) (result sql.Result, err error) {
|
||||
ctx = d.injectNeedParsedSql(ctx)
|
||||
return d.Core.DoDelete(ctx, link, table, condition, args...)
|
||||
}
|
||||
|
||||
func (d *Driver) DoUpdate(ctx context.Context, link gdb.Link, table string, data interface{}, condition string, args ...interface{}) (result sql.Result, err error) {
|
||||
ctx = d.injectNeedParsedSql(ctx)
|
||||
return d.Core.DoUpdate(ctx, link, table, data, condition, args...)
|
||||
}
|
||||
|
||||
// InsertIgnore Other queries for modifying data parts are not supported: REPLACE, MERGE, UPSERT, INSERT UPDATE.
|
||||
func (d *Driver) InsertIgnore(ctx context.Context, table string, data interface{}, batch ...int) (sql.Result, error) {
|
||||
return nil, errUnsupportedInsertIgnore
|
||||
}
|
||||
|
||||
// InsertAndGetId Other queries for modifying data parts are not supported: REPLACE, MERGE, UPSERT, INSERT UPDATE.
|
||||
func (d *Driver) InsertAndGetId(ctx context.Context, table string, data interface{}, batch ...int) (int64, error) {
|
||||
return 0, errUnsupportedInsertGetId
|
||||
}
|
||||
|
||||
// Replace Other queries for modifying data parts are not supported: REPLACE, MERGE, UPSERT, INSERT UPDATE.
|
||||
func (d *Driver) Replace(ctx context.Context, table string, data interface{}, batch ...int) (sql.Result, error) {
|
||||
return nil, errUnsupportedReplace
|
||||
}
|
||||
|
||||
func (d *Driver) Begin(ctx context.Context) (tx *gdb.TX, err error) {
|
||||
return nil, errUnsupportedBegin
|
||||
}
|
||||
|
||||
func (d *Driver) Transaction(ctx context.Context, f func(ctx context.Context, tx *gdb.TX) error) error {
|
||||
return errUnsupportedTransaction
|
||||
}
|
||||
|
||||
func (d *Driver) injectNeedParsedSql(ctx context.Context) context.Context {
|
||||
if ctx.Value(needParsedSqlInCtx) != nil {
|
||||
return ctx
|
||||
}
|
||||
return context.WithValue(ctx, needParsedSqlInCtx, true)
|
||||
}
|
||||
|
||||
func (d *Driver) getNeedParsedSqlFromCtx(ctx context.Context) bool {
|
||||
if ctx.Value(needParsedSqlInCtx) != nil {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
542
contrib/drivers/clickhouse/clickhouse_test.go
Normal file
542
contrib/drivers/clickhouse/clickhouse_test.go
Normal file
@ -0,0 +1,542 @@
|
||||
package clickhouse
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
"github.com/gogf/gf/v2/util/guid"
|
||||
"github.com/google/uuid"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"github.com/gogf/gf/v2/util/grand"
|
||||
)
|
||||
|
||||
const (
|
||||
sqlVisitsDDL = `
|
||||
CREATE TABLE IF NOT EXISTS visits (
|
||||
id UInt64,
|
||||
duration Float64,
|
||||
url String,
|
||||
created DateTime
|
||||
) ENGINE = MergeTree()
|
||||
PRIMARY KEY id
|
||||
ORDER BY id
|
||||
`
|
||||
dimSqlDDL = `
|
||||
CREATE TABLE IF NOT EXISTS dim (
|
||||
"code" String COMMENT '编码',
|
||||
"translation" String COMMENT '译文',
|
||||
"superior" UInt64 COMMENT '上级ID',
|
||||
"row_number" UInt16 COMMENT '行号',
|
||||
"is_active" UInt8 COMMENT '是否激活',
|
||||
"is_preset" UInt8 COMMENT '是否预置',
|
||||
"category" String COMMENT '类别',
|
||||
"tree_path" Array(String) COMMENT '树路径',
|
||||
"id" UInt64 COMMENT '代理主键ID',
|
||||
"scd" UInt64 COMMENT '缓慢变化维ID',
|
||||
"version" UInt64 COMMENT 'Merge版本ID',
|
||||
"sign" Int8 COMMENT '标识位',
|
||||
"created_by" UInt64 COMMENT '创建者ID',
|
||||
"created_at" DateTime64(3,'Asia/Shanghai') COMMENT '创建时间',
|
||||
"updated_by" UInt64 COMMENT '最后修改者ID',
|
||||
"updated_at" DateTime64(3,'Asia/Shanghai') COMMENT '最后修改时间',
|
||||
"updated_tick" UInt16 COMMENT '累计修改次数'
|
||||
) ENGINE = ReplacingMergeTree("version")
|
||||
ORDER BY ("id","scd")
|
||||
COMMENT '会计准则';
|
||||
`
|
||||
dimSqlDML = `
|
||||
insert into dim (code, translation, superior, row_number, is_active, is_preset, category, tree_path, id, scd, version, sign, created_by, created_at, updated_by, updated_at, updated_tick)
|
||||
values ('CN', '{"zh_CN":"中国大陆会计准则","en_US":"Chinese mainland accounting legislation"}', 0, 1, 1, 1, 1, '[''CN'']', 607972403489804288, 0, 0, 0, 607536279118155777, '2017-09-06 00:00:00', 607536279118155777, '2017-09-06 00:00:00', 0),
|
||||
('HK', '{"zh_CN":"中国香港会计准则","en_US":"Chinese Hong Kong accounting legislation"}', 0, 2, 1, 1, 1, '[''HK'']', 607972558544834566, 0, 0, 0, 607536279118155777, '2017-09-06 00:00:00', 607536279118155777, '2017-09-06 00:00:00', 0);
|
||||
`
|
||||
factSqlDDL = `
|
||||
CREATE TABLE IF NOT EXISTS fact (
|
||||
"adjustment_level" UInt64 COMMENT '调整层ID',
|
||||
"data_version" UInt64 COMMENT '数据版本ID',
|
||||
"accounting_legislation" UInt64 COMMENT '会计准则ID',
|
||||
"fiscal_year" UInt16 COMMENT '会计年度',
|
||||
"fiscal_period" UInt8 COMMENT '会计期间',
|
||||
"fiscal_year_period" UInt32 COMMENT '会计年度期间',
|
||||
"legal_entity" UInt64 COMMENT '法人主体ID',
|
||||
"cost_center" UInt64 COMMENT '成本中心ID',
|
||||
"legal_entity_partner" UInt64 COMMENT '内部关联方ID',
|
||||
"financial_posting" UInt64 COMMENT '凭证头ID',
|
||||
"line" UInt16 COMMENT '行号',
|
||||
"general_ledger_account" UInt64 COMMENT '总账科目ID',
|
||||
"debit" Decimal64(9) COMMENT '借方金额',
|
||||
"credit" Decimal64(9) COMMENT '贷方金额',
|
||||
"transaction_currency" UInt64 COMMENT '交易币种ID',
|
||||
"debit_tc" Decimal64(9) COMMENT '借方金额(交易币种)',
|
||||
"credit_tc" Decimal64(9) COMMENT '贷方金额(交易币种)',
|
||||
"posting_date" Date32 COMMENT '过账日期',
|
||||
"gc_year" UInt16 COMMENT '公历年',
|
||||
"gc_quarter" UInt8 COMMENT '公历季',
|
||||
"gc_month" UInt8 COMMENT '公历月',
|
||||
"gc_week" UInt8 COMMENT '公历周',
|
||||
"raw_info" String COMMENT '源信息',
|
||||
"summary" String COMMENT '摘要',
|
||||
"id" UInt64 COMMENT '代理主键ID',
|
||||
"version" UInt64 COMMENT 'Merge版本ID',
|
||||
"sign" Int8 COMMENT '标识位'
|
||||
) ENGINE = ReplacingMergeTree("version")
|
||||
ORDER BY ("adjustment_level","data_version","legal_entity","fiscal_year","fiscal_period","financial_posting","line")
|
||||
PARTITION BY ("adjustment_level","data_version","legal_entity","fiscal_year","fiscal_period")
|
||||
COMMENT '数据主表';
|
||||
`
|
||||
factSqlDML = `
|
||||
insert into fact (adjustment_level, data_version, accounting_legislation, fiscal_year, fiscal_period, fiscal_year_period, legal_entity, cost_center, legal_entity_partner, financial_posting, line, general_ledger_account, debit, credit, transaction_currency, debit_tc, credit_tc, posting_date, gc_year, gc_quarter, gc_month, gc_week, raw_info, summary, id, version, sign)
|
||||
values (607970943242866688, 607973669943119880, 607972403489804288, 2022, 3, 202203, 607974511316307985, 0, 607976190010986520, 607996702456025136, 1, 607985607569838111, 8674.39, 0, 607974898261823505, 8674.39, 0, '2022-03-05', 2022, 1, 3, 11, '{}', '摘要', 607992882741121073, 0, 0),
|
||||
(607970943242866688, 607973669943119880, 607972403489804288, 2022, 4, 202204, 607974511316307985, 0, 607976190010986520, 607993586419503145, 1, 607985607569838111, 9999.88, 0, 607974898261823505, 9999.88, 0, '2022-04-10', 2022, 2, 4, 18, '{}', '摘要', 607996939140599857, 0, 0);
|
||||
`
|
||||
expmSqlDDL = `
|
||||
CREATE TABLE IF NOT EXISTS data_type (
|
||||
Col1 UInt8 COMMENT '列1'
|
||||
, Col2 Nullable(String) COMMENT '列2'
|
||||
, Col3 FixedString(3) COMMENT '列3'
|
||||
, Col4 String COMMENT '列4'
|
||||
, Col5 Map(String, UInt8) COMMENT '列5'
|
||||
, Col6 Array(String) COMMENT '列6'
|
||||
, Col7 Tuple(String, UInt8, Array(Map(String, String))) COMMENT '列7'
|
||||
, Col8 DateTime COMMENT '列8'
|
||||
, Col9 UUID COMMENT '列9'
|
||||
, Col10 DateTime COMMENT '列10'
|
||||
) ENGINE = MergeTree()
|
||||
PRIMARY KEY Col4
|
||||
ORDER BY Col4
|
||||
`
|
||||
)
|
||||
|
||||
func clickhouseConfigDB() gdb.DB {
|
||||
connect, err := gdb.New(gdb.ConfigNode{
|
||||
Host: "127.0.0.1",
|
||||
Port: "9000",
|
||||
User: "default",
|
||||
Name: "default",
|
||||
Type: "clickhouse",
|
||||
Debug: true,
|
||||
})
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertNE(connect, nil)
|
||||
return connect
|
||||
}
|
||||
|
||||
func createClickhouseTableVisits(connect gdb.DB) error {
|
||||
_, err := connect.Exec(context.Background(), sqlVisitsDDL)
|
||||
return err
|
||||
}
|
||||
|
||||
func createClickhouseTableDim(connect gdb.DB) error {
|
||||
_, err := connect.Exec(context.Background(), dimSqlDDL)
|
||||
return err
|
||||
}
|
||||
|
||||
func createClickhouseTableFact(connect gdb.DB) error {
|
||||
_, err := connect.Exec(context.Background(), factSqlDDL)
|
||||
return err
|
||||
}
|
||||
|
||||
func createClickhouseExampleTable(connect gdb.DB) error {
|
||||
_, err := connect.Exec(context.Background(), expmSqlDDL)
|
||||
return err
|
||||
}
|
||||
|
||||
func dropClickhouseTableVisits(conn gdb.DB) {
|
||||
sqlStr := fmt.Sprintf("DROP TABLE IF EXISTS `visits`")
|
||||
_, _ = conn.Exec(context.Background(), sqlStr)
|
||||
}
|
||||
|
||||
func dropClickhouseTableDim(conn gdb.DB) {
|
||||
sqlStr := fmt.Sprintf("DROP TABLE IF EXISTS `dim`")
|
||||
_, _ = conn.Exec(context.Background(), sqlStr)
|
||||
}
|
||||
|
||||
func dropClickhouseTableFact(conn gdb.DB) {
|
||||
sqlStr := fmt.Sprintf("DROP TABLE IF EXISTS `fact`")
|
||||
_, _ = conn.Exec(context.Background(), sqlStr)
|
||||
}
|
||||
|
||||
func dropClickhouseExampleTable(conn gdb.DB) {
|
||||
sqlStr := fmt.Sprintf("DROP TABLE IF EXISTS `data_type`")
|
||||
_, _ = conn.Exec(context.Background(), sqlStr)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_Create(t *testing.T) {
|
||||
gtest.AssertNil(createClickhouseTableVisits(clickhouseConfigDB()))
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_New(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertNE(connect, nil)
|
||||
gtest.AssertNil(connect.PingMaster())
|
||||
gtest.AssertNil(connect.PingSlave())
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_OpenLink_Ping(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertNE(connect, nil)
|
||||
gtest.AssertNil(connect.PingMaster())
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_Tables(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertEQ(createClickhouseTableVisits(connect), nil)
|
||||
defer dropClickhouseTableVisits(connect)
|
||||
tables, err := connect.Tables(context.Background())
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertNE(len(tables), 0)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_TableFields_Use_Config(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertNil(createClickhouseTableVisits(connect))
|
||||
defer dropClickhouseTableVisits(connect)
|
||||
field, err := connect.TableFields(context.Background(), "visits")
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertEQ(len(field), 4)
|
||||
gtest.AssertNQ(field, nil)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_TableFields_Use_Link(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertNil(createClickhouseTableVisits(connect))
|
||||
defer dropClickhouseTableVisits(connect)
|
||||
field, err := connect.TableFields(context.Background(), "visits")
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertEQ(len(field), 4)
|
||||
gtest.AssertNQ(field, nil)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_Transaction(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
defer dropClickhouseTableVisits(connect)
|
||||
gtest.AssertNE(connect.Transaction(context.Background(), func(ctx context.Context, tx *gdb.TX) error {
|
||||
return nil
|
||||
}), nil)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_InsertIgnore(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
_, err := connect.InsertIgnore(context.Background(), "", nil)
|
||||
gtest.AssertEQ(err, errUnsupportedInsertIgnore)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_InsertAndGetId(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
_, err := connect.InsertAndGetId(context.Background(), "", nil)
|
||||
gtest.AssertEQ(err, errUnsupportedInsertGetId)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_InsertOne(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertEQ(createClickhouseTableVisits(connect), nil)
|
||||
defer dropClickhouseTableVisits(connect)
|
||||
_, err := connect.Model("visits").Data(g.Map{
|
||||
"duration": float64(grand.Intn(999)),
|
||||
"url": gconv.String(grand.Intn(999)),
|
||||
"created": time.Now(),
|
||||
}).Insert()
|
||||
gtest.AssertNil(err)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_InsertMany(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertEQ(createClickhouseTableVisits(connect), nil)
|
||||
defer dropClickhouseTableVisits(connect)
|
||||
tx, err := connect.Begin(context.Background())
|
||||
gtest.AssertEQ(err, errUnsupportedBegin)
|
||||
gtest.AssertNil(tx)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_Insert(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertEQ(createClickhouseTableVisits(connect), nil)
|
||||
defer dropClickhouseTableVisits(connect)
|
||||
type insertItem struct {
|
||||
Id uint64 `orm:"id"`
|
||||
Duration float64 `orm:"duration"`
|
||||
Url string `orm:"url"`
|
||||
Created time.Time `orm:"created"`
|
||||
}
|
||||
var (
|
||||
insertUrl = "https://goframe.org"
|
||||
total = 0
|
||||
item = insertItem{
|
||||
Duration: 1,
|
||||
Url: insertUrl,
|
||||
Created: time.Now(),
|
||||
}
|
||||
)
|
||||
_, err := connect.Model("visits").Data(item).Insert()
|
||||
gtest.AssertNil(err)
|
||||
_, err = connect.Model("visits").Data(item).Save()
|
||||
gtest.AssertNil(err)
|
||||
total, err = connect.Model("visits").Count()
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertEQ(total, 2)
|
||||
var list []*insertItem
|
||||
for i := 0; i < 50; i++ {
|
||||
list = append(list, &insertItem{
|
||||
Duration: float64(grand.Intn(999)),
|
||||
Url: insertUrl,
|
||||
Created: time.Now(),
|
||||
})
|
||||
}
|
||||
_, err = connect.Model("visits").Data(list).Insert()
|
||||
gtest.AssertNil(err)
|
||||
_, err = connect.Model("visits").Data(list).Save()
|
||||
gtest.AssertNil(err)
|
||||
total, err = connect.Model("visits").Count()
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertEQ(total, 102)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_Insert_Use_Exec(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertEQ(createClickhouseTableFact(connect), nil)
|
||||
defer dropClickhouseTableFact(connect)
|
||||
_, err := connect.Exec(context.Background(), factSqlDML)
|
||||
gtest.AssertNil(err)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_Delete(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertEQ(createClickhouseTableVisits(connect), nil)
|
||||
defer dropClickhouseTableVisits(connect)
|
||||
_, err := connect.Model("visits").Where("created >", "2021-01-01 00:00:00").Delete()
|
||||
gtest.AssertNil(err)
|
||||
_, err = connect.Model("visits").
|
||||
Where("created >", "2021-01-01 00:00:00").
|
||||
Where("duration > ", 0).
|
||||
Where("url is not null").
|
||||
Delete()
|
||||
gtest.AssertNil(err)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_Update(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertEQ(createClickhouseTableVisits(connect), nil)
|
||||
defer dropClickhouseTableVisits(connect)
|
||||
_, err := connect.Model("visits").Where("created > ", "2021-01-01 15:15:15").Data(g.Map{
|
||||
"created": time.Now().Format("2006-01-02 15:04:05"),
|
||||
}).Update()
|
||||
gtest.AssertNil(err)
|
||||
_, err = connect.Model("visits").
|
||||
Where("created > ", "2021-01-01 15:15:15").
|
||||
Where("duration > ", 0).
|
||||
Where("url is not null").
|
||||
Data(g.Map{
|
||||
"created": time.Now().Format("2006-01-02 15:04:05"),
|
||||
}).Update()
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_Replace(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
_, err := connect.Replace(context.Background(), "", nil)
|
||||
gtest.AssertEQ(err, errUnsupportedReplace)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_DoFilter(t *testing.T) {
|
||||
rawSQL := "select * from visits where 1 = 1"
|
||||
this := Driver{}
|
||||
replaceSQL, _, err := this.DoFilter(context.Background(), nil, rawSQL, []interface{}{1})
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertEQ(rawSQL, replaceSQL)
|
||||
|
||||
// this SQL can't run ,clickhouse will report an error because there is no WHERE statement
|
||||
rawSQL = "update visit set url = '1'"
|
||||
replaceSQL, _, err = this.DoFilter(context.Background(), nil, rawSQL, []interface{}{1})
|
||||
gtest.AssertNil(err)
|
||||
|
||||
// this SQL can't run ,clickhouse will report an error because there is no WHERE statement
|
||||
rawSQL = "delete from visit"
|
||||
replaceSQL, _, err = this.DoFilter(context.Background(), nil, rawSQL, []interface{}{1})
|
||||
gtest.AssertNil(err)
|
||||
|
||||
ctx := this.injectNeedParsedSql(context.Background())
|
||||
rawSQL = "UPDATE visit SET url = '1' WHERE url = '0'"
|
||||
replaceSQL, _, err = this.DoFilter(ctx, nil, rawSQL, []interface{}{1})
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertEQ(replaceSQL, "ALTER TABLE visit UPDATE url = '1' WHERE url = '0'")
|
||||
|
||||
rawSQL = "DELETE FROM visit WHERE url = '0'"
|
||||
replaceSQL, _, err = this.DoFilter(ctx, nil, rawSQL, []interface{}{1})
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertEQ(replaceSQL, "ALTER TABLE visit DELETE WHERE url = '0'")
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_Select(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertNil(createClickhouseTableVisits(connect))
|
||||
defer dropClickhouseTableVisits(connect)
|
||||
_, err := connect.Model("visits").Data(g.Map{
|
||||
"url": "goframe.org",
|
||||
"duration": float64(1),
|
||||
}).Insert()
|
||||
gtest.AssertNil(err)
|
||||
temp, err := connect.Model("visits").Where("url", "goframe.org").Where("duration >= ", 1).One()
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertEQ(temp.IsEmpty(), false)
|
||||
_, err = connect.Model("visits").Data(g.Map{
|
||||
"url": "goframe.org",
|
||||
"duration": float64(2),
|
||||
}).Insert()
|
||||
gtest.AssertNil(err)
|
||||
data, err := connect.Model("visits").Where("url", "goframe.org").Where("duration >= ", 1).All()
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertEQ(len(data), 2)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_Exec_OPTIMIZE(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertNil(createClickhouseTableVisits(connect))
|
||||
defer dropClickhouseTableVisits(connect)
|
||||
sqlStr := "OPTIMIZE table visits"
|
||||
_, err := connect.Exec(context.Background(), sqlStr)
|
||||
gtest.AssertNil(err)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_ExecInsert(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertEQ(createClickhouseTableDim(connect), nil)
|
||||
defer dropClickhouseTableDim(connect)
|
||||
_, err := connect.Exec(context.Background(), dimSqlDML)
|
||||
gtest.AssertNil(err)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_NilTime(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertNil(createClickhouseExampleTable(connect))
|
||||
defer dropClickhouseExampleTable(connect)
|
||||
type testNilTime struct {
|
||||
Col1 uint8
|
||||
Col2 string
|
||||
Col3 string
|
||||
Col4 string
|
||||
Col5 map[string]uint8
|
||||
Col6 []string
|
||||
Col7 []interface{}
|
||||
Col8 *time.Time
|
||||
Col9 uuid.UUID
|
||||
Col10 *gtime.Time
|
||||
}
|
||||
insertData := []*testNilTime{}
|
||||
for i := 0; i < 10000; i++ {
|
||||
insertData = append(insertData, &testNilTime{
|
||||
Col4: "Inc.",
|
||||
Col9: uuid.New(),
|
||||
Col7: []interface{}{ // Tuple(String, UInt8, Array(Map(String, String)))
|
||||
"String Value", uint8(5), []map[string]string{
|
||||
map[string]string{"key": "value"},
|
||||
map[string]string{"key": "value"},
|
||||
map[string]string{"key": "value"},
|
||||
}},
|
||||
})
|
||||
}
|
||||
_, err := connect.Model("data_type").Data(insertData).Insert()
|
||||
gtest.AssertNil(err)
|
||||
count, err := connect.Model("data_type").Where("Col4", "Inc.").Count()
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertEQ(count, 10000)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_BatchInsert(t *testing.T) {
|
||||
// example from
|
||||
// https://github.com/ClickHouse/clickhouse-go/blob/v2/examples/std/batch/main.go
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertNil(createClickhouseExampleTable(connect))
|
||||
defer dropClickhouseExampleTable(connect)
|
||||
insertData := []g.Map{}
|
||||
for i := 0; i < 10000; i++ {
|
||||
insertData = append(insertData, g.Map{
|
||||
"Col1": uint8(42),
|
||||
"Col2": "ClickHouse",
|
||||
"Col3": "Inc",
|
||||
"Col4": guid.S(),
|
||||
"Col5": map[string]uint8{"key": 1}, // Map(String, UInt8)
|
||||
"Col6": []string{"Q", "W", "E", "R", "T", "Y"}, // Array(String)
|
||||
"Col7": []interface{}{ // Tuple(String, UInt8, Array(Map(String, String)))
|
||||
"String Value", uint8(5), []map[string]string{
|
||||
map[string]string{"key": "value"},
|
||||
map[string]string{"key": "value"},
|
||||
map[string]string{"key": "value"},
|
||||
},
|
||||
},
|
||||
"Col8": gtime.Now(),
|
||||
"Col9": uuid.New(),
|
||||
"Col10": nil,
|
||||
})
|
||||
}
|
||||
_, err := connect.Model("data_type").Data(insertData).Insert()
|
||||
gtest.AssertNil(err)
|
||||
count, err := connect.Model("data_type").Where("Col2", "ClickHouse").Where("Col3", "Inc").Count()
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertEQ(count, 10000)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_Open(t *testing.T) {
|
||||
// link
|
||||
// DSM
|
||||
// clickhouse://username:password@host1:9000,host2:9000/database?dial_timeout=200ms&max_execution_time=60
|
||||
link := "clickhouse://default@127.0.0.1:9000,127.0.0.1:9000/default?dial_timeout=200ms&max_execution_time=60"
|
||||
db, err := gdb.New(gdb.ConfigNode{
|
||||
Link: link,
|
||||
Type: "clickhouse",
|
||||
})
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertNil(db.PingMaster())
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_ReplaceConfig(t *testing.T) {
|
||||
db := &Driver{}
|
||||
// parse link's name set to config
|
||||
c1 := &gdb.ConfigNode{}
|
||||
c1.Link = "clickhouse://default@127.0.0.1:9000,127.0.0.1:9000/default?dial_timeout=200ms&max_execution_time=60"
|
||||
_, _ = db.Open(c1)
|
||||
gtest.AssertEQ(c1.Name, "default")
|
||||
// replace link's name from config
|
||||
c2 := &gdb.ConfigNode{}
|
||||
c2.Name = "clickhouseJohn"
|
||||
c2.Link = "clickhouse://default@127.0.0.1:9000,127.0.0.1:9000/default?dial_timeout=200ms&max_execution_time=60"
|
||||
_, _ = db.Open(c2)
|
||||
gtest.AssertEQ(strings.Contains(c2.Link, "clickhouseJohn"), true)
|
||||
}
|
||||
|
||||
func TestDriverClickhouse_TableFields(t *testing.T) {
|
||||
connect := clickhouseConfigDB()
|
||||
gtest.AssertNil(createClickhouseExampleTable(connect))
|
||||
defer dropClickhouseExampleTable(connect)
|
||||
dataTypeTable, err := connect.TableFields(context.Background(), "data_type")
|
||||
gtest.AssertNil(err)
|
||||
gtest.AssertNE(dataTypeTable, nil)
|
||||
|
||||
var result = map[string][]interface{}{
|
||||
"Col1": {1, "Col1", "UInt8", false, "", "", "", "列1"},
|
||||
"Col2": {2, "Col2", "String", true, "", "", "", "列2"},
|
||||
"Col3": {3, "Col3", "FixedString(3)", false, "", "", "", "列3"},
|
||||
"Col4": {4, "Col4", "String", false, "", "", "", "列4"},
|
||||
"Col5": {5, "Col5", "Map(String, UInt8)", false, "", "", "", "列5"},
|
||||
"Col6": {6, "Col6", "Array(String)", false, "", "", "", "列6"},
|
||||
"Col7": {7, "Col7", "Tuple(String, UInt8, Array(Map(String, String)))", false, "", "", "", "列7"},
|
||||
"Col8": {8, "Col8", "DateTime", false, "", "", "", "列8"},
|
||||
"Col9": {9, "Col9", "UUID", false, "", "", "", "列9"},
|
||||
"Col10": {10, "Col10", "DateTime", false, "", "", "", "列10"},
|
||||
}
|
||||
for k, v := range result {
|
||||
_, ok := dataTypeTable[k]
|
||||
gtest.AssertEQ(ok, true)
|
||||
gtest.AssertEQ(dataTypeTable[k].Index, v[0])
|
||||
gtest.AssertEQ(dataTypeTable[k].Name, v[1])
|
||||
gtest.AssertEQ(dataTypeTable[k].Type, v[2])
|
||||
gtest.AssertEQ(dataTypeTable[k].Null, v[3])
|
||||
gtest.AssertEQ(dataTypeTable[k].Key, v[4])
|
||||
gtest.AssertEQ(dataTypeTable[k].Default, v[5])
|
||||
gtest.AssertEQ(dataTypeTable[k].Comment, v[7])
|
||||
}
|
||||
}
|
||||
@ -3,11 +3,13 @@ module github.com/gogf/gf/contrib/drivers/clickhouse/v2
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/ClickHouse/clickhouse-go v1.5.2
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/stretchr/testify v1.7.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.0.14
|
||||
github.com/gogf/gf/v2 v2.0.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
github.com/ClickHouse/clickhouse-go/v2 => github.com/gogf/clickhouse-go/v2 v2.0.14-compatible
|
||||
github.com/gogf/gf/v2 => ../../../
|
||||
)
|
||||
|
||||
@ -1,32 +1,217 @@
|
||||
github.com/ClickHouse/clickhouse-go v1.5.2 h1:yXgaOZ8WEHrd+okvZXjzulSt1zS33nM4ujfx9lVncl8=
|
||||
github.com/ClickHouse/clickhouse-go v1.5.2/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk=
|
||||
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0=
|
||||
github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
|
||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||
github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E=
|
||||
github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/gogf/clickhouse-go/v2 v2.0.14-compatible h1:eTT+USRgOZyTXyHyIFzJU+utFUsNVPmrzmQaKS9zdoM=
|
||||
github.com/gogf/clickhouse-go/v2 v2.0.14-compatible/go.mod h1:NdPxn4Kfffa6Tv14otrFtbV+zH6v2xHVfDf4KICt/0s=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0=
|
||||
github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
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/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
|
||||
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mkevac/debugcharts v0.0.0-20191222103121-ae1c48aa8615/go.mod h1:Ad7oeElCZqA1Ufj0U9/liOF4BtVepxRcTvr2ey7zTvM=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ=
|
||||
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
||||
github.com/paulmach/orb v0.7.0 h1:l6uxkg+vRU9QJkBHtzvYpkVb09tCIRwnEHbY5MNMNqo=
|
||||
github.com/paulmach/orb v0.7.0/go.mod h1:FWRlTgl88VI1RBx/MkrwWDRhQ96ctqMCh8boXhmqB/A=
|
||||
github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
|
||||
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/pierrec/lz4/v4 v4.1.14 h1:+fL8AQEZtz/ijeNnpduH0bROTu0O3NZAlPjQxGn8LwE=
|
||||
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/shirou/gopsutil v2.19.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
|
||||
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
|
||||
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM=
|
||||
go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk=
|
||||
go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0=
|
||||
go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU=
|
||||
go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o=
|
||||
go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220220014-0732a990476f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220429233432-b5fbb4746d32 h1:Js08h5hqB5xyWR789+QqueR6sDE8mk+YvpETZ+F6X9Y=
|
||||
golang.org/x/sys v0.0.0-20220429233432-b5fbb4746d32/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba h1:AyHWHCBVlIYI5rgEM3o+1PLd0sLPcIAoaUckGQMaWtw=
|
||||
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 h1:GLw7MR8AfAG2GmGcmVgObFOHXYypgGjnGno25RDwn3Y=
|
||||
golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@ -4,7 +4,7 @@ go 1.15
|
||||
|
||||
require (
|
||||
github.com/denisenkom/go-mssqldb v0.11.0
|
||||
github.com/gogf/gf/v2 v2.0.0-rc
|
||||
github.com/gogf/gf/v2 v2.0.0
|
||||
)
|
||||
|
||||
replace github.com/gogf/gf/v2 => ../../../
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
|
||||
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E=
|
||||
github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -15,12 +18,15 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
|
||||
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
@ -38,13 +44,17 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0=
|
||||
github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
|
||||
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
@ -59,26 +69,30 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ=
|
||||
github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
|
||||
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
|
||||
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.opentelemetry.io/otel v1.0.0 h1:qTTn6x71GVBvoafHK/yaRUmFzI4LcONZD0/kXxl5PHI=
|
||||
go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
|
||||
go.opentelemetry.io/otel/sdk v1.0.0 h1:BNPMYUONPNbLneMttKSjQhOTlFLOD9U22HNG1KrIN2Y=
|
||||
go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM=
|
||||
go.opentelemetry.io/otel/trace v1.0.0 h1:TSBr8GTEtKevYMG/2d21M989r5WJYVimhTHBKVEZuh4=
|
||||
go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
|
||||
go.opentelemetry.io/otel v1.7.0 h1:Z2lA3Tdch0iDcrhJXDIlC94XE+bxok1F9B+4Lz/lGsM=
|
||||
go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk=
|
||||
go.opentelemetry.io/otel/sdk v1.7.0 h1:4OmStpcKVOfvDOgCt7UriAPtKolwIhxpnSNI/yK+1B0=
|
||||
go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU=
|
||||
go.opentelemetry.io/otel/trace v1.7.0 h1:O37Iogk1lEkMRXewVtZ1BBTVn5JEp8GrJvP92bJqC6o=
|
||||
go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@ -105,6 +119,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -114,8 +129,10 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
||||
@ -13,14 +13,14 @@
|
||||
package mssql
|
||||
|
||||
import (
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gmap"
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
@ -66,6 +66,10 @@ func (d *Driver) Open(config *gdb.ConfigNode) (db *sql.DB, err error) {
|
||||
)
|
||||
if config.Link != "" {
|
||||
source = config.Link
|
||||
// Custom changing the schema in runtime.
|
||||
if config.Name != "" {
|
||||
source, _ = gregex.ReplaceString(`database=([\w\.\-]+)+`, "database="+config.Name, source)
|
||||
}
|
||||
} else {
|
||||
source = fmt.Sprintf(
|
||||
"user id=%s;password=%s;server=%s;port=%s;database=%s;encrypt=disable",
|
||||
@ -100,7 +104,7 @@ func (d *Driver) FilteredLink() string {
|
||||
|
||||
// GetChars returns the security char for this type of database.
|
||||
func (d *Driver) GetChars() (charLeft string, charRight string) {
|
||||
return "\"", "\""
|
||||
return `"`, `"`
|
||||
}
|
||||
|
||||
// DoFilter deals with the sql string before commits it to underlying sql driver.
|
||||
@ -223,7 +227,7 @@ func (d *Driver) Tables(ctx context.Context, schema ...string) (tables []string,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err = d.DoGetAll(ctx, link, `SELECT NAME FROM SYSOBJECTS WHERE XTYPE='U' AND STATUS >= 0 ORDER BY NAME`)
|
||||
result, err = d.DoSelect(ctx, link, `SELECT NAME FROM SYSOBJECTS WHERE XTYPE='U' AND STATUS >= 0 ORDER BY NAME`)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -289,13 +293,14 @@ ORDER BY a.id,a.colorder`,
|
||||
table,
|
||||
)
|
||||
structureSql, _ = gregex.ReplaceString(`[\n\r\s]+`, " ", gstr.Trim(structureSql))
|
||||
result, err = d.DoGetAll(ctx, link, structureSql)
|
||||
result, err = d.DoSelect(ctx, link, structureSql)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
fields = make(map[string]*gdb.TableField)
|
||||
for i, m := range result {
|
||||
fields[strings.ToLower(m["Field"].String())] = &gdb.TableField{
|
||||
|
||||
fields[m["Field"].String()] = &gdb.TableField{
|
||||
Index: i,
|
||||
Name: m["Field"].String(),
|
||||
Type: m["Type"].String(),
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user