mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
Replace TiDB with SQLite for improved stability #66
As a side effect, we need less configuration values. Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
@@ -8,11 +8,13 @@
|
||||
/assets/resources/nsfw
|
||||
/assets/testdata
|
||||
/assets/backups
|
||||
Dockerfile
|
||||
/photoprism
|
||||
docker-compose*
|
||||
/coverage.*
|
||||
/frontend/tests/acceptance/screenshots
|
||||
.dockerignore
|
||||
.idea
|
||||
.DS_Store
|
||||
/frontend/tests/acceptance/screenshots
|
||||
*.db
|
||||
*.db-journal
|
||||
Dockerfile
|
||||
docker-compose*
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -17,6 +17,8 @@
|
||||
/assets/resources/nsfw
|
||||
/package-lock.json
|
||||
*.log
|
||||
*.db
|
||||
*.db-journal
|
||||
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
|
||||
3
Makefile
3
Makefile
@@ -96,8 +96,9 @@ acceptance-firefox:
|
||||
$(info Running JS acceptance tests in Firefox...)
|
||||
(cd frontend && npm run acceptance-firefox)
|
||||
reset-test-db:
|
||||
$(info Purging test database...)
|
||||
$(info Purging test databases...)
|
||||
mysql < scripts/reset-test-db.sql
|
||||
find ./internal -type f -name '.test.*' -delete
|
||||
run-test-short:
|
||||
$(info Running short Go unit tests in parallel mode...)
|
||||
$(GOTEST) -parallel 2 -count 1 -cpu 2 -short -timeout 5m ./pkg/... ./internal/...
|
||||
|
||||
@@ -18,11 +18,7 @@ import-path: ~/Pictures/Import
|
||||
http-host:
|
||||
http-mode: release
|
||||
http-port: 2342
|
||||
tidb-host: localhost
|
||||
tidb-port: 2343
|
||||
tidb-password: photoprism
|
||||
database-driver: tidb
|
||||
database-dsn: root:photoprism@tcp(localhost:2343)/photoprism?parseTime=true
|
||||
database-driver: sqlite
|
||||
pid-filename: ~/.local/share/photoprism/photoprism.pid
|
||||
log-filename: ~/.local/share/photoprism/photoprism.log
|
||||
detach-server: false
|
||||
|
||||
@@ -22,12 +22,9 @@ services:
|
||||
PHOTOPRISM_DETACH_SERVER: "true"
|
||||
PHOTOPRISM_HTTP_HOST: "0.0.0.0"
|
||||
PHOTOPRISM_HTTP_PORT: 2342
|
||||
PHOTOPRISM_TIDB_HOST: "0.0.0.0"
|
||||
PHOTOPRISM_TIDB_PORT: 2343
|
||||
PHOTOPRISM_TIDB_PASSWORD: "photoprism"
|
||||
PHOTOPRISM_DATABASE_DRIVER: "tidb"
|
||||
PHOTOPRISM_DATABASE_DSN: "root:photoprism@tcp(localhost:2343)/photoprism?parseTime=true"
|
||||
PHOTOPRISM_TEST_DSN: "root:photoprism@tcp(photoprism-db:4001)/photoprism?parseTime=true"
|
||||
PHOTOPRISM_DATABASE_DRIVER: "mysql"
|
||||
PHOTOPRISM_DATABASE_DSN: "root:photoprism@tcp(photoprism-db:4001)/photoprism?parseTime=true"
|
||||
PHOTOPRISM_TEST_DRIVER: "test"
|
||||
PHOTOPRISM_TITLE: "PhotoPrism"
|
||||
PHOTOPRISM_SUBTITLE: "Browse your life"
|
||||
PHOTOPRISM_DESCRIPTION: "Personal Photo Management tested by Travis CI."
|
||||
|
||||
@@ -8,7 +8,6 @@ services:
|
||||
- photoprism-db
|
||||
ports:
|
||||
- "2342:2342" # Web Server (PhotoPrism)
|
||||
- "2343:2343" # Database (built-in TiDB)
|
||||
volumes:
|
||||
- ".:/go/src/github.com/photoprism/photoprism"
|
||||
- "go-mod:/go/pkg/mod"
|
||||
@@ -25,12 +24,9 @@ services:
|
||||
PHOTOPRISM_SERVER_MODE: "debug"
|
||||
PHOTOPRISM_HTTP_HOST: "0.0.0.0"
|
||||
PHOTOPRISM_HTTP_PORT: 2342
|
||||
PHOTOPRISM_TIDB_HOST: "0.0.0.0"
|
||||
PHOTOPRISM_TIDB_PORT: 2343
|
||||
PHOTOPRISM_TIDB_PASSWORD: "photoprism"
|
||||
PHOTOPRISM_DATABASE_DRIVER: "tidb"
|
||||
PHOTOPRISM_DATABASE_DSN: "root:photoprism@tcp(localhost:2343)/photoprism?parseTime=true"
|
||||
PHOTOPRISM_TEST_DSN: "root:photoprism@tcp(photoprism-db:4001)/photoprism?parseTime=true"
|
||||
PHOTOPRISM_DATABASE_DRIVER: "mysql"
|
||||
PHOTOPRISM_DATABASE_DSN: "root:photoprism@tcp(photoprism-db:4001)/photoprism?parseTime=true"
|
||||
PHOTOPRISM_TEST_DRIVER: "test"
|
||||
PHOTOPRISM_ASSETS_PATH: "/go/src/github.com/photoprism/photoprism/assets"
|
||||
PHOTOPRISM_CACHE_PATH: "/go/src/github.com/photoprism/photoprism/assets/cache"
|
||||
PHOTOPRISM_RESOURCES_PATH: "/go/src/github.com/photoprism/photoprism/assets/resources"
|
||||
|
||||
@@ -49,7 +49,8 @@ RUN apt-get update && apt-get upgrade && \
|
||||
firefox \
|
||||
libheif-examples \
|
||||
exiftool \
|
||||
ffmpeg
|
||||
ffmpeg \
|
||||
lsof
|
||||
|
||||
# Install RAW to JPEG converter
|
||||
RUN sh -c "echo 'deb http://download.opensuse.org/repositories/graphics:/darktable/xUbuntu_18.04/ /' > /etc/apt/sources.list.d/graphics:darktable.list" && \
|
||||
@@ -122,8 +123,8 @@ COPY /docker/development/.my.cnf /root/.my.cnf
|
||||
# Set up project directory
|
||||
WORKDIR "/go/src/github.com/photoprism/photoprism"
|
||||
|
||||
# Expose HTTP port 2342 plus 2343 for TiDB and 9515 for chromedriver
|
||||
EXPOSE 2342 2343 9515
|
||||
# Expose HTTP port 2342 plus 9515 for chromedriver
|
||||
EXPOSE 2342 9515
|
||||
|
||||
# Keep container running (services can be started manually using a terminal)
|
||||
CMD tail -f /dev/null
|
||||
|
||||
@@ -56,7 +56,6 @@ ENV PATH /photoprism/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin
|
||||
|
||||
ENV PHOTOPRISM_ORIGINALS_PATH /photoprism/originals
|
||||
ENV PHOTOPRISM_IMPORT_PATH /photoprism/import
|
||||
ENV PHOTOPRISM_TIDB_PATH /photoprism/database
|
||||
ENV PHOTOPRISM_TEMP_PATH /photoprism/temp
|
||||
ENV PHOTOPRISM_CACHE_PATH /photoprism/cache
|
||||
ENV PHOTOPRISM_CONFIG_PATH /photoprism/config
|
||||
|
||||
@@ -140,7 +140,6 @@ ENV PATH /photoprism/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin
|
||||
|
||||
ENV PHOTOPRISM_ORIGINALS_PATH /photoprism/originals
|
||||
ENV PHOTOPRISM_IMPORT_PATH /photoprism/import
|
||||
ENV PHOTOPRISM_TIDB_PATH /photoprism/database
|
||||
ENV PHOTOPRISM_TEMP_PATH /photoprism/temp
|
||||
ENV PHOTOPRISM_CACHE_PATH /photoprism/cache
|
||||
ENV PHOTOPRISM_CONFIG_PATH /photoprism/config
|
||||
|
||||
@@ -13,7 +13,6 @@ services:
|
||||
- seccomp:unconfined
|
||||
ports:
|
||||
- 2342:2342 # [local port]:[container port]
|
||||
# - 2343:2343 # Database (built-in TiDB)
|
||||
healthcheck: # Optional
|
||||
test: "photoprism status"
|
||||
interval: 60s
|
||||
@@ -34,14 +33,10 @@ services:
|
||||
PHOTOPRISM_DISABLE_SETTINGS: "false"
|
||||
PHOTOPRISM_HTTP_HOST: "0.0.0.0"
|
||||
PHOTOPRISM_HTTP_PORT: 2342
|
||||
PHOTOPRISM_TIDB_HOST: "0.0.0.0"
|
||||
PHOTOPRISM_TIDB_PORT: 2343 # Port for built-in TiDB SQL server (driver "tidb")
|
||||
PHOTOPRISM_TIDB_PASSWORD: "photoprism" # Plain text only (username "root")
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "photoprism" # Plain text or bcrypt hash (escape "$" with "$$")
|
||||
PHOTOPRISM_WEBDAV_PASSWORD: "photoprism" # Plain text only (username "photoprism")
|
||||
PHOTOPRISM_DATABASE_DRIVER: "tidb" # Change to "mysql" for external MySQL or MariaDB
|
||||
PHOTOPRISM_DATABASE_DSN: "root:photoprism@tcp(localhost:2343)/photoprism?parseTime=true"
|
||||
# PHOTOPRISM_DATABASE_DRIVER: "mysql" # Using MariaDB or MySQL instead of the internal TiDB is optional
|
||||
PHOTOPRISM_DATABASE_DRIVER: "sqlite" # Change to "mysql" for external MySQL or MariaDB
|
||||
# PHOTOPRISM_DATABASE_DRIVER: "mysql" # Using MariaDB or MySQL instead of SQLite is optional
|
||||
# PHOTOPRISM_DATABASE_DSN: "photoprism:photoprism@tcp(photoprism-db:3306)/photoprism?parseTime=true"
|
||||
# PHOTOPRISM_SIDECAR_JSON: "true" # Read metadata from JSON sidecar files created by exiftool
|
||||
# PHOTOPRISM_SIDECAR_YAML: "true" # Backup photo metadata to YAML sidecar files
|
||||
@@ -58,12 +53,9 @@ services:
|
||||
- "~/Pictures/Import:/photoprism/import" # [local path]:[container path] (optional)
|
||||
- "photoprism-config:/photoprism/config" # keep settings
|
||||
- "photoprism-cache:/photoprism/cache" # keep thumbnail cache
|
||||
- "photoprism-database:/photoprism/database" # keep database files
|
||||
|
||||
volumes: # keep this
|
||||
photoprism-config:
|
||||
driver: local
|
||||
photoprism-cache:
|
||||
driver: local
|
||||
photoprism-database:
|
||||
driver: local
|
||||
|
||||
@@ -12,7 +12,6 @@ services:
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 2342:2342 # [local port]:[container port]
|
||||
# - 2343:2343 # Database (built-in TiDB)
|
||||
healthcheck: # Optional
|
||||
test: "photoprism status"
|
||||
interval: 60s
|
||||
@@ -33,14 +32,10 @@ services:
|
||||
PHOTOPRISM_DISABLE_SETTINGS: "false"
|
||||
PHOTOPRISM_HTTP_HOST: "0.0.0.0"
|
||||
PHOTOPRISM_HTTP_PORT: 2342
|
||||
PHOTOPRISM_TIDB_HOST: "0.0.0.0"
|
||||
PHOTOPRISM_TIDB_PORT: 2343 # Port for built-in TiDB SQL server (driver "tidb")
|
||||
PHOTOPRISM_TIDB_PASSWORD: "photoprism" # Plain text only (username "root")
|
||||
PHOTOPRISM_ADMIN_PASSWORD: "photoprism" # Plain text or bcrypt hash (escape "$" with "$$")
|
||||
PHOTOPRISM_WEBDAV_PASSWORD: "photoprism" # Plain text only (username "photoprism")
|
||||
PHOTOPRISM_DATABASE_DRIVER: "tidb" # Change to "mysql" for external MySQL or MariaDB
|
||||
PHOTOPRISM_DATABASE_DSN: "root:photoprism@tcp(localhost:2343)/photoprism?parseTime=true"
|
||||
# PHOTOPRISM_DATABASE_DRIVER: "mysql" # Using MariaDB or MySQL instead of the internal TiDB is optional
|
||||
PHOTOPRISM_DATABASE_DRIVER: "sqlite" # Change to "mysql" for external MySQL or MariaDB
|
||||
# PHOTOPRISM_DATABASE_DRIVER: "mysql" # Using MariaDB or MySQL instead of SQLite is optional
|
||||
# PHOTOPRISM_DATABASE_DSN: "photoprism:photoprism@tcp(photoprism-db:3306)/photoprism?parseTime=true"
|
||||
# PHOTOPRISM_SIDECAR_JSON: "true" # Read metadata from JSON sidecar files created by exiftool
|
||||
# PHOTOPRISM_SIDECAR_YAML: "true" # Backup photo metadata to YAML sidecar files
|
||||
@@ -57,9 +52,8 @@ services:
|
||||
- "~/Pictures/Import:/photoprism/import" # [local path]:[container path] (optional)
|
||||
- "photoprism-config:/photoprism/config" # keep settings
|
||||
- "photoprism-cache:/photoprism/cache" # keep thumbnail cache
|
||||
- "photoprism-database:/photoprism/database" # TiDB database files, remove if you use MariaDB or MySQL
|
||||
|
||||
# photoprism-db: # Uncomment, if you want to use MariaDB instead of the internal TiDB
|
||||
# photoprism-db: # Uncomment, if you want to use MariaDB instead of SQLite
|
||||
# image: mariadb:10.5 # Alternatively mysql:8.0
|
||||
# restart: unless-stopped
|
||||
# command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=1024 --innodb-rollback-on-timeout=ON --innodb-lock-wait-timeout=120
|
||||
@@ -76,5 +70,5 @@ volumes: # keep this
|
||||
driver: local
|
||||
photoprism-cache:
|
||||
driver: local
|
||||
photoprism-database:
|
||||
driver: local
|
||||
# photoprism-database:
|
||||
# driver: local
|
||||
|
||||
39
go.mod
39
go.mod
@@ -3,13 +3,7 @@ module github.com/photoprism/photoprism
|
||||
require (
|
||||
github.com/allegro/bigcache v1.2.1
|
||||
github.com/araddon/dateparse v0.0.0-20200409225146-d820a6159ab1
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect
|
||||
github.com/coreos/etcd v3.3.10+incompatible // indirect
|
||||
github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142 // indirect
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
|
||||
github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8 // indirect
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/djherbis/times v1.2.0
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200519064707-3cdb59fd80c7
|
||||
@@ -17,18 +11,11 @@ require (
|
||||
github.com/dsoprea/go-png-image-structure v0.0.0-20200518003737-91ceb687d379
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/gogo/protobuf v1.2.0 // indirect
|
||||
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d
|
||||
github.com/golang/protobuf v1.3.5 // indirect
|
||||
github.com/golang/snappy v0.0.1 // indirect
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c // indirect
|
||||
github.com/google/open-location-code/go v0.0.0-20191230190541-a6eb95b4d2f9
|
||||
github.com/gorilla/context v1.1.1 // indirect
|
||||
github.com/gorilla/mux v1.6.2 // indirect
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/gosimple/slug v1.9.0
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.5.1 // indirect
|
||||
github.com/jinzhu/gorm v1.9.12
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
||||
github.com/karrick/godirwalk v1.15.6
|
||||
@@ -39,50 +26,24 @@ require (
|
||||
github.com/melihmucuk/geocache v0.0.0-20160621165317-521b336a001c
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/montanaflynn/stats v0.0.0-20181214052348-945b007cb92f // indirect
|
||||
github.com/myesui/uuid v1.0.0 // indirect
|
||||
github.com/onsi/gomega v1.4.3 // indirect
|
||||
github.com/opentracing/opentracing-go v1.0.2
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/paulmach/go.geojson v1.4.0
|
||||
github.com/pingcap/errors v0.11.1
|
||||
github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e // indirect
|
||||
github.com/pingcap/parser v0.0.0-20190529073816-0550d84c65ad
|
||||
github.com/pingcap/pd v2.1.0-rc.4+incompatible
|
||||
github.com/pingcap/tidb v2.1.11+incompatible
|
||||
github.com/pingcap/tidb-tools v2.1.3-0.20190116051332-34c808eef588+incompatible
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20190512091148-babf20351dd7 // indirect
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/sevlyar/go-daemon v0.1.5
|
||||
github.com/shopspring/decimal v1.2.0 // indirect
|
||||
github.com/sirupsen/logrus v1.6.0
|
||||
github.com/soheilhy/cmux v0.1.4 // indirect
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 // indirect
|
||||
github.com/stretchr/objx v0.2.0 // indirect
|
||||
github.com/stretchr/testify v1.5.1
|
||||
github.com/studio-b12/gowebdav v0.0.0-20200303150724-9380631c29a1
|
||||
github.com/tensorflow/tensorflow v1.15.2
|
||||
github.com/tidwall/gjson v1.6.0
|
||||
github.com/tidwall/pretty v1.0.1 // indirect
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 // indirect
|
||||
github.com/twinj/uuid v1.0.0 // indirect
|
||||
github.com/uber-go/atomic v1.3.2 // indirect
|
||||
github.com/uber/jaeger-client-go v2.15.0+incompatible // indirect
|
||||
github.com/uber/jaeger-lib v1.5.0 // indirect
|
||||
github.com/ulule/deepcopier v0.0.0-20200430083143-45decc6639b6
|
||||
github.com/unrolled/render v0.0.0-20181210145518-4c664cb3ad2f // indirect
|
||||
github.com/urfave/cli v1.22.4
|
||||
go.uber.org/atomic v1.4.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 // indirect
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9 // indirect
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d // indirect
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
gopkg.in/stretchr/testify.v1 v1.2.2 // indirect
|
||||
gopkg.in/ugjka/go-tz.v2 v2.0.9
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
)
|
||||
|
||||
294
go.sum
294
go.sum
@@ -1,56 +1,18 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc=
|
||||
github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/apache/thrift v0.0.0-20161221203622-b2a4d4ae21c7 h1:Fv9bK1Q+ly/ROk4aJsVMeuIwPel4bEnD8EPiI91nZMg=
|
||||
github.com/apache/thrift v0.0.0-20161221203622-b2a4d4ae21c7/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/araddon/dateparse v0.0.0-20200409225146-d820a6159ab1 h1:TEBmxO80TM04L8IuMWk77SGL1HomBmKTdzdJLLWznxI=
|
||||
github.com/araddon/dateparse v0.0.0-20200409225146-d820a6159ab1/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
|
||||
github.com/beorn7/perks v0.0.0-20160229213445-3ac7bf7a47d1/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/blacktear23/go-proxyprotocol v0.0.0-20180807104634-af7a81e8dd0d h1:rQlvB2AYWme2bIB18r/SipGiMEVJYE9U0z+MGoU/LtQ=
|
||||
github.com/blacktear23/go-proxyprotocol v0.0.0-20180807104634-af7a81e8dd0d/go.mod h1:VKt7CNAQxpFpSDz3sXyj9hY/GbVsQCr0sB3w59nE7lU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292/go.mod h1:qRiX68mZX1lGBkTWyp3CLcenw9I94W2dLeRvMzcn9N4=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20160425231609-f8ad88b59a58/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/coreos/bbolt v1.3.1-coreos.6 h1:uTXKg9gY70s9jMAKdfljFQcuh4e/BXOM+V+d00KFj3A=
|
||||
github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.2.18+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180202092358-40e2722dffea/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142 h1:3jFq2xL4ZajGK4aZY8jz+DAF0FHjI51BXjjSwCzS1Dk=
|
||||
github.com/coreos/go-systemd v0.0.0-20181031085051-9002847aa142/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cznic/mathutil v0.0.0-20160613104831-78ad7f262603/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 h1:iwZdTE0PVqJCos1vaoKsclOGD3ADKpshg3SRtYBbwso=
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||
github.com/cznic/sortutil v0.0.0-20150617083342-4c7342852e65/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ=
|
||||
github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8 h1:LpMLYGyy67BoAFGda1NeOBQwqlv7nUXpm+rIVHGxZZ4=
|
||||
github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ=
|
||||
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/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||
github.com/djherbis/times v1.2.0 h1:xANXjsC/iBqbO00vkWlYwPWgBgEVU6m6AFYg0Pic+Mc=
|
||||
@@ -71,107 +33,47 @@ github.com/dsoprea/go-png-image-structure v0.0.0-20200518003737-91ceb687d379 h1:
|
||||
github.com/dsoprea/go-png-image-structure v0.0.0-20200518003737-91ceb687d379/go.mod h1:Tg1+KPxoNGpX2lVyapYmTNsX1VNVmlEeNqWNA0jwpsg=
|
||||
github.com/dsoprea/go-utility v0.0.0-20200512094054-1abbbc781176 h1:CfXezFYb2STGOd1+n1HshvE191zVx+QX3A1nML5xxME=
|
||||
github.com/dsoprea/go-utility v0.0.0-20200512094054-1abbbc781176/go.mod h1:95+K3z2L0mqsVYd6yveIv1lmtT3tcQQ3dVakPySffW8=
|
||||
github.com/dustin/go-humanize v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
|
||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/etcd-io/gofail v0.0.0-20180808172546-51ce9a71510a h1:QNEenQIsGDEEfFNSnN+h6hE1OwnHqTg7Dl9gEk1Cko4=
|
||||
github.com/etcd-io/gofail v0.0.0-20180808172546-51ce9a71510a/go.mod h1:49H/RkXP8pKaZy4h0d+NW16rSLhyVBt4o6VLJbmOqDE=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.6.2 h1:88crIK23zO6TqlQBt+f9FrPJNKm9ZEr7qjp9vl/d5TM=
|
||||
github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-errors/errors v1.0.2 h1:xMxH9j2fNg/L4hLn/4y3M0IUsn0M6Wbu/Uh9QlOfBh4=
|
||||
github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/overalls v0.0.0-20180201144345-22ec1a223b7c/go.mod h1:UqxAgEOt89sCiXlrc/ycnx00LVvUO/eS8tMUkWX4R7w=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-sql-driver/mysql v0.0.0-20170715192408-3955978caca4/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
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=
|
||||
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec h1:lJwO/92dFXWeXOZdoGXgptLmNLwynMSHUmU6besqtiw=
|
||||
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d h1:C/hKUcHT483btRbeGkrRjJz+Zbcj8audldIi9tRJDCc=
|
||||
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff h1:kOkM9whyQYodu09SJ6W3NCsHG7crFaJILQ22Gozp3lg=
|
||||
github.com/golang/groupcache v0.0.0-20181024230925-c65c006176ff/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
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 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20161217183710-316fb6d3f031/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
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 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/open-location-code/go v0.0.0-20191230190541-a6eb95b4d2f9 h1:6ILzS4n0F17S38XvOB1BcyzB+0BtVzU77EyuMtkMffo=
|
||||
github.com/google/open-location-code/go v0.0.0-20191230190541-a6eb95b4d2f9/go.mod h1:eJfRN6aj+kR/rnua/rw9jAgYhqoMHldQkdTi+sePRKk=
|
||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
|
||||
github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v0.0.0-20170228224354-599cba5e7b61/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
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/gosimple/slug v1.9.0 h1:r5vDcYrFz9BmfIAMC829un9hq7hKM4cHUrsv36LbEqs=
|
||||
github.com/gosimple/slug v1.9.0/go.mod h1:AMZ+sOVe65uByN3kgEyf9WEBKBCSS+dJjMX9x4vDJbg=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v0.0.0-20171020063731-82921fcf811d/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20160910222444-6b7015e65d36 h1:cwTrrTEhz13khQS3/UZMLFWwiqlcsdp/2sxFmSjAWeQ=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v0.0.0-20160910222444-6b7015e65d36/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.4.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.5.1 h1:3scN4iuXkNOyP98jF55Lv8a9j1o/IwvnDIZ0LHJK1nk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.5.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
|
||||
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
|
||||
@@ -179,22 +81,14 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
|
||||
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/karrick/godirwalk v1.15.6 h1:Yf2mmR8TJy+8Fa0SuQVto5SYap6IF7lNVX4Jdl8G1qA=
|
||||
github.com/karrick/godirwalk v1.15.6/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
@@ -215,8 +109,6 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
|
||||
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/melihmucuk/geocache v0.0.0-20160621165317-521b336a001c h1:1ErTnOL2d0OvfUABvEjGcPM8cKSLxYZpJiYS4BfQ3o4=
|
||||
github.com/melihmucuk/geocache v0.0.0-20160621165317-521b336a001c/go.mod h1:CX2bLGC22DrgJTaYvKt+lOi3BACGNA60hbFXh2iWebs=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -225,83 +117,14 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/montanaflynn/stats v0.0.0-20151014174947-eeaced052adb/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/montanaflynn/stats v0.0.0-20181214052348-945b007cb92f h1:r//C+RGlxxi1gPODiDj/Y/uvv3OaZlZPSFz2SuwIees=
|
||||
github.com/montanaflynn/stats v0.0.0-20181214052348-945b007cb92f/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/myesui/uuid v1.0.0 h1:xCBmH4l5KuvLYc5L7AS7SZg9/jKdIFubM7OVoLqaQUI=
|
||||
github.com/myesui/uuid v1.0.0/go.mod h1:2CDfNgU0LR8mIdO8vdWd8i9gWWxLlcoIGGpSNgafq84=
|
||||
github.com/ngaut/pools v0.0.0-20180318154953-b7bc8c42aac7 h1:7KAv7KMGTTqSmYZtNdcNTgsos+vFzULLwyElndwn+5c=
|
||||
github.com/ngaut/pools v0.0.0-20180318154953-b7bc8c42aac7/go.mod h1:iWMfgwqYW+e8n5lC/jjNEhwcjbRDpl5NT7n2h+4UNcI=
|
||||
github.com/ngaut/sync2 v0.0.0-20141008032647-7a24ed77b2ef h1:K0Fn+DoFqNqktdZtdV3bPQ/0cuYh2H4rkg0tytX/07k=
|
||||
github.com/ngaut/sync2 v0.0.0-20141008032647-7a24ed77b2ef/go.mod h1:7WjlapSfwQyo6LNmIvEWzsW1hbBQfpUO4JWnuQRmva8=
|
||||
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/opentracing/basictracer-go v1.0.0 h1:YyUAhaEfjoWXclZVJ9sGoNct7j4TVk7lZWlQw5UXuoo=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/paulmach/go.geojson v1.4.0 h1:5x5moCkCtDo5x8af62P9IOAYGQcYHtxz2QJ3x1DoCgY=
|
||||
github.com/paulmach/go.geojson v1.4.0/go.mod h1:YaKx1hKpWF+T2oj2lFJPsW/t1Q5e1jQI61eoQSTwpIs=
|
||||
github.com/pelletier/go-toml v1.3.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
|
||||
github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8 h1:USx2/E1bX46VG32FIw034Au6seQ2fY9NEILmNh/UlQg=
|
||||
github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8/go.mod h1:B1+S9LNcuMyLH/4HMTViQOJevkGiik3wW2AN9zb2fNQ=
|
||||
github.com/pingcap/errors v0.11.0 h1:DCJQB8jrHbQ1VVlMFIrbj2ApScNNotVmkSNplu2yUt4=
|
||||
github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||
github.com/pingcap/errors v0.11.1 h1:BXFZ6MdDd2U1uJUa2sRAWTmm+nieEzuyYM0R4aUTcC8=
|
||||
github.com/pingcap/errors v0.11.1/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||
github.com/pingcap/failpoint v0.0.0-20190430075617-bf45ab20bfc4 h1:4dCk6ysGubtlSc9hE/t5Ptl6mMVxSoWSsTvGSbFJwJ8=
|
||||
github.com/pingcap/failpoint v0.0.0-20190430075617-bf45ab20bfc4/go.mod h1:p2F6D0adua5g+596cw96U8hU8slkeJhboEV7ySGDeEg=
|
||||
github.com/pingcap/goleveldb v0.0.0-20171020084629-8d44bfdf1030 h1:XJLuW0lsP7vAtQ2iPjZwvXZ14m5urp9No+Qr06ZZcTo=
|
||||
github.com/pingcap/goleveldb v0.0.0-20171020084629-8d44bfdf1030/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw=
|
||||
github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e h1:P73/4dPCL96rGrobssy1nVy2VaVpNCuLpCbr+FEaTA8=
|
||||
github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw=
|
||||
github.com/pingcap/kvproto v0.0.0-20190226063853-f6c0b7ffff11 h1:e81flSfRbbMW5RUnz1cJl+8XKOVUCfF8FapFS8HnHLs=
|
||||
github.com/pingcap/kvproto v0.0.0-20190226063853-f6c0b7ffff11/go.mod h1:0gwbe1F2iBIjuQ9AH0DbQhL+Dpr5GofU8fgYyXk+ykk=
|
||||
github.com/pingcap/log v0.0.0-20190307075452-bd41d9273596 h1:t2OQTpPJnrPDGlvA+3FwJptMTt6MEPdzK1Wt99oaefQ=
|
||||
github.com/pingcap/log v0.0.0-20190307075452-bd41d9273596/go.mod h1:WpHUKhNZ18v116SvGrmjkA9CBhYmuUTKL+p8JC9ANEw=
|
||||
github.com/pingcap/parser v0.0.0-20190529073816-0550d84c65ad h1:XLVTXFsIYkKlV55mbBk84op/W67Cjh497d0zLt6jn/M=
|
||||
github.com/pingcap/parser v0.0.0-20190529073816-0550d84c65ad/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA=
|
||||
github.com/pingcap/pd v2.1.0-rc.4+incompatible h1:/buwGk04aHO5odk/+O8ZOXGs4qkUjYTJ2UpCJXna8NE=
|
||||
github.com/pingcap/pd v2.1.0-rc.4+incompatible/go.mod h1:nD3+EoYes4+aNNODO99ES59V83MZSI+dFbhyr667a0E=
|
||||
github.com/pingcap/tidb v2.1.11+incompatible h1:gK+uPTQSG8brUbwx+HIPdQBvAWZjvIHqvxfNOvUxNOc=
|
||||
github.com/pingcap/tidb v2.1.11+incompatible/go.mod h1:XcM8kyDXxZR+dkzsNuajtC2REDqMblOiFTKHxTX0LZ0=
|
||||
github.com/pingcap/tidb-tools v2.1.3-0.20190116051332-34c808eef588+incompatible h1:e9Gi/LP9181HT3gBfSOeSBA+5JfemuE4aEAhqNgoE4k=
|
||||
github.com/pingcap/tidb-tools v2.1.3-0.20190116051332-34c808eef588+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM=
|
||||
github.com/pingcap/tipb v0.0.0-20180910045846-371b48b15d93 h1:gI5bOzLMxjUq6ui+md/JnT4pYpkzrABJ/PeYORWiYYs=
|
||||
github.com/pingcap/tipb v0.0.0-20180910045846-371b48b15d93/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+CiwcpGTW6pL6bv6KI3KbyEyCKyS+1JWS2h8PNDnGA=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f h1:BVwpUVJDADN2ufcGik7W992pyps0wZ888b/y9GXcLTU=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.0.0-20180426121432-d811d2e9bf89/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20180408092902-8b1c2da0d56d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be h1:ta7tUOvsPHVHGom5hKW5VXNc2xZIkfCKP8iaqOyYtUQ=
|
||||
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be/go.mod h1:MIDFMn7db1kT65GmV94GzpX9Qdi7N/pQlwb+AN8wh+Q=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20190512091148-babf20351dd7 h1:FUL3b97ZY2EPqg2NbXKuMHs5pXJB9hjj1fDHnF2vl28=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20190512091148-babf20351dd7/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
@@ -312,23 +135,9 @@ github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXY
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v0.0.0-20170323161349-3bcb09397d6d/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.2.0 h1:juTguoYk5qI21pwyTXY3B3Y5cOTH3ZUyZCg1v/mihuo=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q=
|
||||
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
|
||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20150829172844-0d12bf811670/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
@@ -349,93 +158,33 @@ github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8=
|
||||
github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6 h1:lYIiVDtZnyTWlNwiAxLj0bbpTcx1BWCFhXjfsvmPdNc=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20171017195756-830351dc03c6/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/twinj/uuid v0.0.0-20150629100731-70cac2bcd273/go.mod h1:mMgcE1RHFUFqe5AfiwlINXisXfDGro23fWdPUfOMjRY=
|
||||
github.com/twinj/uuid v1.0.0 h1:fzz7COZnDrXGTAOHGuUGYd6sG+JMq+AoE7+Jlu0przk=
|
||||
github.com/twinj/uuid v1.0.0/go.mod h1:mMgcE1RHFUFqe5AfiwlINXisXfDGro23fWdPUfOMjRY=
|
||||
github.com/uber-go/atomic v1.3.2 h1:Azu9lPBWRNKzYXSIwRfgRuDuS0YKsK4NFhiQv98gkxo=
|
||||
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
|
||||
github.com/uber/jaeger-client-go v2.8.0+incompatible h1:7DGH8Hqk6PirD+GE+bvCf0cLnspLuae7N1NcwMeQcyg=
|
||||
github.com/uber/jaeger-client-go v2.8.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-client-go v2.15.0+incompatible h1:NP3qsSqNxh8VYr956ur1N/1C1PjvOJnJykCzcD5QHbk=
|
||||
github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v1.1.0 h1:k1oxbz5ToLJtwCGmTlNSmfciXv/SPe1tnmNe+FqTl5w=
|
||||
github.com/uber/jaeger-lib v1.1.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/uber/jaeger-lib v1.5.0 h1:OHbgr8l656Ub3Fw5k9SWnBfIEwvoHQ+W2y+Aa9D1Uyo=
|
||||
github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go v1.1.1 h1:gmervu+jDMvXTbcHQ0pd2wee85nEoE0BsVyEuzkfK8w=
|
||||
github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ulule/deepcopier v0.0.0-20200430083143-45decc6639b6 h1:TtyC78WMafNW8QFfv3TeP3yWNDG+uxNkk9vOrnDu6JA=
|
||||
github.com/ulule/deepcopier v0.0.0-20200430083143-45decc6639b6/go.mod h1:h8272+G2omSmi30fBXiZDMkmHuOgonplfKIKjQWzlfs=
|
||||
github.com/unrolled/render v0.0.0-20171102162132-65450fb6b2d3/go.mod h1:tu82oB5W2ykJRVioYsB+IQKcft7ryBr7w12qMBUPyXg=
|
||||
github.com/unrolled/render v0.0.0-20181210145518-4c664cb3ad2f h1:+feYJlxPM00jEkdybexHiwIIOVuClwTEbh1WLiNr0mk=
|
||||
github.com/unrolled/render v0.0.0-20181210145518-4c664cb3ad2f/go.mod h1:tu82oB5W2ykJRVioYsB+IQKcft7ryBr7w12qMBUPyXg=
|
||||
github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
|
||||
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18 h1:MPPkRncZLN9Kh4MEFmbnK4h3BD7AUmskWv2+EeZJCCs=
|
||||
github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yookoala/realpath v1.0.0/go.mod h1:gJJMA9wuX7AcqLy1+ffPatSCySA1FQ2S8Ya9AIoYBpE=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180503215945-1f94bef427e3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
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=
|
||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88=
|
||||
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw=
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
|
||||
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-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200320220750-118fecf932d8/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120 h1:EZ3cVSzKOlJxAd8e8YAJ7no8nNypTxexh/YE/xW3ZEY=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/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/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -448,56 +197,14 @@ golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181105230042-78dc5bac0cac h1:0Nb35Izc6T6Yz1iGmRc4cg14cxRaFjbjD4hWFI6JNJ8=
|
||||
golang.org/x/tools v0.0.0-20181105230042-78dc5bac0cac/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d h1:lzLdP95xJmMpwQ6LUHwrc5V7js93hTiY7gkznu0BgmY=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
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 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180427144745-86e600f69ee4/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107 h1:xtNn7qFlagY2mQNFHMSRPjT2RkOV4OXM7P5TVy9xATo=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
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 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/alecthomas/gometalinter.v2 v2.0.12/go.mod h1:NDRytsqEZyolNuAgTzJkZMkSQM7FIKyzVzGhjB/qfYo=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/alecthomas/kingpin.v3-unstable v3.0.0-20180810215634-df19058c872c/go.mod h1:3HH7i1SgMqlzxCcBmUHW657sD4Kvv9sC3HpL3YukzwA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/stretchr/testify.v1 v1.2.2 h1:yhQC6Uy5CqibAIlk1wlusa/MJ3iAN49/BsR/dCCKz3M=
|
||||
gopkg.in/stretchr/testify.v1 v1.2.2/go.mod h1:QI5V/q6UbPmuhtm10CaFZxED9NreB8PnFYN9JcR6TxU=
|
||||
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/ugjka/go-tz.v2 v2.0.9 h1:2ECB40UPBRJ6G53XE6zf7LMsiI038orvYfJKx/eir3g=
|
||||
gopkg.in/ugjka/go-tz.v2 v2.0.9/go.mod h1:1iX2y1/xUdZjNIyGW/dLRRinbWrntuHYc9oIkGWFvz4=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
|
||||
@@ -506,4 +213,3 @@ gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
@@ -168,7 +168,8 @@ func BatchPhotosPrivate(router *gin.RouterGroup, conf *config.Config) {
|
||||
|
||||
log.Infof("marking photos as private: %#v", f.Photos)
|
||||
|
||||
err := entity.Db().Model(entity.Photo{}).Where("photo_uid IN (?)", f.Photos).UpdateColumn("photo_private", gorm.Expr("IF (`photo_private`, 0, 1)")).Error
|
||||
err := entity.Db().Model(entity.Photo{}).Where("photo_uid IN (?)", f.Photos).UpdateColumn("photo_private",
|
||||
gorm.Expr("CASE WHEN photo_private > 0 THEN 0 ELSE 1 END")).Error
|
||||
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, ErrSaveFailed)
|
||||
|
||||
@@ -103,12 +103,14 @@ func LikeLabel(router *gin.RouterGroup, conf *config.Config) {
|
||||
label, err := query.LabelByUID(id)
|
||||
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(404, gin.H{"error": txt.UcFirst(err.Error())})
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": txt.UcFirst(err.Error())})
|
||||
return
|
||||
}
|
||||
|
||||
label.LabelFavorite = true
|
||||
entity.Db().Save(&label)
|
||||
if err := label.Update("LabelFavorite", true); err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": txt.UcFirst(err.Error())})
|
||||
return
|
||||
}
|
||||
|
||||
if label.LabelPriority < 0 {
|
||||
event.Publish("count.labels", event.Data{
|
||||
@@ -137,12 +139,14 @@ func DislikeLabel(router *gin.RouterGroup, conf *config.Config) {
|
||||
label, err := query.LabelByUID(id)
|
||||
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(404, gin.H{"error": txt.UcFirst(err.Error())})
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": txt.UcFirst(err.Error())})
|
||||
return
|
||||
}
|
||||
|
||||
label.LabelFavorite = false
|
||||
entity.Db().Save(&label)
|
||||
if err := label.Update("LabelFavorite", false); err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": txt.UcFirst(err.Error())})
|
||||
return
|
||||
}
|
||||
|
||||
if label.LabelPriority < 0 {
|
||||
event.Publish("count.labels", event.Data{
|
||||
|
||||
@@ -93,7 +93,8 @@ func TestDislikeLabel(t *testing.T) {
|
||||
t.Run("dislike existing label", func(t *testing.T) {
|
||||
app, router, ctx := NewApiTest()
|
||||
GetLabels(router, ctx)
|
||||
r2 := PerformRequest(app, "GET", "/api/v1/labels?count=1&q=landscape")
|
||||
r2 := PerformRequest(app, "GET", "/api/v1/labels?count=3&q=landscape")
|
||||
t.Logf("HTTP BODY: %s", r2.Body.String())
|
||||
val := gjson.Get(r2.Body.String(), `#(Slug=="landscape").Favorite`)
|
||||
assert.Equal(t, "true", val.String())
|
||||
|
||||
@@ -102,7 +103,7 @@ func TestDislikeLabel(t *testing.T) {
|
||||
r := PerformRequest(app, "DELETE", "/api/v1/labels/lt9k3pw1wowuy3c2/like")
|
||||
assert.Equal(t, http.StatusOK, r.Code)
|
||||
|
||||
r3 := PerformRequest(app, "GET", "/api/v1/labels?count=1&q=landscape")
|
||||
r3 := PerformRequest(app, "GET", "/api/v1/labels?count=3&q=landscape")
|
||||
val2 := gjson.Get(r3.Body.String(), `#(Slug=="landscape").Favorite`)
|
||||
assert.Equal(t, "false", val2.String())
|
||||
})
|
||||
|
||||
@@ -19,8 +19,16 @@ var ConfigCommand = cli.Command{
|
||||
func configAction(ctx *cli.Context) error {
|
||||
conf := config.NewConfig(ctx)
|
||||
|
||||
dbDriver := conf.DatabaseDriver()
|
||||
dbDsn := conf.DatabaseDsn()
|
||||
|
||||
fmt.Printf("%-25s VALUE\n", "NAME")
|
||||
|
||||
// Database config
|
||||
fmt.Printf("%-25s %s\n", "database-driver", dbDriver)
|
||||
fmt.Printf("%-25s %s\n", "database-dsn", dbDsn)
|
||||
fmt.Printf("%-25s %d\n", "database-conns", conf.DatabaseConns())
|
||||
|
||||
// Description
|
||||
fmt.Printf("%-25s %s\n", "name", conf.Name())
|
||||
fmt.Printf("%-25s %s\n", "url", conf.Url())
|
||||
@@ -77,17 +85,6 @@ func configAction(ctx *cli.Context) error {
|
||||
fmt.Printf("%-25s %d\n", "http-port", conf.HttpServerPort())
|
||||
fmt.Printf("%-25s %s\n", "http-mode", conf.HttpServerMode())
|
||||
|
||||
// Built-in TiDB server config
|
||||
fmt.Printf("%-25s %s\n", "tidb-host", conf.TidbServerHost())
|
||||
fmt.Printf("%-25s %d\n", "tidb-port", conf.TidbServerPort())
|
||||
fmt.Printf("%-25s %s\n", "tidb-password", conf.TidbServerPassword())
|
||||
fmt.Printf("%-25s %s\n", "tidb-path", conf.TidbServerPath())
|
||||
|
||||
// Database config
|
||||
fmt.Printf("%-25s %s\n", "database-driver", conf.DatabaseDriver())
|
||||
fmt.Printf("%-25s %s\n", "database-dsn", conf.DatabaseDsn())
|
||||
fmt.Printf("%-25s %d\n", "database-conns", conf.DatabaseConns())
|
||||
|
||||
// External binaries
|
||||
fmt.Printf("%-25s %s\n", "sips-bin", conf.SipsBin())
|
||||
fmt.Printf("%-25s %s\n", "darktable-bin", conf.DarktableBin())
|
||||
|
||||
@@ -53,11 +53,6 @@ func startAction(ctx *cli.Context) error {
|
||||
fmt.Printf("NAME VALUE\n")
|
||||
fmt.Printf("detach-server %t\n", conf.DetachServer())
|
||||
|
||||
fmt.Printf("tidb-host %s\n", conf.TidbServerHost())
|
||||
fmt.Printf("tidb-port %d\n", conf.TidbServerPort())
|
||||
fmt.Printf("tidb-password %s\n", conf.TidbServerPassword())
|
||||
fmt.Printf("tidb-path %s\n", conf.TidbServerPath())
|
||||
|
||||
fmt.Printf("http-host %s\n", conf.HttpServerHost())
|
||||
fmt.Printf("http-port %d\n", conf.HttpServerPort())
|
||||
fmt.Printf("http-mode %s\n", conf.HttpServerMode())
|
||||
|
||||
@@ -118,38 +118,6 @@ func TestConfig_DetachServer(t *testing.T) {
|
||||
assert.Equal(t, false, detachServer)
|
||||
}
|
||||
|
||||
func TestConfig_TidbServerHost(t *testing.T) {
|
||||
ctx := CliTestContext()
|
||||
c := NewConfig(ctx)
|
||||
|
||||
host := c.TidbServerHost()
|
||||
assert.Equal(t, "127.0.0.1", host)
|
||||
}
|
||||
|
||||
func TestConfig_TidbServerPort(t *testing.T) {
|
||||
ctx := CliTestContext()
|
||||
c := NewConfig(ctx)
|
||||
|
||||
port := c.TidbServerPort()
|
||||
assert.Equal(t, uint(2343), port)
|
||||
}
|
||||
|
||||
func TestConfig_TidbServerPath(t *testing.T) {
|
||||
ctx := CliTestContext()
|
||||
c := NewConfig(ctx)
|
||||
|
||||
path := c.TidbServerPath()
|
||||
assert.Equal(t, "/go/src/github.com/photoprism/photoprism/assets/resources/database", path)
|
||||
}
|
||||
|
||||
func TestConfig_TidbServerPassword(t *testing.T) {
|
||||
ctx := CliTestContext()
|
||||
c := NewConfig(ctx)
|
||||
|
||||
password := c.TidbServerPassword()
|
||||
assert.Equal(t, "", password)
|
||||
}
|
||||
|
||||
func TestConfig_HttpServerHost(t *testing.T) {
|
||||
ctx := CliTestContext()
|
||||
c := NewConfig(ctx)
|
||||
@@ -237,7 +205,7 @@ func TestConfig_DatabaseDriver(t *testing.T) {
|
||||
c := NewConfig(ctx)
|
||||
|
||||
driver := c.DatabaseDriver()
|
||||
assert.Equal(t, DriverTidb, driver)
|
||||
assert.Equal(t, SQLite, driver)
|
||||
}
|
||||
|
||||
func TestConfig_DatabaseDsn(t *testing.T) {
|
||||
@@ -245,7 +213,7 @@ func TestConfig_DatabaseDsn(t *testing.T) {
|
||||
c := NewConfig(ctx)
|
||||
|
||||
dsn := c.DatabaseDriver()
|
||||
assert.Equal(t, DriverTidb, dsn)
|
||||
assert.Equal(t, SQLite, dsn)
|
||||
}
|
||||
|
||||
func TestConfig_CachePath(t *testing.T) {
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -13,22 +15,46 @@ import (
|
||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/mutex"
|
||||
"github.com/photoprism/photoprism/internal/tidb"
|
||||
)
|
||||
|
||||
// DatabaseDriver returns the database driver name.
|
||||
func (c *Config) DatabaseDriver() string {
|
||||
if strings.ToLower(c.params.DatabaseDriver) == "mysql" {
|
||||
return DriverMysql
|
||||
switch strings.ToLower(c.params.DatabaseDriver) {
|
||||
case MySQL, "mariadb":
|
||||
c.params.DatabaseDriver = MySQL
|
||||
case SQLite, "sqlite", "sqllite", "test", "file", "":
|
||||
c.params.DatabaseDriver = SQLite
|
||||
case "tidb":
|
||||
log.Warnf("config: database driver 'tidb' is deprecated, using sqlite")
|
||||
c.params.DatabaseDriver = SQLite
|
||||
c.params.DatabaseDsn = ""
|
||||
default:
|
||||
log.Warnf("config: unsupported database driver %s, using sqlite", c.params.DatabaseDriver)
|
||||
c.params.DatabaseDriver = SQLite
|
||||
c.params.DatabaseDsn = ""
|
||||
}
|
||||
|
||||
return DriverTidb
|
||||
return c.params.DatabaseDriver
|
||||
}
|
||||
|
||||
// DatabaseDsn returns the database data source name (DSN).
|
||||
func (c *Config) DatabaseDsn() string {
|
||||
if c.params.DatabaseDsn == "" {
|
||||
return "root:photoprism@tcp(localhost:2343)/photoprism?parseTime=true"
|
||||
switch c.DatabaseDriver() {
|
||||
case MySQL:
|
||||
return "photoprism:photoprism@tcp(photoprism-db:3306)/photoprism?parseTime=true"
|
||||
case SQLite:
|
||||
storagePath := filepath.Join(c.ConfigPath())
|
||||
|
||||
if err := os.MkdirAll(storagePath, os.ModePerm); err != nil {
|
||||
log.Errorf("config: %s (database storage path)", err.Error())
|
||||
} else {
|
||||
return filepath.Join(storagePath, "index.db")
|
||||
}
|
||||
default:
|
||||
log.Errorf("config: empty database dsn")
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
return c.params.DatabaseDsn
|
||||
@@ -97,24 +123,8 @@ func (c *Config) connectToDatabase(ctx context.Context) error {
|
||||
return errors.New("config: database DSN not specified")
|
||||
}
|
||||
|
||||
isTiDB := false
|
||||
initSuccess := false
|
||||
|
||||
if dbDriver == DriverTidb {
|
||||
isTiDB = true
|
||||
dbDriver = DriverMysql
|
||||
}
|
||||
|
||||
db, err := gorm.Open(dbDriver, dbDsn)
|
||||
if err != nil || db == nil {
|
||||
if isTiDB {
|
||||
log.Infof("starting database server at %s:%d\n", c.TidbServerHost(), c.TidbServerPort())
|
||||
|
||||
go tidb.Start(ctx, c.TidbServerPath(), c.TidbServerPort(), c.TidbServerHost(), c.Debug())
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
|
||||
for i := 1; i <= 12; i++ {
|
||||
db, err = gorm.Open(dbDriver, dbDsn)
|
||||
|
||||
@@ -122,16 +132,6 @@ func (c *Config) connectToDatabase(ctx context.Context) error {
|
||||
break
|
||||
}
|
||||
|
||||
if isTiDB && !initSuccess {
|
||||
err = tidb.InitDatabase(c.TidbServerPort(), c.TidbServerPassword())
|
||||
|
||||
if err != nil {
|
||||
log.Debug(err)
|
||||
} else {
|
||||
initSuccess = true
|
||||
}
|
||||
}
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
|
||||
|
||||
@@ -62,10 +62,6 @@ func (c *Config) CreateDirectories() error {
|
||||
return createError(c.ResourcesPath(), err)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(c.TidbServerPath(), os.ModePerm); err != nil {
|
||||
return createError(c.TidbServerPath(), err)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(c.TensorFlowModelPath(), os.ModePerm); err != nil {
|
||||
return createError(c.TensorFlowModelPath(), err)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,24 @@ import (
|
||||
|
||||
// GlobalFlags lists all CLI flags
|
||||
var GlobalFlags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "database-driver",
|
||||
Usage: "database `DRIVER` (sqlite or mysql)",
|
||||
Value: "sqlite",
|
||||
EnvVar: "PHOTOPRISM_DATABASE_DRIVER",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "database-dsn",
|
||||
Usage: "database data source or file name (`DSN`)",
|
||||
Value: "",
|
||||
EnvVar: "PHOTOPRISM_DATABASE_DSN",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "database-conns",
|
||||
Usage: "maximum `NUMBER` of open connections to the database",
|
||||
Value: 256,
|
||||
EnvVar: "PHOTOPRISM_DATABASE_CONNS",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "admin-password",
|
||||
Usage: "admin password",
|
||||
@@ -210,45 +228,6 @@ var GlobalFlags = []cli.Flag{
|
||||
Usage: "debug, release or test",
|
||||
EnvVar: "PHOTOPRISM_HTTP_MODE",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "tidb-port",
|
||||
Value: 2343,
|
||||
Usage: "built-in TiDB server port",
|
||||
EnvVar: "PHOTOPRISM_TIDB_PORT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tidb-host",
|
||||
Usage: "built-in TiDB server host",
|
||||
EnvVar: "PHOTOPRISM_TIDB_HOST",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tidb-password",
|
||||
Usage: "built-in TiDB server password",
|
||||
EnvVar: "PHOTOPRISM_TIDB_PASSWORD",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "tidb-path",
|
||||
Usage: "built-in TiDB server storage `PATH`",
|
||||
EnvVar: "PHOTOPRISM_TIDB_PATH",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "database-driver",
|
||||
Usage: "database `DRIVER` (tidb or mysql)",
|
||||
Value: "tidb",
|
||||
EnvVar: "PHOTOPRISM_DATABASE_DRIVER",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "database-dsn",
|
||||
Usage: "database data source name (`DSN`)",
|
||||
Value: "root:@tcp(localhost:2343)/photoprism?parseTime=true",
|
||||
EnvVar: "PHOTOPRISM_DATABASE_DSN",
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "database-conns",
|
||||
Usage: "maximum `NUMBER` of open connections to the database",
|
||||
Value: 256,
|
||||
EnvVar: "PHOTOPRISM_DATABASE_CONNS",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "detect-nsfw",
|
||||
Usage: "flag photos as private that may be offensive",
|
||||
|
||||
@@ -13,10 +13,10 @@ import (
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// define database drivers const
|
||||
// Database drivers (sql dialects).
|
||||
const (
|
||||
DriverTidb = "tidb"
|
||||
DriverMysql = "mysql"
|
||||
MySQL = "mysql"
|
||||
SQLite = "sqlite3"
|
||||
)
|
||||
|
||||
// Params provides a struct in which application configuration is stored.
|
||||
@@ -57,10 +57,6 @@ type Params struct {
|
||||
DatabaseDriver string `yaml:"database-driver" flag:"database-driver"`
|
||||
DatabaseDsn string `yaml:"database-dsn" flag:"database-dsn"`
|
||||
DatabaseConns int `yaml:"database-conns" flag:"database-conns"`
|
||||
TidbServerHost string `yaml:"tidb-host" flag:"tidb-host"`
|
||||
TidbServerPort uint `yaml:"tidb-port" flag:"tidb-port"`
|
||||
TidbServerPassword string `yaml:"tidb-password" flag:"tidb-password"`
|
||||
TidbServerPath string `yaml:"tidb-path" flag:"tidb-path"`
|
||||
HttpServerHost string `yaml:"http-host" flag:"http-host"`
|
||||
HttpServerPort int `yaml:"http-port" flag:"http-port"`
|
||||
HttpServerMode string `yaml:"http-mode" flag:"http-mode"`
|
||||
@@ -125,7 +121,6 @@ func (c *Params) expandFilenames() {
|
||||
c.OriginalsPath = fs.Abs(c.OriginalsPath)
|
||||
c.ImportPath = fs.Abs(c.ImportPath)
|
||||
c.TempPath = fs.Abs(c.TempPath)
|
||||
c.TidbServerPath = fs.Abs(c.TidbServerPath)
|
||||
c.PIDFilename = fs.Abs(c.PIDFilename)
|
||||
c.LogFilename = fs.Abs(c.LogFilename)
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func TestParams_SetValuesFromFile(t *testing.T) {
|
||||
assert.Equal(t, "/srv/photoprism/photos/originals", c.OriginalsPath)
|
||||
assert.Equal(t, "/srv/photoprism/photos/import", c.ImportPath)
|
||||
assert.Equal(t, "/srv/photoprism/temp", c.TempPath)
|
||||
assert.Equal(t, DriverTidb, c.DatabaseDriver)
|
||||
assert.Equal(t, "root:photoprism@tcp(localhost:2343)/photoprism?parseTime=true", c.DatabaseDsn)
|
||||
assert.NotEmpty(t, c.DatabaseDriver)
|
||||
assert.NotEmpty(t, c.DatabaseDsn)
|
||||
assert.Equal(t, 81, c.HttpServerPort)
|
||||
}
|
||||
|
||||
@@ -80,35 +80,3 @@ func (c *Config) HttpStaticPath() string {
|
||||
func (c *Config) HttpStaticBuildPath() string {
|
||||
return filepath.Join(c.HttpStaticPath(), "build")
|
||||
}
|
||||
|
||||
// TidbServerHost returns the host for the built-in TiDB server. (empty for all interfaces).
|
||||
func (c *Config) TidbServerHost() string {
|
||||
if c.params.TidbServerHost == "" {
|
||||
return "127.0.0.1"
|
||||
}
|
||||
|
||||
return c.params.TidbServerHost
|
||||
}
|
||||
|
||||
// TidbServerPort returns the port for the built-in TiDB server.
|
||||
func (c *Config) TidbServerPort() uint {
|
||||
if c.params.TidbServerPort == 0 {
|
||||
return 2343
|
||||
}
|
||||
|
||||
return c.params.TidbServerPort
|
||||
}
|
||||
|
||||
// TidbServerPassword returns the password for the built-in TiDB server.
|
||||
func (c *Config) TidbServerPassword() string {
|
||||
return c.params.TidbServerPassword
|
||||
}
|
||||
|
||||
// TidbServerPath returns the database storage path for the built-in TiDB server.
|
||||
func (c *Config) TidbServerPath() string {
|
||||
if c.params.TidbServerPath == "" {
|
||||
return filepath.Join(c.ResourcesPath(), "/database")
|
||||
}
|
||||
|
||||
return fs.Abs(c.params.TidbServerPath)
|
||||
}
|
||||
|
||||
@@ -38,6 +38,18 @@ func NewTestParams() *Params {
|
||||
|
||||
testDataPath := testDataPath(assetsPath)
|
||||
|
||||
dbDriver := os.Getenv("PHOTOPRISM_TEST_DRIVER")
|
||||
dbDsn := os.Getenv("PHOTOPRISM_TEST_DSN")
|
||||
|
||||
// Config example for MySQL / MariaDB:
|
||||
// dbDriver = MySQL,
|
||||
// dbDsn = "photoprism:photoprism@tcp(photoprism-db:4001)/photoprism?parseTime=true",
|
||||
|
||||
if dbDriver == "test" || dbDriver == "sqlite" || dbDriver == "" || dbDsn == ""{
|
||||
dbDriver = SQLite
|
||||
dbDsn = ".test.db"
|
||||
}
|
||||
|
||||
c := &Params{
|
||||
Name: "PhotoPrism",
|
||||
Version: "0.0.0",
|
||||
@@ -55,8 +67,8 @@ func NewTestParams() *Params {
|
||||
OriginalsPath: testDataPath + "/originals",
|
||||
ImportPath: testDataPath + "/import",
|
||||
TempPath: testDataPath + "/temp",
|
||||
DatabaseDriver: "mysql",
|
||||
DatabaseDsn: "photoprism:photoprism@tcp(photoprism-db:4001)/photoprism?parseTime=true",
|
||||
DatabaseDriver: dbDriver,
|
||||
DatabaseDsn: dbDsn,
|
||||
}
|
||||
|
||||
return c
|
||||
@@ -75,7 +87,7 @@ func NewTestParamsError() *Params {
|
||||
OriginalsPath: testDataPath + "/originals",
|
||||
ImportPath: testDataPath + "/import",
|
||||
TempPath: testDataPath + "/temp",
|
||||
DatabaseDriver: "mysql",
|
||||
DatabaseDriver: MySQL,
|
||||
DatabaseDsn: "photoprism:photoprism@tcp(photoprism-db:4001)/photoprism?parseTime=true",
|
||||
}
|
||||
|
||||
|
||||
7
internal/config/testdata/config.yml
vendored
7
internal/config/testdata/config.yml
vendored
@@ -9,10 +9,7 @@ http-host:
|
||||
http-mode: release
|
||||
http-port: 81
|
||||
http-password:
|
||||
tidb-host: localhost
|
||||
tidb-port: 2343
|
||||
tidb-password: photoprism
|
||||
database-driver: tidb
|
||||
database-dsn: root:photoprism@tcp(localhost:2343)/photoprism?parseTime=true
|
||||
database-driver: sqlite
|
||||
database-dsn: .photoprism.db
|
||||
theme: lavendel
|
||||
language: english
|
||||
|
||||
@@ -7,6 +7,13 @@ import (
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||
)
|
||||
|
||||
// Database drivers (sql dialects).
|
||||
const (
|
||||
MySQL = "mysql"
|
||||
SQLite = "sqlite3"
|
||||
)
|
||||
|
||||
var dbProvider DbProvider
|
||||
@@ -15,6 +22,16 @@ type DbProvider interface {
|
||||
Db() *gorm.DB
|
||||
}
|
||||
|
||||
// IsDialect returns true if the given sql dialect is used.
|
||||
func IsDialect(name string) bool {
|
||||
return name == Db().Dialect().GetName()
|
||||
}
|
||||
|
||||
// DbDialect returns the sql dialect name.
|
||||
func DbDialect() string {
|
||||
return Db().Dialect().GetName()
|
||||
}
|
||||
|
||||
// SetDbProvider sets the provider to get a gorm db connection.
|
||||
func SetDbProvider(provider DbProvider) {
|
||||
dbProvider = provider
|
||||
@@ -78,7 +95,7 @@ func (g *Gorm) Connect() {
|
||||
|
||||
db.LogMode(false)
|
||||
db.SetLogger(log)
|
||||
db.DB().SetMaxIdleConns(0)
|
||||
db.DB().SetMaxIdleConns(4)
|
||||
db.DB().SetMaxOpenConns(256)
|
||||
|
||||
g.db = db
|
||||
|
||||
@@ -52,13 +52,17 @@ var Entities = Types{
|
||||
"links": &Link{},
|
||||
}
|
||||
|
||||
type RowCount struct {
|
||||
Count int
|
||||
}
|
||||
|
||||
// WaitForMigration waits for the database migration to be successful.
|
||||
func (list Types) WaitForMigration() {
|
||||
attempts := 100
|
||||
|
||||
for name := range list {
|
||||
for i := 0; i <= attempts; i++ {
|
||||
if err := Db().Raw(fmt.Sprintf("DESCRIBE `%s`", name)).Scan(&struct{}{}).Error; err == nil {
|
||||
count := RowCount{}
|
||||
if err := Db().Raw(fmt.Sprintf("SELECT COUNT(*) AS count FROM %s", name)).Scan(&count).Error; err == nil {
|
||||
// log.Debugf("entity: table %s migrated", name)
|
||||
break
|
||||
} else {
|
||||
@@ -77,7 +81,8 @@ func (list Types) WaitForMigration() {
|
||||
// Truncate removes all data from tables without dropping them.
|
||||
func (list Types) Truncate() {
|
||||
for name := range list {
|
||||
if err := Db().Raw(fmt.Sprintf("TRUNCATE TABLE `%s`", name)).Scan(&struct{}{}).Error; err == nil {
|
||||
row := RowCount{}
|
||||
if err := Db().Raw(fmt.Sprintf("DELETE FROM %s WHERE 1", name)).Scan(&row).Error; err == nil {
|
||||
log.Debugf("entity: removed all data from %s", name)
|
||||
break
|
||||
} else if err.Error() != "record not found" {
|
||||
@@ -117,7 +122,7 @@ func CreateDefaultFixtures() {
|
||||
CreateUnknownCountry()
|
||||
CreateUnknownCamera()
|
||||
CreateUnknownLens()
|
||||
CreateViews()
|
||||
// CreateViews()
|
||||
}
|
||||
|
||||
// MigrateDb creates all tables and inserts default entities as needed.
|
||||
@@ -140,13 +145,20 @@ func ResetTestFixtures() {
|
||||
}
|
||||
|
||||
// InitTestDb connects to and completely initializes the test database incl fixtures.
|
||||
func InitTestDb(dsn string) *Gorm {
|
||||
func InitTestDb(driver, dsn string) *Gorm {
|
||||
if HasDbProvider() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if driver == "test" || driver == "sqlite" || driver == "" || dsn == "" {
|
||||
driver = "sqlite3"
|
||||
dsn = ".test.db"
|
||||
}
|
||||
|
||||
log.Infof("initializing %s test db in %s", driver, dsn)
|
||||
|
||||
db := &Gorm{
|
||||
Driver: "mysql",
|
||||
Driver: driver,
|
||||
Dsn: dsn,
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package entity
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -12,19 +11,10 @@ func TestMain(m *testing.M) {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.DebugLevel)
|
||||
|
||||
dsn := os.Getenv("PHOTOPRISM_TEST_DSN")
|
||||
|
||||
if dsn == "" {
|
||||
panic("database dsn is empty")
|
||||
}
|
||||
|
||||
db := InitTestDb(strings.Replace(dsn, "/photoprism", "/entity", 1))
|
||||
db := InitTestDb(os.Getenv("PHOTOPRISM_TEST_DRIVER"), os.Getenv("PHOTOPRISM_TEST_DSN"))
|
||||
defer db.Close()
|
||||
|
||||
code := m.Run()
|
||||
|
||||
if db != nil {
|
||||
db.Close()
|
||||
}
|
||||
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
@@ -72,6 +72,11 @@ func (m *Label) Create() error {
|
||||
return Db().Create(m).Error
|
||||
}
|
||||
|
||||
// Updates a column in the database.
|
||||
func (m *Label) Update(attr string, value interface{}) error {
|
||||
return UnscopedDb().Model(m).UpdateColumn(attr, value).Error
|
||||
}
|
||||
|
||||
// FirstOrCreateLabel returns the existing row, inserts a new row or nil in case of errors.
|
||||
func FirstOrCreateLabel(m *Label) *Label {
|
||||
result := Label{}
|
||||
|
||||
@@ -1,6 +1,45 @@
|
||||
package entity
|
||||
|
||||
import "github.com/jinzhu/gorm"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
type LabelPhotoCount struct {
|
||||
LabelID int
|
||||
PhotoCount int
|
||||
}
|
||||
|
||||
type LabelPhotoCounts []LabelPhotoCount
|
||||
|
||||
func LabelCounts() LabelPhotoCounts {
|
||||
result := LabelPhotoCounts{}
|
||||
|
||||
if err := UnscopedDb().Raw(`
|
||||
SELECT label_id, SUM(photo_count) AS photo_count FROM (
|
||||
SELECT l.id AS label_id, COUNT(*) AS photo_count FROM labels l
|
||||
JOIN photos_labels pl ON pl.label_id = l.id
|
||||
JOIN photos ph ON pl.photo_id = ph.id
|
||||
WHERE pl.uncertainty < 100
|
||||
AND ph.photo_quality >= 0
|
||||
AND ph.photo_private = 0
|
||||
AND ph.deleted_at IS NULL GROUP BY l.id
|
||||
UNION ALL
|
||||
SELECT l.id AS label_id, COUNT(*) AS photo_count FROM labels l
|
||||
JOIN categories c ON c.category_id = l.id
|
||||
JOIN photos_labels pl ON pl.label_id = c.label_id
|
||||
JOIN photos ph ON pl.photo_id = ph.id
|
||||
WHERE pl.uncertainty < 100
|
||||
AND ph.photo_quality >= 0
|
||||
AND ph.photo_private = 0
|
||||
AND ph.deleted_at IS NULL GROUP BY l.id) counts GROUP BY label_id
|
||||
`).Scan(&result).Error; err != nil {
|
||||
log.Errorf("label-count: %s", err.Error())
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// UpdatePhotoCounts updates photos count in related tables as needed.
|
||||
func UpdatePhotoCounts() error {
|
||||
@@ -37,7 +76,7 @@ func UpdatePhotoCounts() error {
|
||||
AND ph.deleted_at IS NULL GROUP BY l.id)) counts GROUP BY label_id
|
||||
*/
|
||||
|
||||
/* TODO: Requires proper view support in TiDB
|
||||
/* TODO: Requires view support
|
||||
|
||||
if err := Db().
|
||||
Table("labels").
|
||||
@@ -46,6 +85,7 @@ func UpdatePhotoCounts() error {
|
||||
log.Warn(err)
|
||||
} */
|
||||
|
||||
if IsDialect(MySQL) {
|
||||
if err := Db().
|
||||
Table("labels").
|
||||
UpdateColumn("photo_count",
|
||||
@@ -70,6 +110,32 @@ func UpdatePhotoCounts() error {
|
||||
) label_counts WHERE label_id = labels.id)`)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else if IsDialect(SQLite) {
|
||||
if err := Db().
|
||||
Table("labels").
|
||||
UpdateColumn("photo_count",
|
||||
gorm.Expr(`(SELECT photo_count FROM (SELECT label_id, SUM(photo_count) AS photo_count FROM (
|
||||
SELECT l.id AS label_id, COUNT(*) AS photo_count FROM labels l
|
||||
JOIN photos_labels pl ON pl.label_id = l.id
|
||||
JOIN photos ph ON pl.photo_id = ph.id
|
||||
WHERE pl.uncertainty < 100
|
||||
AND ph.photo_quality >= 0
|
||||
AND ph.photo_private = 0
|
||||
AND ph.deleted_at IS NULL GROUP BY l.id
|
||||
UNION ALL
|
||||
SELECT l.id AS label_id, COUNT(*) AS photo_count FROM labels l
|
||||
JOIN categories c ON c.category_id = l.id
|
||||
JOIN photos_labels pl ON pl.label_id = c.label_id
|
||||
JOIN photos ph ON pl.photo_id = ph.id
|
||||
WHERE pl.uncertainty < 100
|
||||
AND ph.photo_quality >= 0
|
||||
AND ph.photo_private = 0
|
||||
AND ph.deleted_at IS NULL GROUP BY l.id) counts GROUP BY label_id) label_counts WHERE label_id = labels.id)`)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("unknown sql dialect %s", DbDialect())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,6 +4,18 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLabelCounts(t *testing.T) {
|
||||
results := LabelCounts()
|
||||
|
||||
if len(results) == 0 {
|
||||
t.Fatal("at least one result expected")
|
||||
}
|
||||
|
||||
for _, result := range results {
|
||||
t.Logf("LABEL COUNT: %+v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdatePhotoCounts(t *testing.T) {
|
||||
err := UpdatePhotoCounts()
|
||||
|
||||
|
||||
@@ -12,11 +12,32 @@ import (
|
||||
// EstimatePosition updates the photo with an estimated geolocation if possible.
|
||||
func (m *Photo) EstimatePosition() {
|
||||
var recentPhoto Photo
|
||||
var dateExpr string
|
||||
|
||||
if result := UnscopedDb().
|
||||
switch DbDialect() {
|
||||
case MySQL:
|
||||
dateExpr = "ABS(DATEDIFF(taken_at, ?)) ASC"
|
||||
case SQLite:
|
||||
dateExpr = "ABS(JulianDay(taken_at) - JulianDay(?)) ASC"
|
||||
default:
|
||||
log.Errorf("photo: unknown sql dialect %s", DbDialect())
|
||||
return
|
||||
}
|
||||
|
||||
if err := UnscopedDb().
|
||||
Where("place_id <> '' AND place_id <> 'zz' AND loc_src <> '' AND loc_src <> ?", SrcEstimate).
|
||||
Order(gorm.Expr("ABS(DATEDIFF(taken_at, ?)) ASC", m.TakenAt)).
|
||||
Preload("Place").First(&recentPhoto); result.Error == nil {
|
||||
Order(gorm.Expr(dateExpr, m.TakenAt)).
|
||||
Preload("Place").First(&recentPhoto).Error; err != nil {
|
||||
log.Errorf("photo: %s", err.Error())
|
||||
} else {
|
||||
if days := recentPhoto.TakenAt.Sub(m.TakenAt) / (time.Hour * 24); days < -7 {
|
||||
log.Debugf("prism: can't estimate position of %s, time difference too big (%d days)", m.PhotoUID, -1*days)
|
||||
return
|
||||
} else if days > -7 {
|
||||
log.Debugf("prism: can't estimate position of %s, time difference too big (%d days)", m.PhotoUID, days)
|
||||
return
|
||||
}
|
||||
|
||||
if recentPhoto.HasPlace() {
|
||||
m.Place = recentPhoto.Place
|
||||
m.PlaceID = recentPhoto.PlaceID
|
||||
|
||||
@@ -31,12 +31,6 @@ func NewMoments(conf *config.Config) *Moments {
|
||||
|
||||
// Start creates albums based on popular locations, dates and categories.
|
||||
func (m *Moments) Start() (err error) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
log.Errorf("moments: %s [panic]", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if err := mutex.MainWorker.Start(); err != nil {
|
||||
err = fmt.Errorf("moments: %s", err.Error())
|
||||
event.Error(err.Error())
|
||||
@@ -56,9 +50,11 @@ func (m *Moments) Start() (err error) {
|
||||
counts := query.Counts{}
|
||||
counts.Refresh()
|
||||
|
||||
threshold := int(math.Log2(float64(counts.Photos))) + 1
|
||||
indexSize := counts.Photos + counts.Videos
|
||||
|
||||
log.Infof("moments: threshold %d / %d", threshold, counts.Photos)
|
||||
threshold := int(math.Log2(float64(indexSize))) + 1
|
||||
|
||||
log.Infof("moments: index contains %d photos and videos, threshold %d", indexSize, threshold)
|
||||
|
||||
// Important years and months.
|
||||
if results, err := query.MomentsTime(threshold); err != nil {
|
||||
@@ -149,7 +145,7 @@ func (m *Moments) Start() (err error) {
|
||||
if err := a.Update("AlbumFilter", f.Serialize()); err != nil {
|
||||
log.Errorf("moments: %s", err.Error())
|
||||
} else {
|
||||
log.Infof("moments: updated %s (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Infof("moments: updated %s (%s)", txt.Quote(a.AlbumTitle), f.Serialize())
|
||||
}
|
||||
} else if a := entity.NewMoment(mom.Title(), mom.Slug(), f.Serialize()); a != nil {
|
||||
if err := a.Create(); err != nil {
|
||||
|
||||
@@ -53,22 +53,29 @@ func AlbumCoverByUID(albumUID string) (file entity.File, err error) {
|
||||
|
||||
if err := Db().Where("album_uid = ?", albumUID).First(&a).Error; err != nil {
|
||||
return file, err
|
||||
} else if a.IsMoment() { // TODO: Optimize
|
||||
f := form.PhotoSearch{Album: a.AlbumUID, Filter: a.AlbumFilter, Order: entity.SortOrderRelevance, Count: 1, Offset: 0, Merged: true}
|
||||
} else if a.AlbumType != entity.TypeAlbum { // TODO: Optimize
|
||||
f := form.PhotoSearch{Album: a.AlbumUID, Filter: a.AlbumFilter, Order: entity.SortOrderRelevance, Count: 1, Offset: 0, Merged: false}
|
||||
|
||||
if photos, _, err := PhotoSearch(f); err != nil {
|
||||
return file, err
|
||||
} else if len(photos) > 0 {
|
||||
log.Debugf("PHOTOS: %+v", photos)
|
||||
|
||||
for _, photo := range photos {
|
||||
return FileByPhotoUID(photo.PhotoUID)
|
||||
log.Debugf("PHOTO: %+v", photo)
|
||||
if err := Db().Where("photo_uid = ? AND file_primary = 1", photo.PhotoUID).First(&file).Error; err != nil {
|
||||
log.Debugf("ERROR: %+v", err)
|
||||
return file, err
|
||||
} else {
|
||||
return file, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return file, fmt.Errorf("found no cover for moment")
|
||||
}
|
||||
|
||||
if err := Db().
|
||||
Where("files.file_primary = 1 AND files.file_missing = 0 AND files.file_type = 'jpg' AND files.deleted_at IS NULL").
|
||||
if err := Db().Where("files.file_primary = 1 AND files.file_missing = 0 AND files.file_type = 'jpg' AND files.deleted_at IS NULL").
|
||||
Joins("JOIN albums ON albums.album_uid = ?", albumUID).
|
||||
Joins("JOIN photos_albums pa ON pa.album_uid = albums.album_uid AND pa.photo_uid = files.photo_uid").
|
||||
Joins("JOIN photos ON photos.id = files.photo_id AND photos.photo_private = 0 AND photos.deleted_at IS NULL").
|
||||
|
||||
@@ -319,8 +319,8 @@ func PhotoSearch(f form.PhotoSearch) (results PhotoResults, count int, err error
|
||||
s = s.Limit(100).Offset(0)
|
||||
}
|
||||
|
||||
if result := s.Scan(&results); result.Error != nil {
|
||||
return results, 0, result.Error
|
||||
if err := s.Scan(&results).Error; err != nil {
|
||||
return results, 0, err
|
||||
}
|
||||
|
||||
log.Infof("photos: found %d results for %s [%s]", len(results), f.SerializeAll(), time.Since(start))
|
||||
|
||||
@@ -21,6 +21,11 @@ import (
|
||||
|
||||
var log = event.Log
|
||||
|
||||
const (
|
||||
MySQL = "mysql"
|
||||
SQLite = "sqlite3"
|
||||
)
|
||||
|
||||
// About 1km ('good enough' for now)
|
||||
const SearchRadius = 0.009
|
||||
|
||||
@@ -53,6 +58,16 @@ func UnscopedDb() *gorm.DB {
|
||||
return entity.Db().Unscoped()
|
||||
}
|
||||
|
||||
// IsDialect returns true if the given sql dialect is used.
|
||||
func IsDialect(name string) bool {
|
||||
return name == Db().Dialect().GetName()
|
||||
}
|
||||
|
||||
// DbDialect returns the sql dialect name.
|
||||
func DbDialect() string {
|
||||
return Db().Dialect().GetName()
|
||||
}
|
||||
|
||||
// LikeAny returns a where condition that matches any keyword in search.
|
||||
func LikeAny(col, search string) (where string) {
|
||||
var wheres []string
|
||||
|
||||
@@ -2,7 +2,6 @@ package query
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
@@ -14,20 +13,11 @@ func TestMain(m *testing.M) {
|
||||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.DebugLevel)
|
||||
|
||||
dsn := os.Getenv("PHOTOPRISM_TEST_DSN")
|
||||
|
||||
if dsn == "" {
|
||||
panic("database dsn is empty")
|
||||
}
|
||||
|
||||
db := entity.InitTestDb(strings.Replace(dsn, "/photoprism", "/query", 1))
|
||||
db := entity.InitTestDb(os.Getenv("PHOTOPRISM_TEST_DRIVER"), os.Getenv("PHOTOPRISM_TEST_DSN"))
|
||||
defer db.Close()
|
||||
|
||||
code := m.Run()
|
||||
|
||||
if db != nil {
|
||||
db.Close()
|
||||
}
|
||||
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package query
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
@@ -12,20 +13,31 @@ func PhotoSelection(f form.Selection) (results Photos, err error) {
|
||||
return results, errors.New("no items selected")
|
||||
}
|
||||
|
||||
// Db().LogMode(true)
|
||||
var concat string
|
||||
|
||||
s := UnscopedDb().Table("photos").
|
||||
Select("photos.*").
|
||||
Where(`photos.photo_uid IN (?)
|
||||
switch DbDialect() {
|
||||
case MySQL:
|
||||
concat = "CONCAT(a.path, '/%')"
|
||||
case SQLite:
|
||||
concat = "a.path || '/%'"
|
||||
default:
|
||||
return results, fmt.Errorf("unknown sql dialect: %s", DbDialect())
|
||||
}
|
||||
|
||||
where := fmt.Sprintf(`photos.photo_uid IN (?)
|
||||
OR photos.place_id IN (?)
|
||||
OR photos.photo_uid IN (SELECT photo_uid FROM files WHERE file_uid IN (?))
|
||||
OR photos.photo_path IN (
|
||||
SELECT a.path FROM folders a WHERE a.folder_uid IN (?) UNION
|
||||
SELECT b.path FROM folders a JOIN folders b ON b.path LIKE CONCAT(a.path, '/%') WHERE a.folder_uid IN (?))
|
||||
SELECT b.path FROM folders a JOIN folders b ON b.path LIKE %s WHERE a.folder_uid IN (?))
|
||||
OR photos.photo_uid IN (SELECT photo_uid FROM photos_albums WHERE album_uid IN (?))
|
||||
OR photos.id IN (SELECT pl.photo_id FROM photos_labels pl JOIN labels l ON pl.label_id = l.id AND l.deleted_at IS NULL WHERE l.label_uid IN (?))
|
||||
OR photos.id IN (SELECT pl.photo_id FROM photos_labels pl JOIN categories c ON c.label_id = pl.label_id JOIN labels lc ON lc.id = c.category_id AND lc.deleted_at IS NULL WHERE lc.label_uid IN (?))`,
|
||||
f.Photos, f.Places, f.Files, f.Files, f.Files, f.Albums, f.Labels, f.Labels)
|
||||
concat)
|
||||
|
||||
s := UnscopedDb().Table("photos").
|
||||
Select("photos.*").
|
||||
Where(where, f.Photos, f.Places, f.Files, f.Files, f.Files, f.Albums, f.Labels, f.Labels)
|
||||
|
||||
if result := s.Scan(&results); result.Error != nil {
|
||||
return results, result.Error
|
||||
@@ -40,23 +52,34 @@ func FileSelection(f form.Selection) (results Files, err error) {
|
||||
return results, errors.New("no items selected")
|
||||
}
|
||||
|
||||
// Db().LogMode(true)
|
||||
var concat string
|
||||
|
||||
switch DbDialect() {
|
||||
case MySQL:
|
||||
concat = "CONCAT(a.path, '/%')"
|
||||
case SQLite:
|
||||
concat = "a.path || '/%'"
|
||||
default:
|
||||
return results, fmt.Errorf("unknown sql dialect: %s", DbDialect())
|
||||
}
|
||||
|
||||
where := fmt.Sprintf(`photos.photo_uid IN (?)
|
||||
OR photos.place_id IN (?)
|
||||
OR photos.photo_uid IN (SELECT photo_uid FROM files WHERE file_uid IN (?))
|
||||
OR photos.photo_path IN (
|
||||
SELECT a.path FROM folders a WHERE a.folder_uid IN (?) UNION
|
||||
SELECT b.path FROM folders a JOIN folders b ON b.path LIKE %s WHERE a.folder_uid IN (?))
|
||||
OR photos.photo_uid IN (SELECT photo_uid FROM photos_albums WHERE album_uid IN (?))
|
||||
OR photos.id IN (SELECT pl.photo_id FROM photos_labels pl JOIN labels l ON pl.label_id = l.id AND l.deleted_at IS NULL WHERE l.label_uid IN (?))
|
||||
OR photos.id IN (SELECT pl.photo_id FROM photos_labels pl JOIN categories c ON c.label_id = pl.label_id JOIN labels lc ON lc.id = c.category_id AND lc.deleted_at IS NULL WHERE lc.label_uid IN (?))`,
|
||||
concat)
|
||||
|
||||
s := UnscopedDb().Table("files").
|
||||
Select("files.*").
|
||||
Joins("JOIN photos ON photos.id = files.photo_id").
|
||||
Where("photos.deleted_at IS NULL").
|
||||
Where("files.file_missing = 0").
|
||||
Where(`photos.photo_uid IN (?)
|
||||
OR photos.place_id IN (?)
|
||||
OR photos.photo_uid IN (SELECT photo_uid FROM files WHERE file_uid IN (?))
|
||||
OR photos.photo_path IN (
|
||||
SELECT a.path FROM folders a WHERE a.folder_uid IN (?) UNION
|
||||
SELECT b.path FROM folders a JOIN folders b ON b.path LIKE CONCAT(a.path, '/%') WHERE a.folder_uid IN (?))
|
||||
OR photos.photo_uid IN (SELECT photo_uid FROM photos_albums WHERE album_uid IN (?))
|
||||
OR photos.id IN (SELECT pl.photo_id FROM photos_labels pl JOIN labels l ON pl.label_id = l.id AND l.deleted_at IS NULL WHERE l.label_uid IN (?))
|
||||
OR photos.id IN (SELECT pl.photo_id FROM photos_labels pl JOIN categories c ON c.label_id = pl.label_id JOIN labels lc ON lc.id = c.category_id AND lc.deleted_at IS NULL WHERE lc.label_uid IN (?))`,
|
||||
f.Photos, f.Places, f.Files, f.Files, f.Files, f.Albums, f.Labels, f.Labels).
|
||||
Where(where, f.Photos, f.Places, f.Files, f.Files, f.Files, f.Albums, f.Labels, f.Labels).
|
||||
Group("files.id")
|
||||
|
||||
if result := s.Scan(&results); result.Error != nil {
|
||||
|
||||
@@ -1,366 +0,0 @@
|
||||
// Copyright 2015 PingCAP, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tidb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/pingcap/errors"
|
||||
"github.com/pingcap/parser/mysql"
|
||||
"github.com/pingcap/parser/terror"
|
||||
pd "github.com/pingcap/pd/client"
|
||||
pumpcli "github.com/pingcap/tidb-tools/tidb-binlog/pump_client"
|
||||
"github.com/pingcap/tidb/config"
|
||||
"github.com/pingcap/tidb/ddl"
|
||||
"github.com/pingcap/tidb/domain"
|
||||
"github.com/pingcap/tidb/kv"
|
||||
"github.com/pingcap/tidb/metrics"
|
||||
plannercore "github.com/pingcap/tidb/planner/core"
|
||||
"github.com/pingcap/tidb/privilege/privileges"
|
||||
"github.com/pingcap/tidb/server"
|
||||
"github.com/pingcap/tidb/session"
|
||||
"github.com/pingcap/tidb/sessionctx/binloginfo"
|
||||
"github.com/pingcap/tidb/sessionctx/variable"
|
||||
"github.com/pingcap/tidb/statistics"
|
||||
"github.com/pingcap/tidb/store/mockstore"
|
||||
"github.com/pingcap/tidb/store/tikv"
|
||||
"github.com/pingcap/tidb/store/tikv/gcworker"
|
||||
"github.com/pingcap/tidb/util/logutil"
|
||||
"github.com/pingcap/tidb/util/printer"
|
||||
xserver "github.com/pingcap/tidb/x-server"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/push"
|
||||
)
|
||||
|
||||
var log = event.Log
|
||||
|
||||
var (
|
||||
cfg *config.Config
|
||||
storage kv.Storage
|
||||
dom *domain.Domain
|
||||
svr *server.Server
|
||||
xsvr *xserver.Server
|
||||
graceful bool
|
||||
)
|
||||
|
||||
// Start the TiDB server using the configuration provided
|
||||
func Start(ctx context.Context, path string, port uint, host string, debug bool) {
|
||||
if err := logutil.SetLevel("fatal"); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
registerStores()
|
||||
registerMetrics()
|
||||
loadConfig()
|
||||
|
||||
cfg.Log.Level = log.GetLevel().String()
|
||||
|
||||
// cfg.Security.SkipGrantTable = true
|
||||
if debug {
|
||||
cfg.Log.Level = "error"
|
||||
host = "0.0.0.0"
|
||||
}
|
||||
|
||||
cfg.Path = path
|
||||
cfg.Store = "mocktikv"
|
||||
|
||||
if host == "" {
|
||||
host = "localhost"
|
||||
}
|
||||
|
||||
cfg.Host = host
|
||||
cfg.Port = port
|
||||
cfg.Status.ReportStatus = false
|
||||
|
||||
validateConfig()
|
||||
setGlobalVars()
|
||||
setupTracing()
|
||||
|
||||
if debug {
|
||||
printInfo()
|
||||
}
|
||||
|
||||
setupBinlogClient()
|
||||
// setupMetrics()
|
||||
createStoreAndDomain()
|
||||
createServer()
|
||||
go runServer()
|
||||
|
||||
<-ctx.Done()
|
||||
serverShutdown(true)
|
||||
cleanup()
|
||||
log.Info("tidb server shutdown complete")
|
||||
}
|
||||
|
||||
func registerStores() {
|
||||
err := session.RegisterStore("tikv", tikv.Driver{})
|
||||
terror.MustNil(err)
|
||||
tikv.NewGCHandlerFunc = gcworker.NewGCWorker
|
||||
err = session.RegisterStore("mocktikv", mockstore.MockDriver{})
|
||||
terror.MustNil(err)
|
||||
}
|
||||
|
||||
func registerMetrics() {
|
||||
metrics.RegisterMetrics()
|
||||
}
|
||||
|
||||
func createStoreAndDomain() {
|
||||
fullPath := fmt.Sprintf("%s://%s", cfg.Store, cfg.Path)
|
||||
var err error
|
||||
storage, err = session.NewStore(fullPath)
|
||||
terror.MustNil(err)
|
||||
// Bootstrap a session to load information schema.
|
||||
dom, err = session.BootstrapSession(storage)
|
||||
terror.MustNil(err)
|
||||
}
|
||||
|
||||
func setupBinlogClient() {
|
||||
if !cfg.Binlog.Enable {
|
||||
return
|
||||
}
|
||||
|
||||
if cfg.Binlog.IgnoreError {
|
||||
binloginfo.SetIgnoreError(true)
|
||||
}
|
||||
|
||||
client, err := pumpcli.NewPumpsClient(cfg.Path, parseDuration(cfg.Binlog.WriteTimeout), pd.SecurityOption{
|
||||
CAPath: cfg.Security.ClusterSSLCA,
|
||||
CertPath: cfg.Security.ClusterSSLCert,
|
||||
KeyPath: cfg.Security.ClusterSSLKey,
|
||||
})
|
||||
terror.MustNil(err)
|
||||
|
||||
binloginfo.SetPumpsClient(client)
|
||||
log.Infof("create pumps client success, ignore binlog error %v", cfg.Binlog.IgnoreError)
|
||||
}
|
||||
|
||||
// Prometheus push.
|
||||
const zeroDuration = time.Duration(0)
|
||||
|
||||
// pushMetric pushes metrics in background.
|
||||
func pushMetric(addr string, interval time.Duration) {
|
||||
if interval == zeroDuration || len(addr) == 0 {
|
||||
log.Info("disable Prometheus push client")
|
||||
return
|
||||
}
|
||||
log.Infof("start Prometheus push client with server addr %s and interval %s", addr, interval)
|
||||
go prometheusPushClient(addr, interval)
|
||||
}
|
||||
|
||||
// prometheusPushClient pushes metrics to Prometheus Pushgateway.
|
||||
func prometheusPushClient(addr string, interval time.Duration) {
|
||||
// TODO: TiDB do not have uniq name, so we use host+port to compose a name.
|
||||
job := "tidb"
|
||||
for {
|
||||
err := push.AddFromGatherer(
|
||||
job,
|
||||
map[string]string{"instance": instanceName()},
|
||||
addr,
|
||||
prometheus.DefaultGatherer,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("could not push metrics to Prometheus Pushgateway: %v", err)
|
||||
}
|
||||
time.Sleep(interval)
|
||||
}
|
||||
}
|
||||
|
||||
func instanceName() string {
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return "unknown"
|
||||
}
|
||||
return fmt.Sprintf("%s_%d", hostname, cfg.Port)
|
||||
}
|
||||
|
||||
// parseDuration parses lease argument string.
|
||||
func parseDuration(lease string) time.Duration {
|
||||
dur, err := time.ParseDuration(lease)
|
||||
if err != nil {
|
||||
dur, err = time.ParseDuration(lease + "s")
|
||||
}
|
||||
if err != nil || dur < 0 {
|
||||
log.Fatalf("invalid lease duration %s", lease)
|
||||
}
|
||||
return dur
|
||||
}
|
||||
|
||||
func hasRootPrivilege() bool {
|
||||
return os.Geteuid() == 0
|
||||
}
|
||||
|
||||
func flagBoolean(name string, defaultVal bool, usage string) *bool {
|
||||
if defaultVal == false {
|
||||
// Fix #4125, golang do not print default false value in usage, so we append it.
|
||||
usage = fmt.Sprintf("%s (default false)", usage)
|
||||
return flag.Bool(name, defaultVal, usage)
|
||||
}
|
||||
return flag.Bool(name, defaultVal, usage)
|
||||
}
|
||||
|
||||
func loadConfig() {
|
||||
cfg = config.GetGlobalConfig()
|
||||
}
|
||||
|
||||
func validateConfig() {
|
||||
if cfg.Security.SkipGrantTable && !hasRootPrivilege() {
|
||||
log.Error("TiDB run with skip-grant-table need root privilege.")
|
||||
os.Exit(-1)
|
||||
}
|
||||
if _, ok := config.ValidStorage[cfg.Store]; !ok {
|
||||
nameList := make([]string, 0, len(config.ValidStorage))
|
||||
for k, v := range config.ValidStorage {
|
||||
if v {
|
||||
nameList = append(nameList, k)
|
||||
}
|
||||
}
|
||||
log.Errorf("\"store\" should be in [%s] only", strings.Join(nameList, ", "))
|
||||
os.Exit(-1)
|
||||
}
|
||||
if cfg.Store == "mocktikv" && cfg.RunDDL == false {
|
||||
log.Errorf("can't disable DDL on mocktikv")
|
||||
os.Exit(-1)
|
||||
}
|
||||
if cfg.Log.File.MaxSize > config.MaxLogFileSize {
|
||||
log.Errorf("log max-size should not be larger than %d MB", config.MaxLogFileSize)
|
||||
os.Exit(-1)
|
||||
}
|
||||
if cfg.XProtocol.XServer {
|
||||
log.Error("X Server is not available")
|
||||
os.Exit(-1)
|
||||
}
|
||||
cfg.OOMAction = strings.ToLower(cfg.OOMAction)
|
||||
|
||||
// lower_case_table_names is allowed to be 0, 1, 2
|
||||
if cfg.LowerCaseTableNames < 0 || cfg.LowerCaseTableNames > 2 {
|
||||
log.Errorf("lower-case-table-names should be 0 or 1 or 2.")
|
||||
os.Exit(-1)
|
||||
}
|
||||
}
|
||||
|
||||
func setGlobalVars() {
|
||||
ddlLeaseDuration := parseDuration(cfg.Lease)
|
||||
session.SetSchemaLease(ddlLeaseDuration)
|
||||
runtime.GOMAXPROCS(int(cfg.Performance.MaxProcs))
|
||||
statsLeaseDuration := parseDuration(cfg.Performance.StatsLease)
|
||||
session.SetStatsLease(statsLeaseDuration)
|
||||
domain.RunAutoAnalyze = cfg.Performance.RunAutoAnalyze
|
||||
statistics.FeedbackProbability = cfg.Performance.FeedbackProbability
|
||||
statistics.MaxQueryFeedbackCount = int(cfg.Performance.QueryFeedbackLimit)
|
||||
statistics.RatioOfPseudoEstimate = cfg.Performance.PseudoEstimateRatio
|
||||
ddl.RunWorker = cfg.RunDDL
|
||||
ddl.EnableSplitTableRegion = cfg.SplitTable
|
||||
plannercore.AllowCartesianProduct = cfg.Performance.CrossJoin
|
||||
privileges.SkipWithGrant = cfg.Security.SkipGrantTable
|
||||
variable.ForcePriority = int32(mysql.Str2Priority(cfg.Performance.ForcePriority))
|
||||
|
||||
variable.SysVars[variable.TIDBMemQuotaQuery].Value = strconv.FormatInt(cfg.MemQuotaQuery, 10)
|
||||
variable.SysVars["lower_case_table_names"].Value = strconv.Itoa(cfg.LowerCaseTableNames)
|
||||
|
||||
plannercore.SetPreparedPlanCache(cfg.PreparedPlanCache.Enabled)
|
||||
if plannercore.PreparedPlanCacheEnabled() {
|
||||
plannercore.PreparedPlanCacheCapacity = cfg.PreparedPlanCache.Capacity
|
||||
}
|
||||
|
||||
if cfg.TiKVClient.GrpcConnectionCount > 0 {
|
||||
tikv.MaxConnectionCount = cfg.TiKVClient.GrpcConnectionCount
|
||||
}
|
||||
tikv.GrpcKeepAliveTime = time.Duration(cfg.TiKVClient.GrpcKeepAliveTime) * time.Second
|
||||
tikv.GrpcKeepAliveTimeout = time.Duration(cfg.TiKVClient.GrpcKeepAliveTimeout) * time.Second
|
||||
|
||||
tikv.CommitMaxBackoff = int(parseDuration(cfg.TiKVClient.CommitTimeout).Seconds() * 1000)
|
||||
}
|
||||
|
||||
func printInfo() {
|
||||
// Make sure the TiDB info is always printed.
|
||||
printer.PrintTiDBInfo()
|
||||
}
|
||||
|
||||
func createServer() {
|
||||
var driver server.IDriver
|
||||
driver = server.NewTiDBDriver(storage)
|
||||
var err error
|
||||
svr, err = server.NewServer(cfg, driver)
|
||||
// Both domain and storage have started, so we have to clean them before exiting.
|
||||
terror.MustNil(err, closeDomainAndStorage)
|
||||
if cfg.XProtocol.XServer {
|
||||
xcfg := &xserver.Config{
|
||||
Addr: fmt.Sprintf("%s:%d", cfg.XProtocol.XHost, cfg.XProtocol.XPort),
|
||||
Socket: cfg.XProtocol.XSocket,
|
||||
TokenLimit: cfg.TokenLimit,
|
||||
}
|
||||
xsvr, err = xserver.NewServer(xcfg)
|
||||
terror.MustNil(err, closeDomainAndStorage)
|
||||
}
|
||||
}
|
||||
|
||||
func serverShutdown(isgraceful bool) {
|
||||
if isgraceful {
|
||||
log.Info("graceful database shutdown")
|
||||
graceful = true
|
||||
} else {
|
||||
log.Info("database shutdown")
|
||||
}
|
||||
|
||||
if xsvr != nil {
|
||||
xsvr.Close() // Should close xserver before server.
|
||||
}
|
||||
|
||||
svr.Close()
|
||||
|
||||
log.Info("database server closed")
|
||||
}
|
||||
|
||||
func setupTracing() {
|
||||
tracingCfg := cfg.OpenTracing.ToTracingConfig()
|
||||
tracer, _, err := tracingCfg.New("TiDB")
|
||||
if err != nil {
|
||||
log.Fatal("cannot initialize Jaeger Tracer", err)
|
||||
}
|
||||
opentracing.SetGlobalTracer(tracer)
|
||||
}
|
||||
|
||||
func runServer() {
|
||||
err := svr.Run()
|
||||
if err != nil {
|
||||
log.Errorf("Server failed to run: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func closeDomainAndStorage() {
|
||||
dom.Close()
|
||||
if err := storage.Close(); err != nil {
|
||||
log.Error(errors.Trace(err))
|
||||
} else {
|
||||
log.Info("database storage closed")
|
||||
}
|
||||
}
|
||||
|
||||
func cleanup() {
|
||||
if graceful {
|
||||
svr.GracefulDown()
|
||||
} else {
|
||||
svr.KillAllConnections()
|
||||
}
|
||||
closeDomainAndStorage()
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package tidb
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func InitDatabase(port uint, password string) error {
|
||||
log.Info("init database")
|
||||
|
||||
db, err := sql.Open("mysql", fmt.Sprintf("root:@tcp(localhost:%d)/", port))
|
||||
|
||||
if err != nil {
|
||||
log.Debug(err.Error())
|
||||
log.Debug("database login as root with password")
|
||||
db, err = sql.Open("mysql", fmt.Sprintf("root:%s@tcp(localhost:%d)/", password, port))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
defer db.Close()
|
||||
|
||||
if password != "" {
|
||||
log.Debug("set database password")
|
||||
|
||||
_, err = db.Exec(fmt.Sprintf("SET PASSWORD FOR 'root'@'%%' = '%s'", password))
|
||||
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
} else {
|
||||
log.Debug("flush database privileges")
|
||||
|
||||
_, err = db.Exec("FLUSH PRIVILEGES")
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug("create database if not exists")
|
||||
|
||||
_, err = db.Exec("CREATE DATABASE IF NOT EXISTS photoprism")
|
||||
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
}
|
||||
|
||||
log.Info("database created")
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/mutex"
|
||||
"github.com/photoprism/photoprism/internal/photoprism"
|
||||
"github.com/photoprism/photoprism/internal/query"
|
||||
)
|
||||
|
||||
@@ -104,6 +105,12 @@ func (worker *Prism) Start() (err error) {
|
||||
|
||||
worker.logError(entity.UpdatePhotoCounts())
|
||||
|
||||
moments := photoprism.NewMoments(worker.conf)
|
||||
|
||||
if err := moments.Start(); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
runtime.GC()
|
||||
|
||||
return nil
|
||||
|
||||
@@ -11,6 +11,8 @@ import (
|
||||
func TestPrism_Start(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
t.Logf("database-dsn: %s", conf.DatabaseDsn())
|
||||
|
||||
worker := NewPrism(conf)
|
||||
|
||||
assert.IsType(t, &Prism{}, worker)
|
||||
|
||||
Reference in New Issue
Block a user