Browse Source

将项目修改为go mod模式

weicky 3 years ago
parent
commit
97bc5f3851
96 changed files with 257411 additions and 31 deletions
  1. 0 2
      .env
  2. 1 1
      src/cnphper.com/redisdog/functions.go
  3. 8 0
      go.mod
  4. 6 0
      go.sum
  5. 0 0
      http_debug.go
  6. 1 1
      src/cnphper.com/redisdog/http_index.go
  7. 1 1
      src/cnphper.com/redisdog/http_log_autoprocess.go
  8. 1 1
      src/cnphper.com/redisdog/http_log_monitor.go
  9. 1 1
      src/cnphper.com/redisdog/http_log_syslog.go
  10. 1 1
      src/cnphper.com/redisdog/http_log_warn.go
  11. 1 1
      src/cnphper.com/redisdog/http_login.go
  12. 1 1
      src/cnphper.com/redisdog/http_profile.go
  13. 1 1
      src/cnphper.com/redisdog/http_syscfg_account.go
  14. 1 1
      src/cnphper.com/redisdog/http_syscfg_misc.go
  15. 1 1
      src/cnphper.com/redisdog/http_syscfg_redis.go
  16. 1 1
      src/cnphper.com/redisdog/http_syscfg_warn.go
  17. 0 0
      mail_sender.go
  18. 1 1
      src/cnphper.com/redisdog/main.go
  19. 1 13
      make.sh
  20. 0 0
      model/accounts.go
  21. 0 0
      model/model.go
  22. 0 0
      model/monitorlog.go
  23. 0 0
      model/processlog.go
  24. 0 0
      model/rediscfg.go
  25. 0 0
      model/syscfg.go
  26. 0 0
      model/syslog.go
  27. 0 0
      model/warnlog.go
  28. 1 1
      src/cnphper.com/redisdog/redis_monitor.go
  29. 1 1
      src/cnphper.com/redisdog/session_pool.go
  30. 0 0
      sql_vars.go
  31. 1 1
      src/cnphper.com/redisdog/syscfg_cache.go
  32. 175 0
      vendor/github.com/gomodule/redigo/LICENSE
  33. 54 0
      vendor/github.com/gomodule/redigo/internal/commandinfo.go
  34. 673 0
      vendor/github.com/gomodule/redigo/redis/conn.go
  35. 177 0
      vendor/github.com/gomodule/redigo/redis/doc.go
  36. 27 0
      vendor/github.com/gomodule/redigo/redis/go16.go
  37. 29 0
      vendor/github.com/gomodule/redigo/redis/go17.go
  38. 9 0
      vendor/github.com/gomodule/redigo/redis/go18.go
  39. 134 0
      vendor/github.com/gomodule/redigo/redis/log.go
  40. 562 0
      vendor/github.com/gomodule/redigo/redis/pool.go
  41. 35 0
      vendor/github.com/gomodule/redigo/redis/pool17.go
  42. 148 0
      vendor/github.com/gomodule/redigo/redis/pubsub.go
  43. 117 0
      vendor/github.com/gomodule/redigo/redis/redis.go
  44. 479 0
      vendor/github.com/gomodule/redigo/redis/reply.go
  45. 585 0
      vendor/github.com/gomodule/redigo/redis/scan.go
  46. 91 0
      vendor/github.com/gomodule/redigo/redis/script.go
  47. 4 0
      vendor/github.com/mattn/go-sqlite3/.codecov.yml
  48. 14 0
      vendor/github.com/mattn/go-sqlite3/.gitignore
  49. 21 0
      vendor/github.com/mattn/go-sqlite3/LICENSE
  50. 592 0
      vendor/github.com/mattn/go-sqlite3/README.md
  51. 85 0
      vendor/github.com/mattn/go-sqlite3/backup.go
  52. 392 0
      vendor/github.com/mattn/go-sqlite3/callback.go
  53. 299 0
      vendor/github.com/mattn/go-sqlite3/convert.go
  54. 135 0
      vendor/github.com/mattn/go-sqlite3/doc.go
  55. 150 0
      vendor/github.com/mattn/go-sqlite3/error.go
  56. 3 0
      vendor/github.com/mattn/go-sqlite3/go.mod
  57. 0 0
      vendor/github.com/mattn/go-sqlite3/go.sum
  58. 234589 0
      vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
  59. 12365 0
      vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
  60. 2183 0
      vendor/github.com/mattn/go-sqlite3/sqlite3.go
  61. 103 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_context.go
  62. 120 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_func_crypt.go
  63. 70 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_go18.go
  64. 19 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go
  65. 84 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension.go
  66. 24 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension_omit.go
  67. 15 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_allow_uri_authority.go
  68. 16 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_app_armor.go
  69. 21 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_column_metadata.go
  70. 15 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_foreign_keys.go
  71. 14 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_fts5.go
  72. 17 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_icu.go
  73. 15 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_introspect.go
  74. 13 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_json1.go
  75. 20 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate.go
  76. 112 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_hook.go
  77. 21 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_omit.go
  78. 15 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_secure_delete.go
  79. 15 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_secure_delete_fast.go
  80. 15 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_stat4.go
  81. 85 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.c
  82. 93 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.go
  83. 289 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_userauth.go
  84. 152 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_userauth_omit.go
  85. 15 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vacuum_full.go
  86. 15 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vacuum_incr.go
  87. 709 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vtable.go
  88. 17 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_other.go
  89. 14 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_solaris.go
  90. 287 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_trace.go
  91. 62 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_type.go
  92. 41 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_usleep_windows.go
  93. 18 0
      vendor/github.com/mattn/go-sqlite3/sqlite3_windows.go
  94. 668 0
      vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
  95. 37 0
      vendor/github.com/mattn/go-sqlite3/static_mock.go
  96. 7 0
      vendor/modules.txt

+ 0 - 2
.env

@@ -1,2 +0,0 @@
-cd $(dirname ${BASH_SOURCE-$0})
-export GOPATH=$(pwd)

+ 1 - 1
src/cnphper.com/redisdog/functions.go

@@ -7,7 +7,7 @@ import (
 	"strings"
 	"time"
 
-	"cnphper.com/model"
+	"redisdog/model"
 	"github.com/gomodule/redigo/redis"
 )
 

+ 8 - 0
go.mod

@@ -0,0 +1,8 @@
+module redisdog
+
+go 1.14
+
+require (
+	github.com/gomodule/redigo v2.0.0+incompatible
+	github.com/mattn/go-sqlite3 v1.14.7
+)

+ 6 - 0
go.sum

@@ -0,0 +1,6 @@
+github.com/gomodule/redigo v1.7.0 h1:ZKld1VOtsGhAe37E7wMxEDgAlGM5dvFY+DiOhSkhP9Y=
+github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
+github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
+github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
+github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
+github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=

src/cnphper.com/redisdog/http_debug.go → http_debug.go


+ 1 - 1
src/cnphper.com/redisdog/http_index.go

@@ -9,7 +9,7 @@ import (
 	"os"
 	"path/filepath"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 type StatRet struct {

+ 1 - 1
src/cnphper.com/redisdog/http_log_autoprocess.go

@@ -9,7 +9,7 @@ import (
 	"path/filepath"
 	"strconv"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 type LogProcessLogListRetData struct {

+ 1 - 1
src/cnphper.com/redisdog/http_log_monitor.go

@@ -9,7 +9,7 @@ import (
 	"path/filepath"
 	"strconv"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 type LogMonitorLogListRetData struct {

+ 1 - 1
src/cnphper.com/redisdog/http_log_syslog.go

@@ -9,7 +9,7 @@ import (
 	"path/filepath"
 	"strconv"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 type LogSysLogListRetData struct {

+ 1 - 1
src/cnphper.com/redisdog/http_log_warn.go

@@ -9,7 +9,7 @@ import (
 	"path/filepath"
 	"strconv"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 type LogWarnLogListRetData struct {

+ 1 - 1
src/cnphper.com/redisdog/http_login.go

@@ -8,7 +8,7 @@ import (
 	"net/http"
 	"path/filepath"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 type LoginRet struct {

+ 1 - 1
src/cnphper.com/redisdog/http_profile.go

@@ -8,7 +8,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 func profile_logout(resp http.ResponseWriter, req *http.Request) {

+ 1 - 1
src/cnphper.com/redisdog/http_syscfg_account.go

@@ -10,7 +10,7 @@ import (
 	"regexp"
 	"strconv"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 type SyscfgAccountListRet struct {

+ 1 - 1
src/cnphper.com/redisdog/http_syscfg_misc.go

@@ -9,7 +9,7 @@ import (
 	"path/filepath"
 	"strconv"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 type SysCfgMiscGetRet struct {

+ 1 - 1
src/cnphper.com/redisdog/http_syscfg_redis.go

@@ -9,7 +9,7 @@ import (
 	"path/filepath"
 	"strconv"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 type SyscfgRedisListRet struct {

+ 1 - 1
src/cnphper.com/redisdog/http_syscfg_warn.go

@@ -8,7 +8,7 @@ import (
 	"net/http"
 	"path/filepath"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 type SysCfgWarnGetRet struct {

src/cnphper.com/redisdog/mail_sender.go → mail_sender.go


+ 1 - 1
src/cnphper.com/redisdog/main.go

@@ -16,7 +16,7 @@ import (
 	"syscall"
 	"time"
 
-	"cnphper.com/model"
+	"redisdog/model"
 	_ "github.com/mattn/go-sqlite3"
 )
 

+ 1 - 13
make.sh

@@ -1,17 +1,5 @@
 #!/bin/bash
 
 cd $(dirname $0)
-ROOT=$(pwd)
 
-source ./.env
-
-INSTALL="src/cnphper.com/model src/cnphper.com/redisdog"
-
-for ITEM in $INSTALL
-do
-	echo $ITEM
-	cd $ROOT/$ITEM
-	go install
-done
-
-cd $ROOT
+go build -o bin/redisdog

src/cnphper.com/model/accounts.go → model/accounts.go


src/cnphper.com/model/model.go → model/model.go


src/cnphper.com/model/monitorlog.go → model/monitorlog.go


src/cnphper.com/model/processlog.go → model/processlog.go


src/cnphper.com/model/rediscfg.go → model/rediscfg.go


src/cnphper.com/model/syscfg.go → model/syscfg.go


src/cnphper.com/model/syslog.go → model/syslog.go


src/cnphper.com/model/warnlog.go → model/warnlog.go


+ 1 - 1
src/cnphper.com/redisdog/redis_monitor.go

@@ -6,7 +6,7 @@ import (
 	"strings"
 	"time"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 const (

+ 1 - 1
src/cnphper.com/redisdog/session_pool.go

@@ -6,7 +6,7 @@ import (
 	"math/rand"
 	"time"
 
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 type Session struct {

src/cnphper.com/redisdog/sql_vars.go → sql_vars.go


+ 1 - 1
src/cnphper.com/redisdog/syscfg_cache.go

@@ -1,7 +1,7 @@
 package main
 
 import (
-	"cnphper.com/model"
+	"redisdog/model"
 )
 
 type SysCfgCache struct {

+ 175 - 0
vendor/github.com/gomodule/redigo/LICENSE

@@ -0,0 +1,175 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.

+ 54 - 0
vendor/github.com/gomodule/redigo/internal/commandinfo.go

@@ -0,0 +1,54 @@
+// Copyright 2014 Gary Burd
+//
+// 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, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package internal // import "github.com/gomodule/redigo/internal"
+
+import (
+	"strings"
+)
+
+const (
+	WatchState = 1 << iota
+	MultiState
+	SubscribeState
+	MonitorState
+)
+
+type CommandInfo struct {
+	Set, Clear int
+}
+
+var commandInfos = map[string]CommandInfo{
+	"WATCH":      {Set: WatchState},
+	"UNWATCH":    {Clear: WatchState},
+	"MULTI":      {Set: MultiState},
+	"EXEC":       {Clear: WatchState | MultiState},
+	"DISCARD":    {Clear: WatchState | MultiState},
+	"PSUBSCRIBE": {Set: SubscribeState},
+	"SUBSCRIBE":  {Set: SubscribeState},
+	"MONITOR":    {Set: MonitorState},
+}
+
+func init() {
+	for n, ci := range commandInfos {
+		commandInfos[strings.ToLower(n)] = ci
+	}
+}
+
+func LookupCommandInfo(commandName string) CommandInfo {
+	if ci, ok := commandInfos[commandName]; ok {
+		return ci
+	}
+	return commandInfos[strings.ToUpper(commandName)]
+}

+ 673 - 0
vendor/github.com/gomodule/redigo/redis/conn.go

@@ -0,0 +1,673 @@
+// Copyright 2012 Gary Burd
+//
+// 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, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package redis
+
+import (
+	"bufio"
+	"bytes"
+	"crypto/tls"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"net/url"
+	"regexp"
+	"strconv"
+	"sync"
+	"time"
+)
+
+var (
+	_ ConnWithTimeout = (*conn)(nil)
+)
+
+// conn is the low-level implementation of Conn
+type conn struct {
+	// Shared
+	mu      sync.Mutex
+	pending int
+	err     error
+	conn    net.Conn
+
+	// Read
+	readTimeout time.Duration
+	br          *bufio.Reader
+
+	// Write
+	writeTimeout time.Duration
+	bw           *bufio.Writer
+
+	// Scratch space for formatting argument length.
+	// '*' or '$', length, "\r\n"
+	lenScratch [32]byte
+
+	// Scratch space for formatting integers and floats.
+	numScratch [40]byte
+}
+
+// DialTimeout acts like Dial but takes timeouts for establishing the
+// connection to the server, writing a command and reading a reply.
+//
+// Deprecated: Use Dial with options instead.
+func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error) {
+	return Dial(network, address,
+		DialConnectTimeout(connectTimeout),
+		DialReadTimeout(readTimeout),
+		DialWriteTimeout(writeTimeout))
+}
+
+// DialOption specifies an option for dialing a Redis server.
+type DialOption struct {
+	f func(*dialOptions)
+}
+
+type dialOptions struct {
+	readTimeout  time.Duration
+	writeTimeout time.Duration
+	dialer       *net.Dialer
+	dial         func(network, addr string) (net.Conn, error)
+	db           int
+	password     string
+	useTLS       bool
+	skipVerify   bool
+	tlsConfig    *tls.Config
+}
+
+// DialReadTimeout specifies the timeout for reading a single command reply.
+func DialReadTimeout(d time.Duration) DialOption {
+	return DialOption{func(do *dialOptions) {
+		do.readTimeout = d
+	}}
+}
+
+// DialWriteTimeout specifies the timeout for writing a single command.
+func DialWriteTimeout(d time.Duration) DialOption {
+	return DialOption{func(do *dialOptions) {
+		do.writeTimeout = d
+	}}
+}
+
+// DialConnectTimeout specifies the timeout for connecting to the Redis server when
+// no DialNetDial option is specified.
+func DialConnectTimeout(d time.Duration) DialOption {
+	return DialOption{func(do *dialOptions) {
+		do.dialer.Timeout = d
+	}}
+}
+
+// DialKeepAlive specifies the keep-alive period for TCP connections to the Redis server
+// when no DialNetDial option is specified.
+// If zero, keep-alives are not enabled. If no DialKeepAlive option is specified then
+// the default of 5 minutes is used to ensure that half-closed TCP sessions are detected.
+func DialKeepAlive(d time.Duration) DialOption {
+	return DialOption{func(do *dialOptions) {
+		do.dialer.KeepAlive = d
+	}}
+}
+
+// DialNetDial specifies a custom dial function for creating TCP
+// connections, otherwise a net.Dialer customized via the other options is used.
+// DialNetDial overrides DialConnectTimeout and DialKeepAlive.
+func DialNetDial(dial func(network, addr string) (net.Conn, error)) DialOption {
+	return DialOption{func(do *dialOptions) {
+		do.dial = dial
+	}}
+}
+
+// DialDatabase specifies the database to select when dialing a connection.
+func DialDatabase(db int) DialOption {
+	return DialOption{func(do *dialOptions) {
+		do.db = db
+	}}
+}
+
+// DialPassword specifies the password to use when connecting to
+// the Redis server.
+func DialPassword(password string) DialOption {
+	return DialOption{func(do *dialOptions) {
+		do.password = password
+	}}
+}
+
+// DialTLSConfig specifies the config to use when a TLS connection is dialed.
+// Has no effect when not dialing a TLS connection.
+func DialTLSConfig(c *tls.Config) DialOption {
+	return DialOption{func(do *dialOptions) {
+		do.tlsConfig = c
+	}}
+}
+
+// DialTLSSkipVerify disables server name verification when connecting over
+// TLS. Has no effect when not dialing a TLS connection.
+func DialTLSSkipVerify(skip bool) DialOption {
+	return DialOption{func(do *dialOptions) {
+		do.skipVerify = skip
+	}}
+}
+
+// DialUseTLS specifies whether TLS should be used when connecting to the
+// server. This option is ignore by DialURL.
+func DialUseTLS(useTLS bool) DialOption {
+	return DialOption{func(do *dialOptions) {
+		do.useTLS = useTLS
+	}}
+}
+
+// Dial connects to the Redis server at the given network and
+// address using the specified options.
+func Dial(network, address string, options ...DialOption) (Conn, error) {
+	do := dialOptions{
+		dialer: &net.Dialer{
+			KeepAlive: time.Minute * 5,
+		},
+	}
+	for _, option := range options {
+		option.f(&do)
+	}
+	if do.dial == nil {
+		do.dial = do.dialer.Dial
+	}
+
+	netConn, err := do.dial(network, address)
+	if err != nil {
+		return nil, err
+	}
+
+	if do.useTLS {
+		var tlsConfig *tls.Config
+		if do.tlsConfig == nil {
+			tlsConfig = &tls.Config{InsecureSkipVerify: do.skipVerify}
+		} else {
+			tlsConfig = cloneTLSConfig(do.tlsConfig)
+		}
+		if tlsConfig.ServerName == "" {
+			host, _, err := net.SplitHostPort(address)
+			if err != nil {
+				netConn.Close()
+				return nil, err
+			}
+			tlsConfig.ServerName = host
+		}
+
+		tlsConn := tls.Client(netConn, tlsConfig)
+		if err := tlsConn.Handshake(); err != nil {
+			netConn.Close()
+			return nil, err
+		}
+		netConn = tlsConn
+	}
+
+	c := &conn{
+		conn:         netConn,
+		bw:           bufio.NewWriter(netConn),
+		br:           bufio.NewReader(netConn),
+		readTimeout:  do.readTimeout,
+		writeTimeout: do.writeTimeout,
+	}
+
+	if do.password != "" {
+		if _, err := c.Do("AUTH", do.password); err != nil {
+			netConn.Close()
+			return nil, err
+		}
+	}
+
+	if do.db != 0 {
+		if _, err := c.Do("SELECT", do.db); err != nil {
+			netConn.Close()
+			return nil, err
+		}
+	}
+
+	return c, nil
+}
+
+var pathDBRegexp = regexp.MustCompile(`/(\d*)\z`)
+
+// DialURL connects to a Redis server at the given URL using the Redis
+// URI scheme. URLs should follow the draft IANA specification for the
+// scheme (https://www.iana.org/assignments/uri-schemes/prov/redis).
+func DialURL(rawurl string, options ...DialOption) (Conn, error) {
+	u, err := url.Parse(rawurl)
+	if err != nil {
+		return nil, err
+	}
+
+	if u.Scheme != "redis" && u.Scheme != "rediss" {
+		return nil, fmt.Errorf("invalid redis URL scheme: %s", u.Scheme)
+	}
+
+	// As per the IANA draft spec, the host defaults to localhost and
+	// the port defaults to 6379.
+	host, port, err := net.SplitHostPort(u.Host)
+	if err != nil {
+		// assume port is missing
+		host = u.Host
+		port = "6379"
+	}
+	if host == "" {
+		host = "localhost"
+	}
+	address := net.JoinHostPort(host, port)
+
+	if u.User != nil {
+		password, isSet := u.User.Password()
+		if isSet {
+			options = append(options, DialPassword(password))
+		}
+	}
+
+	match := pathDBRegexp.FindStringSubmatch(u.Path)
+	if len(match) == 2 {
+		db := 0
+		if len(match[1]) > 0 {
+			db, err = strconv.Atoi(match[1])
+			if err != nil {
+				return nil, fmt.Errorf("invalid database: %s", u.Path[1:])
+			}
+		}
+		if db != 0 {
+			options = append(options, DialDatabase(db))
+		}
+	} else if u.Path != "" {
+		return nil, fmt.Errorf("invalid database: %s", u.Path[1:])
+	}
+
+	options = append(options, DialUseTLS(u.Scheme == "rediss"))
+
+	return Dial("tcp", address, options...)
+}
+
+// NewConn returns a new Redigo connection for the given net connection.
+func NewConn(netConn net.Conn, readTimeout, writeTimeout time.Duration) Conn {
+	return &conn{
+		conn:         netConn,
+		bw:           bufio.NewWriter(netConn),
+		br:           bufio.NewReader(netConn),
+		readTimeout:  readTimeout,
+		writeTimeout: writeTimeout,
+	}
+}
+
+func (c *conn) Close() error {
+	c.mu.Lock()
+	err := c.err
+	if c.err == nil {
+		c.err = errors.New("redigo: closed")
+		err = c.conn.Close()
+	}
+	c.mu.Unlock()
+	return err
+}
+
+func (c *conn) fatal(err error) error {
+	c.mu.Lock()
+	if c.err == nil {
+		c.err = err
+		// Close connection to force errors on subsequent calls and to unblock
+		// other reader or writer.
+		c.conn.Close()
+	}
+	c.mu.Unlock()
+	return err
+}
+
+func (c *conn) Err() error {
+	c.mu.Lock()
+	err := c.err
+	c.mu.Unlock()
+	return err
+}
+
+func (c *conn) writeLen(prefix byte, n int) error {
+	c.lenScratch[len(c.lenScratch)-1] = '\n'
+	c.lenScratch[len(c.lenScratch)-2] = '\r'
+	i := len(c.lenScratch) - 3
+	for {
+		c.lenScratch[i] = byte('0' + n%10)
+		i -= 1
+		n = n / 10
+		if n == 0 {
+			break
+		}
+	}
+	c.lenScratch[i] = prefix
+	_, err := c.bw.Write(c.lenScratch[i:])
+	return err
+}
+
+func (c *conn) writeString(s string) error {
+	c.writeLen('$', len(s))
+	c.bw.WriteString(s)
+	_, err := c.bw.WriteString("\r\n")
+	return err
+}
+
+func (c *conn) writeBytes(p []byte) error {
+	c.writeLen('$', len(p))
+	c.bw.Write(p)
+	_, err := c.bw.WriteString("\r\n")
+	return err
+}
+
+func (c *conn) writeInt64(n int64) error {
+	return c.writeBytes(strconv.AppendInt(c.numScratch[:0], n, 10))
+}
+
+func (c *conn) writeFloat64(n float64) error {
+	return c.writeBytes(strconv.AppendFloat(c.numScratch[:0], n, 'g', -1, 64))
+}
+
+func (c *conn) writeCommand(cmd string, args []interface{}) error {
+	c.writeLen('*', 1+len(args))
+	if err := c.writeString(cmd); err != nil {
+		return err
+	}
+	for _, arg := range args {
+		if err := c.writeArg(arg, true); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (c *conn) writeArg(arg interface{}, argumentTypeOK bool) (err error) {
+	switch arg := arg.(type) {
+	case string:
+		return c.writeString(arg)
+	case []byte:
+		return c.writeBytes(arg)
+	case int:
+		return c.writeInt64(int64(arg))
+	case int64:
+		return c.writeInt64(arg)
+	case float64:
+		return c.writeFloat64(arg)
+	case bool:
+		if arg {
+			return c.writeString("1")
+		} else {
+			return c.writeString("0")
+		}
+	case nil:
+		return c.writeString("")
+	case Argument:
+		if argumentTypeOK {
+			return c.writeArg(arg.RedisArg(), false)
+		}
+		// See comment in default clause below.
+		var buf bytes.Buffer
+		fmt.Fprint(&buf, arg)
+		return c.writeBytes(buf.Bytes())
+	default:
+		// This default clause is intended to handle builtin numeric types.
+		// The function should return an error for other types, but this is not
+		// done for compatibility with previous versions of the package.
+		var buf bytes.Buffer
+		fmt.Fprint(&buf, arg)
+		return c.writeBytes(buf.Bytes())
+	}
+}
+
+type protocolError string
+
+func (pe protocolError) Error() string {
+	return fmt.Sprintf("redigo: %s (possible server error or unsupported concurrent read by application)", string(pe))
+}
+
+func (c *conn) readLine() ([]byte, error) {
+	p, err := c.br.ReadSlice('\n')
+	if err == bufio.ErrBufferFull {
+		return nil, protocolError("long response line")
+	}
+	if err != nil {
+		return nil, err
+	}
+	i := len(p) - 2
+	if i < 0 || p[i] != '\r' {
+		return nil, protocolError("bad response line terminator")
+	}
+	return p[:i], nil
+}
+
+// parseLen parses bulk string and array lengths.
+func parseLen(p []byte) (int, error) {
+	if len(p) == 0 {
+		return -1, protocolError("malformed length")
+	}
+
+	if p[0] == '-' && len(p) == 2 && p[1] == '1' {
+		// handle $-1 and $-1 null replies.
+		return -1, nil
+	}
+
+	var n int
+	for _, b := range p {
+		n *= 10
+		if b < '0' || b > '9' {
+			return -1, protocolError("illegal bytes in length")
+		}
+		n += int(b - '0')
+	}
+
+	return n, nil
+}
+
+// parseInt parses an integer reply.
+func parseInt(p []byte) (interface{}, error) {
+	if len(p) == 0 {
+		return 0, protocolError("malformed integer")
+	}
+
+	var negate bool
+	if p[0] == '-' {
+		negate = true
+		p = p[1:]
+		if len(p) == 0 {
+			return 0, protocolError("malformed integer")
+		}
+	}
+
+	var n int64
+	for _, b := range p {
+		n *= 10
+		if b < '0' || b > '9' {
+			return 0, protocolError("illegal bytes in length")
+		}
+		n += int64(b - '0')
+	}
+
+	if negate {
+		n = -n
+	}
+	return n, nil
+}
+
+var (
+	okReply   interface{} = "OK"
+	pongReply interface{} = "PONG"
+)
+
+func (c *conn) readReply() (interface{}, error) {
+	line, err := c.readLine()
+	if err != nil {
+		return nil, err
+	}
+	if len(line) == 0 {
+		return nil, protocolError("short response line")
+	}
+	switch line[0] {
+	case '+':
+		switch {
+		case len(line) == 3 && line[1] == 'O' && line[2] == 'K':
+			// Avoid allocation for frequent "+OK" response.
+			return okReply, nil
+		case len(line) == 5 && line[1] == 'P' && line[2] == 'O' && line[3] == 'N' && line[4] == 'G':
+			// Avoid allocation in PING command benchmarks :)
+			return pongReply, nil
+		default:
+			return string(line[1:]), nil
+		}
+	case '-':
+		return Error(string(line[1:])), nil
+	case ':':
+		return parseInt(line[1:])
+	case '$':
+		n, err := parseLen(line[1:])
+		if n < 0 || err != nil {
+			return nil, err
+		}
+		p := make([]byte, n)
+		_, err = io.ReadFull(c.br, p)
+		if err != nil {
+			return nil, err
+		}
+		if line, err := c.readLine(); err != nil {
+			return nil, err
+		} else if len(line) != 0 {
+			return nil, protocolError("bad bulk string format")
+		}
+		return p, nil
+	case '*':
+		n, err := parseLen(line[1:])
+		if n < 0 || err != nil {
+			return nil, err
+		}
+		r := make([]interface{}, n)
+		for i := range r {
+			r[i], err = c.readReply()
+			if err != nil {
+				return nil, err
+			}
+		}
+		return r, nil
+	}
+	return nil, protocolError("unexpected response line")
+}
+
+func (c *conn) Send(cmd string, args ...interface{}) error {
+	c.mu.Lock()
+	c.pending += 1
+	c.mu.Unlock()
+	if c.writeTimeout != 0 {
+		c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
+	}
+	if err := c.writeCommand(cmd, args); err != nil {
+		return c.fatal(err)
+	}
+	return nil
+}
+
+func (c *conn) Flush() error {
+	if c.writeTimeout != 0 {
+		c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
+	}
+	if err := c.bw.Flush(); err != nil {
+		return c.fatal(err)
+	}
+	return nil
+}
+
+func (c *conn) Receive() (interface{}, error) {
+	return c.ReceiveWithTimeout(c.readTimeout)
+}
+
+func (c *conn) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) {
+	var deadline time.Time
+	if timeout != 0 {
+		deadline = time.Now().Add(timeout)
+	}
+	c.conn.SetReadDeadline(deadline)
+
+	if reply, err = c.readReply(); err != nil {
+		return nil, c.fatal(err)
+	}
+	// When using pub/sub, the number of receives can be greater than the
+	// number of sends. To enable normal use of the connection after
+	// unsubscribing from all channels, we do not decrement pending to a
+	// negative value.
+	//
+	// The pending field is decremented after the reply is read to handle the
+	// case where Receive is called before Send.
+	c.mu.Lock()
+	if c.pending > 0 {
+		c.pending -= 1
+	}
+	c.mu.Unlock()
+	if err, ok := reply.(Error); ok {
+		return nil, err
+	}
+	return
+}
+
+func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
+	return c.DoWithTimeout(c.readTimeout, cmd, args...)
+}
+
+func (c *conn) DoWithTimeout(readTimeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
+	c.mu.Lock()
+	pending := c.pending
+	c.pending = 0
+	c.mu.Unlock()
+
+	if cmd == "" && pending == 0 {
+		return nil, nil
+	}
+
+	if c.writeTimeout != 0 {
+		c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
+	}
+
+	if cmd != "" {
+		if err := c.writeCommand(cmd, args); err != nil {
+			return nil, c.fatal(err)
+		}
+	}
+
+	if err := c.bw.Flush(); err != nil {
+		return nil, c.fatal(err)
+	}
+
+	var deadline time.Time
+	if readTimeout != 0 {
+		deadline = time.Now().Add(readTimeout)
+	}
+	c.conn.SetReadDeadline(deadline)
+
+	if cmd == "" {
+		reply := make([]interface{}, pending)
+		for i := range reply {
+			r, e := c.readReply()
+			if e != nil {
+				return nil, c.fatal(e)
+			}
+			reply[i] = r
+		}
+		return reply, nil
+	}
+
+	var err error
+	var reply interface{}
+	for i := 0; i <= pending; i++ {
+		var e error
+		if reply, e = c.readReply(); e != nil {
+			return nil, c.fatal(e)
+		}
+		if e, ok := reply.(Error); ok && err == nil {
+			err = e
+		}
+	}
+	return reply, err
+}

+ 177 - 0
vendor/github.com/gomodule/redigo/redis/doc.go

@@ -0,0 +1,177 @@
+// Copyright 2012 Gary Burd
+//
+// 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, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+// Package redis is a client for the Redis database.
+//
+// The Redigo FAQ (https://github.com/gomodule/redigo/wiki/FAQ) contains more
+// documentation about this package.
+//
+// Connections
+//
+// The Conn interface is the primary interface for working with Redis.
+// Applications create connections by calling the Dial, DialWithTimeout or
+// NewConn functions. In the future, functions will be added for creating
+// sharded and other types of connections.
+//
+// The application must call the connection Close method when the application
+// is done with the connection.
+//
+// Executing Commands
+//
+// The Conn interface has a generic method for executing Redis commands:
+//
+//  Do(commandName string, args ...interface{}) (reply interface{}, err error)
+//
+// The Redis command reference (http://redis.io/commands) lists the available
+// commands. An example of using the Redis APPEND command is:
+//
+//  n, err := conn.Do("APPEND", "key", "value")
+//
+// The Do method converts command arguments to bulk strings for transmission
+// to the server as follows:
+//
+//  Go Type                 Conversion
+//  []byte                  Sent as is
+//  string                  Sent as is
+//  int, int64              strconv.FormatInt(v)
+//  float64                 strconv.FormatFloat(v, 'g', -1, 64)
+//  bool                    true -> "1", false -> "0"
+//  nil                     ""
+//  all other types         fmt.Fprint(w, v)
+//
+// Redis command reply types are represented using the following Go types:
+//
+//  Redis type              Go type
+//  error                   redis.Error
+//  integer                 int64
+//  simple string           string
+//  bulk string             []byte or nil if value not present.
+//  array                   []interface{} or nil if value not present.
+//
+// Use type assertions or the reply helper functions to convert from
+// interface{} to the specific Go type for the command result.
+//
+// Pipelining
+//
+// Connections support pipelining using the Send, Flush and Receive methods.
+//
+//  Send(commandName string, args ...interface{}) error
+//  Flush() error
+//  Receive() (reply interface{}, err error)
+//
+// Send writes the command to the connection's output buffer. Flush flushes the
+// connection's output buffer to the server. Receive reads a single reply from
+// the server. The following example shows a simple pipeline.
+//
+//  c.Send("SET", "foo", "bar")
+//  c.Send("GET", "foo")
+//  c.Flush()
+//  c.Receive() // reply from SET
+//  v, err = c.Receive() // reply from GET
+//
+// The Do method combines the functionality of the Send, Flush and Receive
+// methods. The Do method starts by writing the command and flushing the output
+// buffer. Next, the Do method receives all pending replies including the reply
+// for the command just sent by Do. If any of the received replies is an error,
+// then Do returns the error. If there are no errors, then Do returns the last
+// reply. If the command argument to the Do method is "", then the Do method
+// will flush the output buffer and receive pending replies without sending a
+// command.
+//
+// Use the Send and Do methods to implement pipelined transactions.
+//
+//  c.Send("MULTI")
+//  c.Send("INCR", "foo")
+//  c.Send("INCR", "bar")
+//  r, err := c.Do("EXEC")
+//  fmt.Println(r) // prints [1, 1]
+//
+// Concurrency
+//
+// Connections support one concurrent caller to the Receive method and one
+// concurrent caller to the Send and Flush methods. No other concurrency is
+// supported including concurrent calls to the Do method.
+//
+// For full concurrent access to Redis, use the thread-safe Pool to get, use
+// and release a connection from within a goroutine. Connections returned from
+// a Pool have the concurrency restrictions described in the previous
+// paragraph.
+//
+// Publish and Subscribe
+//
+// Use the Send, Flush and Receive methods to implement Pub/Sub subscribers.
+//
+//  c.Send("SUBSCRIBE", "example")
+//  c.Flush()
+//  for {
+//      reply, err := c.Receive()
+//      if err != nil {
+//          return err
+//      }
+//      // process pushed message
+//  }
+//
+// The PubSubConn type wraps a Conn with convenience methods for implementing
+// subscribers. The Subscribe, PSubscribe, Unsubscribe and PUnsubscribe methods
+// send and flush a subscription management command. The receive method
+// converts a pushed message to convenient types for use in a type switch.
+//
+//  psc := redis.PubSubConn{Conn: c}
+//  psc.Subscribe("example")
+//  for {
+//      switch v := psc.Receive().(type) {
+//      case redis.Message:
+//          fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
+//      case redis.Subscription:
+//          fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
+//      case error:
+//          return v
+//      }
+//  }
+//
+// Reply Helpers
+//
+// The Bool, Int, Bytes, String, Strings and Values functions convert a reply
+// to a value of a specific type. To allow convenient wrapping of calls to the
+// connection Do and Receive methods, the functions take a second argument of
+// type error.  If the error is non-nil, then the helper function returns the
+// error. If the error is nil, the function converts the reply to the specified
+// type:
+//
+//  exists, err := redis.Bool(c.Do("EXISTS", "foo"))
+//  if err != nil {
+//      // handle error return from c.Do or type conversion error.
+//  }
+//
+// The Scan function converts elements of a array reply to Go types:
+//
+//  var value1 int
+//  var value2 string
+//  reply, err := redis.Values(c.Do("MGET", "key1", "key2"))
+//  if err != nil {
+//      // handle error
+//  }
+//   if _, err := redis.Scan(reply, &value1, &value2); err != nil {
+//      // handle error
+//  }
+//
+// Errors
+//
+// Connection methods return error replies from the server as type redis.Error.
+//
+// Call the connection Err() method to determine if the connection encountered
+// non-recoverable error such as a network error or protocol parsing error. If
+// Err() returns a non-nil value, then the connection is not usable and should
+// be closed.
+package redis // import "github.com/gomodule/redigo/redis"

+ 27 - 0
vendor/github.com/gomodule/redigo/redis/go16.go

@@ -0,0 +1,27 @@
+// +build !go1.7
+
+package redis
+
+import "crypto/tls"
+
+func cloneTLSConfig(cfg *tls.Config) *tls.Config {
+	return &tls.Config{
+		Rand:                     cfg.Rand,
+		Time:                     cfg.Time,
+		Certificates:             cfg.Certificates,
+		NameToCertificate:        cfg.NameToCertificate,
+		GetCertificate:           cfg.GetCertificate,
+		RootCAs:                  cfg.RootCAs,
+		NextProtos:               cfg.NextProtos,
+		ServerName:               cfg.ServerName,
+		ClientAuth:               cfg.ClientAuth,
+		ClientCAs:                cfg.ClientCAs,
+		InsecureSkipVerify:       cfg.InsecureSkipVerify,
+		CipherSuites:             cfg.CipherSuites,
+		PreferServerCipherSuites: cfg.PreferServerCipherSuites,
+		ClientSessionCache:       cfg.ClientSessionCache,
+		MinVersion:               cfg.MinVersion,
+		MaxVersion:               cfg.MaxVersion,
+		CurvePreferences:         cfg.CurvePreferences,
+	}
+}

+ 29 - 0
vendor/github.com/gomodule/redigo/redis/go17.go

@@ -0,0 +1,29 @@
+// +build go1.7,!go1.8
+
+package redis
+
+import "crypto/tls"
+
+func cloneTLSConfig(cfg *tls.Config) *tls.Config {
+	return &tls.Config{
+		Rand:                        cfg.Rand,
+		Time:                        cfg.Time,
+		Certificates:                cfg.Certificates,
+		NameToCertificate:           cfg.NameToCertificate,
+		GetCertificate:              cfg.GetCertificate,
+		RootCAs:                     cfg.RootCAs,
+		NextProtos:                  cfg.NextProtos,
+		ServerName:                  cfg.ServerName,
+		ClientAuth:                  cfg.ClientAuth,
+		ClientCAs:                   cfg.ClientCAs,
+		InsecureSkipVerify:          cfg.InsecureSkipVerify,
+		CipherSuites:                cfg.CipherSuites,
+		PreferServerCipherSuites:    cfg.PreferServerCipherSuites,
+		ClientSessionCache:          cfg.ClientSessionCache,
+		MinVersion:                  cfg.MinVersion,
+		MaxVersion:                  cfg.MaxVersion,
+		CurvePreferences:            cfg.CurvePreferences,
+		DynamicRecordSizingDisabled: cfg.DynamicRecordSizingDisabled,
+		Renegotiation:               cfg.Renegotiation,
+	}
+}

+ 9 - 0
vendor/github.com/gomodule/redigo/redis/go18.go

@@ -0,0 +1,9 @@
+// +build go1.8
+
+package redis
+
+import "crypto/tls"
+
+func cloneTLSConfig(cfg *tls.Config) *tls.Config {
+	return cfg.Clone()
+}

+ 134 - 0
vendor/github.com/gomodule/redigo/redis/log.go

@@ -0,0 +1,134 @@
+// Copyright 2012 Gary Burd
+//
+// 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, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package redis
+
+import (
+	"bytes"
+	"fmt"
+	"log"
+	"time"
+)
+
+var (
+	_ ConnWithTimeout = (*loggingConn)(nil)
+)
+
+// NewLoggingConn returns a logging wrapper around a connection.
+func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn {
+	if prefix != "" {
+		prefix = prefix + "."
+	}
+	return &loggingConn{conn, logger, prefix}
+}
+
+type loggingConn struct {
+	Conn
+	logger *log.Logger
+	prefix string
+}
+
+func (c *loggingConn) Close() error {
+	err := c.Conn.Close()
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "%sClose() -> (%v)", c.prefix, err)
+	c.logger.Output(2, buf.String())
+	return err
+}
+
+func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) {
+	const chop = 32
+	switch v := v.(type) {
+	case []byte:
+		if len(v) > chop {
+			fmt.Fprintf(buf, "%q...", v[:chop])
+		} else {
+			fmt.Fprintf(buf, "%q", v)
+		}
+	case string:
+		if len(v) > chop {
+			fmt.Fprintf(buf, "%q...", v[:chop])
+		} else {
+			fmt.Fprintf(buf, "%q", v)
+		}
+	case []interface{}:
+		if len(v) == 0 {
+			buf.WriteString("[]")
+		} else {
+			sep := "["
+			fin := "]"
+			if len(v) > chop {
+				v = v[:chop]
+				fin = "...]"
+			}
+			for _, vv := range v {
+				buf.WriteString(sep)
+				c.printValue(buf, vv)
+				sep = ", "
+			}
+			buf.WriteString(fin)
+		}
+	default:
+		fmt.Fprint(buf, v)
+	}
+}
+
+func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) {
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "%s%s(", c.prefix, method)
+	if method != "Receive" {
+		buf.WriteString(commandName)
+		for _, arg := range args {
+			buf.WriteString(", ")
+			c.printValue(&buf, arg)
+		}
+	}
+	buf.WriteString(") -> (")
+	if method != "Send" {
+		c.printValue(&buf, reply)
+		buf.WriteString(", ")
+	}
+	fmt.Fprintf(&buf, "%v)", err)
+	c.logger.Output(3, buf.String())
+}
+
+func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{}, error) {
+	reply, err := c.Conn.Do(commandName, args...)
+	c.print("Do", commandName, args, reply, err)
+	return reply, err
+}
+
+func (c *loggingConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (interface{}, error) {
+	reply, err := DoWithTimeout(c.Conn, timeout, commandName, args...)
+	c.print("DoWithTimeout", commandName, args, reply, err)
+	return reply, err
+}
+
+func (c *loggingConn) Send(commandName string, args ...interface{}) error {
+	err := c.Conn.Send(commandName, args...)
+	c.print("Send", commandName, args, nil, err)
+	return err
+}
+
+func (c *loggingConn) Receive() (interface{}, error) {
+	reply, err := c.Conn.Receive()
+	c.print("Receive", "", nil, reply, err)
+	return reply, err
+}
+
+func (c *loggingConn) ReceiveWithTimeout(timeout time.Duration) (interface{}, error) {
+	reply, err := ReceiveWithTimeout(c.Conn, timeout)
+	c.print("ReceiveWithTimeout", "", nil, reply, err)
+	return reply, err
+}

+ 562 - 0
vendor/github.com/gomodule/redigo/redis/pool.go

@@ -0,0 +1,562 @@
+// Copyright 2012 Gary Burd
+//
+// 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, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package redis
+
+import (
+	"bytes"
+	"crypto/rand"
+	"crypto/sha1"
+	"errors"
+	"io"
+	"strconv"
+	"sync"
+	"sync/atomic"
+	"time"
+
+	"github.com/gomodule/redigo/internal"
+)
+
+var (
+	_ ConnWithTimeout = (*activeConn)(nil)
+	_ ConnWithTimeout = (*errorConn)(nil)
+)
+
+var nowFunc = time.Now // for testing
+
+// ErrPoolExhausted is returned from a pool connection method (Do, Send,
+// Receive, Flush, Err) when the maximum number of database connections in the
+// pool has been reached.
+var ErrPoolExhausted = errors.New("redigo: connection pool exhausted")
+
+var (
+	errPoolClosed = errors.New("redigo: connection pool closed")
+	errConnClosed = errors.New("redigo: connection closed")
+)
+
+// Pool maintains a pool of connections. The application calls the Get method
+// to get a connection from the pool and the connection's Close method to
+// return the connection's resources to the pool.
+//
+// The following example shows how to use a pool in a web application. The
+// application creates a pool at application startup and makes it available to
+// request handlers using a package level variable. The pool configuration used
+// here is an example, not a recommendation.
+//
+//  func newPool(addr string) *redis.Pool {
+//    return &redis.Pool{
+//      MaxIdle: 3,
+//      IdleTimeout: 240 * time.Second,
+//      Dial: func () (redis.Conn, error) { return redis.Dial("tcp", addr) },
+//    }
+//  }
+//
+//  var (
+//    pool *redis.Pool
+//    redisServer = flag.String("redisServer", ":6379", "")
+//  )
+//
+//  func main() {
+//    flag.Parse()
+//    pool = newPool(*redisServer)
+//    ...
+//  }
+//
+// A request handler gets a connection from the pool and closes the connection
+// when the handler is done:
+//
+//  func serveHome(w http.ResponseWriter, r *http.Request) {
+//      conn := pool.Get()
+//      defer conn.Close()
+//      ...
+//  }
+//
+// Use the Dial function to authenticate connections with the AUTH command or
+// select a database with the SELECT command:
+//
+//  pool := &redis.Pool{
+//    // Other pool configuration not shown in this example.
+//    Dial: func () (redis.Conn, error) {
+//      c, err := redis.Dial("tcp", server)
+//      if err != nil {
+//        return nil, err
+//      }
+//      if _, err := c.Do("AUTH", password); err != nil {
+//        c.Close()
+//        return nil, err
+//      }
+//      if _, err := c.Do("SELECT", db); err != nil {
+//        c.Close()
+//        return nil, err
+//      }
+//      return c, nil
+//    },
+//  }
+//
+// Use the TestOnBorrow function to check the health of an idle connection
+// before the connection is returned to the application. This example PINGs
+// connections that have been idle more than a minute:
+//
+//  pool := &redis.Pool{
+//    // Other pool configuration not shown in this example.
+//    TestOnBorrow: func(c redis.Conn, t time.Time) error {
+//      if time.Since(t) < time.Minute {
+//        return nil
+//      }
+//      _, err := c.Do("PING")
+//      return err
+//    },
+//  }
+//
+type Pool struct {
+	// Dial is an application supplied function for creating and configuring a
+	// connection.
+	//
+	// The connection returned from Dial must not be in a special state
+	// (subscribed to pubsub channel, transaction started, ...).
+	Dial func() (Conn, error)
+
+	// TestOnBorrow is an optional application supplied function for checking
+	// the health of an idle connection before the connection is used again by
+	// the application. Argument t is the time that the connection was returned
+	// to the pool. If the function returns an error, then the connection is
+	// closed.
+	TestOnBorrow func(c Conn, t time.Time) error
+
+	// Maximum number of idle connections in the pool.
+	MaxIdle int
+
+	// Maximum number of connections allocated by the pool at a given time.
+	// When zero, there is no limit on the number of connections in the pool.
+	MaxActive int
+
+	// Close connections after remaining idle for this duration. If the value
+	// is zero, then idle connections are not closed. Applications should set
+	// the timeout to a value less than the server's timeout.
+	IdleTimeout time.Duration
+
+	// If Wait is true and the pool is at the MaxActive limit, then Get() waits
+	// for a connection to be returned to the pool before returning.
+	Wait bool
+
+	// Close connections older than this duration. If the value is zero, then
+	// the pool does not close connections based on age.
+	MaxConnLifetime time.Duration
+
+	chInitialized uint32 // set to 1 when field ch is initialized
+
+	mu     sync.Mutex    // mu protects the following fields
+	closed bool          // set to true when the pool is closed.
+	active int           // the number of open connections in the pool
+	ch     chan struct{} // limits open connections when p.Wait is true
+	idle   idleList      // idle connections
+}
+
+// NewPool creates a new pool.
+//
+// Deprecated: Initialize the Pool directory as shown in the example.
+func NewPool(newFn func() (Conn, error), maxIdle int) *Pool {
+	return &Pool{Dial: newFn, MaxIdle: maxIdle}
+}
+
+// Get gets a connection. The application must close the returned connection.
+// This method always returns a valid connection so that applications can defer
+// error handling to the first use of the connection. If there is an error
+// getting an underlying connection, then the connection Err, Do, Send, Flush
+// and Receive methods return that error.
+func (p *Pool) Get() Conn {
+	pc, err := p.get(nil)
+	if err != nil {
+		return errorConn{err}
+	}
+	return &activeConn{p: p, pc: pc}
+}
+
+// PoolStats contains pool statistics.
+type PoolStats struct {
+	// ActiveCount is the number of connections in the pool. The count includes
+	// idle connections and connections in use.
+	ActiveCount int
+	// IdleCount is the number of idle connections in the pool.
+	IdleCount int
+}
+
+// Stats returns pool's statistics.
+func (p *Pool) Stats() PoolStats {
+	p.mu.Lock()
+	stats := PoolStats{
+		ActiveCount: p.active,
+		IdleCount:   p.idle.count,
+	}
+	p.mu.Unlock()
+
+	return stats
+}
+
+// ActiveCount returns the number of connections in the pool. The count
+// includes idle connections and connections in use.
+func (p *Pool) ActiveCount() int {
+	p.mu.Lock()
+	active := p.active
+	p.mu.Unlock()
+	return active
+}
+
+// IdleCount returns the number of idle connections in the pool.
+func (p *Pool) IdleCount() int {
+	p.mu.Lock()
+	idle := p.idle.count
+	p.mu.Unlock()
+	return idle
+}
+
+// Close releases the resources used by the pool.
+func (p *Pool) Close() error {
+	p.mu.Lock()
+	if p.closed {
+		p.mu.Unlock()
+		return nil
+	}
+	p.closed = true
+	p.active -= p.idle.count
+	pc := p.idle.front
+	p.idle.count = 0
+	p.idle.front, p.idle.back = nil, nil
+	if p.ch != nil {
+		close(p.ch)
+	}
+	p.mu.Unlock()
+	for ; pc != nil; pc = pc.next {
+		pc.c.Close()
+	}
+	return nil
+}
+
+func (p *Pool) lazyInit() {
+	// Fast path.
+	if atomic.LoadUint32(&p.chInitialized) == 1 {
+		return
+	}
+	// Slow path.
+	p.mu.Lock()
+	if p.chInitialized == 0 {
+		p.ch = make(chan struct{}, p.MaxActive)
+		if p.closed {
+			close(p.ch)
+		} else {
+			for i := 0; i < p.MaxActive; i++ {
+				p.ch <- struct{}{}
+			}
+		}
+		atomic.StoreUint32(&p.chInitialized, 1)
+	}
+	p.mu.Unlock()
+}
+
+// get prunes stale connections and returns a connection from the idle list or
+// creates a new connection.
+func (p *Pool) get(ctx interface {
+	Done() <-chan struct{}
+	Err() error
+}) (*poolConn, error) {
+
+	// Handle limit for p.Wait == true.
+	if p.Wait && p.MaxActive > 0 {
+		p.lazyInit()
+		if ctx == nil {
+			<-p.ch
+		} else {
+			select {
+			case <-p.ch:
+			case <-ctx.Done():
+				return nil, ctx.Err()
+			}
+		}
+	}
+
+	p.mu.Lock()
+
+	// Prune stale connections at the back of the idle list.
+	if p.IdleTimeout > 0 {
+		n := p.idle.count
+		for i := 0; i < n && p.idle.back != nil && p.idle.back.t.Add(p.IdleTimeout).Before(nowFunc()); i++ {
+			pc := p.idle.back
+			p.idle.popBack()
+			p.mu.Unlock()
+			pc.c.Close()
+			p.mu.Lock()
+			p.active--
+		}
+	}
+
+	// Get idle connection from the front of idle list.
+	for p.idle.front != nil {
+		pc := p.idle.front
+		p.idle.popFront()
+		p.mu.Unlock()
+		if (p.TestOnBorrow == nil || p.TestOnBorrow(pc.c, pc.t) == nil) &&
+			(p.MaxConnLifetime == 0 || nowFunc().Sub(pc.created) < p.MaxConnLifetime) {
+			return pc, nil
+		}
+		pc.c.Close()
+		p.mu.Lock()
+		p.active--
+	}
+
+	// Check for pool closed before dialing a new connection.
+	if p.closed {
+		p.mu.Unlock()
+		return nil, errors.New("redigo: get on closed pool")
+	}
+
+	// Handle limit for p.Wait == false.
+	if !p.Wait && p.MaxActive > 0 && p.active >= p.MaxActive {
+		p.mu.Unlock()
+		return nil, ErrPoolExhausted
+	}
+
+	p.active++
+	p.mu.Unlock()
+	c, err := p.Dial()
+	if err != nil {
+		c = nil
+		p.mu.Lock()
+		p.active--
+		if p.ch != nil && !p.closed {
+			p.ch <- struct{}{}
+		}
+		p.mu.Unlock()
+	}
+	return &poolConn{c: c, created: nowFunc()}, err
+}
+
+func (p *Pool) put(pc *poolConn, forceClose bool) error {
+	p.mu.Lock()
+	if !p.closed && !forceClose {
+		pc.t = nowFunc()
+		p.idle.pushFront(pc)
+		if p.idle.count > p.MaxIdle {
+			pc = p.idle.back
+			p.idle.popBack()
+		} else {
+			pc = nil
+		}
+	}
+
+	if pc != nil {
+		p.mu.Unlock()
+		pc.c.Close()
+		p.mu.Lock()
+		p.active--
+	}
+
+	if p.ch != nil && !p.closed {
+		p.ch <- struct{}{}
+	}
+	p.mu.Unlock()
+	return nil
+}
+
+type activeConn struct {
+	p     *Pool
+	pc    *poolConn
+	state int
+}
+
+var (
+	sentinel     []byte
+	sentinelOnce sync.Once
+)
+
+func initSentinel() {
+	p := make([]byte, 64)
+	if _, err := rand.Read(p); err == nil {
+		sentinel = p
+	} else {
+		h := sha1.New()
+		io.WriteString(h, "Oops, rand failed. Use time instead.")
+		io.WriteString(h, strconv.FormatInt(time.Now().UnixNano(), 10))
+		sentinel = h.Sum(nil)
+	}
+}
+
+func (ac *activeConn) Close() error {
+	pc := ac.pc
+	if pc == nil {
+		return nil
+	}
+	ac.pc = nil
+
+	if ac.state&internal.MultiState != 0 {
+		pc.c.Send("DISCARD")
+		ac.state &^= (internal.MultiState | internal.WatchState)
+	} else if ac.state&internal.WatchState != 0 {
+		pc.c.Send("UNWATCH")
+		ac.state &^= internal.WatchState
+	}
+	if ac.state&internal.SubscribeState != 0 {
+		pc.c.Send("UNSUBSCRIBE")
+		pc.c.Send("PUNSUBSCRIBE")
+		// To detect the end of the message stream, ask the server to echo
+		// a sentinel value and read until we see that value.
+		sentinelOnce.Do(initSentinel)
+		pc.c.Send("ECHO", sentinel)
+		pc.c.Flush()
+		for {
+			p, err := pc.c.Receive()
+			if err != nil {
+				break
+			}
+			if p, ok := p.([]byte); ok && bytes.Equal(p, sentinel) {
+				ac.state &^= internal.SubscribeState
+				break
+			}
+		}
+	}
+	pc.c.Do("")
+	ac.p.put(pc, ac.state != 0 || pc.c.Err() != nil)
+	return nil
+}
+
+func (ac *activeConn) Err() error {
+	pc := ac.pc
+	if pc == nil {
+		return errConnClosed
+	}
+	return pc.c.Err()
+}
+
+func (ac *activeConn) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
+	pc := ac.pc
+	if pc == nil {
+		return nil, errConnClosed
+	}
+	ci := internal.LookupCommandInfo(commandName)
+	ac.state = (ac.state | ci.Set) &^ ci.Clear
+	return pc.c.Do(commandName, args...)
+}
+
+func (ac *activeConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error) {
+	pc := ac.pc
+	if pc == nil {
+		return nil, errConnClosed
+	}
+	cwt, ok := pc.c.(ConnWithTimeout)
+	if !ok {
+		return nil, errTimeoutNotSupported
+	}
+	ci := internal.LookupCommandInfo(commandName)
+	ac.state = (ac.state | ci.Set) &^ ci.Clear
+	return cwt.DoWithTimeout(timeout, commandName, args...)
+}
+
+func (ac *activeConn) Send(commandName string, args ...interface{}) error {
+	pc := ac.pc
+	if pc == nil {
+		return errConnClosed
+	}
+	ci := internal.LookupCommandInfo(commandName)
+	ac.state = (ac.state | ci.Set) &^ ci.Clear
+	return pc.c.Send(commandName, args...)
+}
+
+func (ac *activeConn) Flush() error {
+	pc := ac.pc
+	if pc == nil {
+		return errConnClosed
+	}
+	return pc.c.Flush()
+}
+
+func (ac *activeConn) Receive() (reply interface{}, err error) {
+	pc := ac.pc
+	if pc == nil {
+		return nil, errConnClosed
+	}
+	return pc.c.Receive()
+}
+
+func (ac *activeConn) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) {
+	pc := ac.pc
+	if pc == nil {
+		return nil, errConnClosed
+	}
+	cwt, ok := pc.c.(ConnWithTimeout)
+	if !ok {
+		return nil, errTimeoutNotSupported
+	}
+	return cwt.ReceiveWithTimeout(timeout)
+}
+
+type errorConn struct{ err error }
+
+func (ec errorConn) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err }
+func (ec errorConn) DoWithTimeout(time.Duration, string, ...interface{}) (interface{}, error) {
+	return nil, ec.err
+}
+func (ec errorConn) Send(string, ...interface{}) error                     { return ec.err }
+func (ec errorConn) Err() error                                            { return ec.err }
+func (ec errorConn) Close() error                                          { return nil }
+func (ec errorConn) Flush() error                                          { return ec.err }
+func (ec errorConn) Receive() (interface{}, error)                         { return nil, ec.err }
+func (ec errorConn) ReceiveWithTimeout(time.Duration) (interface{}, error) { return nil, ec.err }
+
+type idleList struct {
+	count       int
+	front, back *poolConn
+}
+
+type poolConn struct {
+	c          Conn
+	t          time.Time
+	created    time.Time
+	next, prev *poolConn
+}
+
+func (l *idleList) pushFront(pc *poolConn) {
+	pc.next = l.front
+	pc.prev = nil
+	if l.count == 0 {
+		l.back = pc
+	} else {
+		l.front.prev = pc
+	}
+	l.front = pc
+	l.count++
+	return
+}
+
+func (l *idleList) popFront() {
+	pc := l.front
+	l.count--
+	if l.count == 0 {
+		l.front, l.back = nil, nil
+	} else {
+		pc.next.prev = nil
+		l.front = pc.next
+	}
+	pc.next, pc.prev = nil, nil
+}
+
+func (l *idleList) popBack() {
+	pc := l.back
+	l.count--
+	if l.count == 0 {
+		l.front, l.back = nil, nil
+	} else {
+		pc.prev.next = nil
+		l.back = pc.prev
+	}
+	pc.next, pc.prev = nil, nil
+}

+ 35 - 0
vendor/github.com/gomodule/redigo/redis/pool17.go

@@ -0,0 +1,35 @@
+// Copyright 2018 Gary Burd
+//
+// 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, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+// +build go1.7
+
+package redis
+
+import "context"
+
+// GetContext gets a connection using the provided context.
+//
+// The provided Context must be non-nil. If the context expires before the
+// connection is complete, an error is returned. Any expiration on the context
+// will not affect the returned connection.
+//
+// If the function completes without error, then the application must close the
+// returned connection.
+func (p *Pool) GetContext(ctx context.Context) (Conn, error) {
+	pc, err := p.get(ctx)
+	if err != nil {
+		return errorConn{err}, err
+	}
+	return &activeConn{p: p, pc: pc}, nil
+}

+ 148 - 0
vendor/github.com/gomodule/redigo/redis/pubsub.go

@@ -0,0 +1,148 @@
+// Copyright 2012 Gary Burd
+//
+// 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, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package redis
+
+import (
+	"errors"
+	"time"
+)
+
+// Subscription represents a subscribe or unsubscribe notification.
+type Subscription struct {
+	// Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe"
+	Kind string
+
+	// The channel that was changed.
+	Channel string
+
+	// The current number of subscriptions for connection.
+	Count int
+}
+
+// Message represents a message notification.
+type Message struct {
+	// The originating channel.
+	Channel string
+
+	// The matched pattern, if any
+	Pattern string
+
+	// The message data.
+	Data []byte
+}
+
+// Pong represents a pubsub pong notification.
+type Pong struct {
+	Data string
+}
+
+// PubSubConn wraps a Conn with convenience methods for subscribers.
+type PubSubConn struct {
+	Conn Conn
+}
+
+// Close closes the connection.
+func (c PubSubConn) Close() error {
+	return c.Conn.Close()
+}
+
+// Subscribe subscribes the connection to the specified channels.
+func (c PubSubConn) Subscribe(channel ...interface{}) error {
+	c.Conn.Send("SUBSCRIBE", channel...)
+	return c.Conn.Flush()
+}
+
+// PSubscribe subscribes the connection to the given patterns.
+func (c PubSubConn) PSubscribe(channel ...interface{}) error {
+	c.Conn.Send("PSUBSCRIBE", channel...)
+	return c.Conn.Flush()
+}
+
+// Unsubscribe unsubscribes the connection from the given channels, or from all
+// of them if none is given.
+func (c PubSubConn) Unsubscribe(channel ...interface{}) error {
+	c.Conn.Send("UNSUBSCRIBE", channel...)
+	return c.Conn.Flush()
+}
+
+// PUnsubscribe unsubscribes the connection from the given patterns, or from all
+// of them if none is given.
+func (c PubSubConn) PUnsubscribe(channel ...interface{}) error {
+	c.Conn.Send("PUNSUBSCRIBE", channel...)
+	return c.Conn.Flush()
+}
+
+// Ping sends a PING to the server with the specified data.
+//
+// The connection must be subscribed to at least one channel or pattern when
+// calling this method.
+func (c PubSubConn) Ping(data string) error {
+	c.Conn.Send("PING", data)
+	return c.Conn.Flush()
+}
+
+// Receive returns a pushed message as a Subscription, Message, Pong or error.
+// The return value is intended to be used directly in a type switch as
+// illustrated in the PubSubConn example.
+func (c PubSubConn) Receive() interface{} {
+	return c.receiveInternal(c.Conn.Receive())
+}
+
+// ReceiveWithTimeout is like Receive, but it allows the application to
+// override the connection's default timeout.
+func (c PubSubConn) ReceiveWithTimeout(timeout time.Duration) interface{} {
+	return c.receiveInternal(ReceiveWithTimeout(c.Conn, timeout))
+}
+
+func (c PubSubConn) receiveInternal(replyArg interface{}, errArg error) interface{} {
+	reply, err := Values(replyArg, errArg)
+	if err != nil {
+		return err
+	}
+
+	var kind string
+	reply, err = Scan(reply, &kind)
+	if err != nil {
+		return err
+	}
+
+	switch kind {
+	case "message":
+		var m Message
+		if _, err := Scan(reply, &m.Channel, &m.Data); err != nil {
+			return err
+		}
+		return m
+	case "pmessage":
+		var m Message
+		if _, err := Scan(reply, &m.Pattern, &m.Channel, &m.Data); err != nil {
+			return err
+		}
+		return m
+	case "subscribe", "psubscribe", "unsubscribe", "punsubscribe":
+		s := Subscription{Kind: kind}
+		if _, err := Scan(reply, &s.Channel, &s.Count); err != nil {
+			return err
+		}
+		return s
+	case "pong":
+		var p Pong
+		if _, err := Scan(reply, &p.Data); err != nil {
+			return err
+		}
+		return p
+	}
+	return errors.New("redigo: unknown pubsub notification")
+}

+ 117 - 0
vendor/github.com/gomodule/redigo/redis/redis.go

@@ -0,0 +1,117 @@
+// Copyright 2012 Gary Burd
+//
+// 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, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package redis
+
+import (
+	"errors"
+	"time"
+)
+
+// Error represents an error returned in a command reply.
+type Error string
+
+func (err Error) Error() string { return string(err) }
+
+// Conn represents a connection to a Redis server.
+type Conn interface {
+	// Close closes the connection.
+	Close() error
+
+	// Err returns a non-nil value when the connection is not usable.
+	Err() error
+
+	// Do sends a command to the server and returns the received reply.
+	Do(commandName string, args ...interface{}) (reply interface{}, err error)
+
+	// Send writes the command to the client's output buffer.
+	Send(commandName string, args ...interface{}) error
+
+	// Flush flushes the output buffer to the Redis server.
+	Flush() error
+
+	// Receive receives a single reply from the Redis server
+	Receive() (reply interface{}, err error)
+}
+
+// Argument is the interface implemented by an object which wants to control how
+// the object is converted to Redis bulk strings.
+type Argument interface {
+	// RedisArg returns a value to be encoded as a bulk string per the
+	// conversions listed in the section 'Executing Commands'.
+	// Implementations should typically return a []byte or string.
+	RedisArg() interface{}
+}
+
+// Scanner is implemented by an object which wants to control its value is
+// interpreted when read from Redis.
+type Scanner interface {
+	// RedisScan assigns a value from a Redis value. The argument src is one of
+	// the reply types listed in the section `Executing Commands`.
+	//
+	// An error should be returned if the value cannot be stored without
+	// loss of information.
+	RedisScan(src interface{}) error
+}
+
+// ConnWithTimeout is an optional interface that allows the caller to override
+// a connection's default read timeout. This interface is useful for executing
+// the BLPOP, BRPOP, BRPOPLPUSH, XREAD and other commands that block at the
+// server.
+//
+// A connection's default read timeout is set with the DialReadTimeout dial
+// option. Applications should rely on the default timeout for commands that do
+// not block at the server.
+//
+// All of the Conn implementations in this package satisfy the ConnWithTimeout
+// interface.
+//
+// Use the DoWithTimeout and ReceiveWithTimeout helper functions to simplify
+// use of this interface.
+type ConnWithTimeout interface {
+	Conn
+
+	// Do sends a command to the server and returns the received reply.
+	// The timeout overrides the read timeout set when dialing the
+	// connection.
+	DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error)
+
+	// Receive receives a single reply from the Redis server. The timeout
+	// overrides the read timeout set when dialing the connection.
+	ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error)
+}
+
+var errTimeoutNotSupported = errors.New("redis: connection does not support ConnWithTimeout")
+
+// DoWithTimeout executes a Redis command with the specified read timeout. If
+// the connection does not satisfy the ConnWithTimeout interface, then an error
+// is returned.
+func DoWithTimeout(c Conn, timeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
+	cwt, ok := c.(ConnWithTimeout)
+	if !ok {
+		return nil, errTimeoutNotSupported
+	}
+	return cwt.DoWithTimeout(timeout, cmd, args...)
+}
+
+// ReceiveWithTimeout receives a reply with the specified read timeout. If the
+// connection does not satisfy the ConnWithTimeout interface, then an error is
+// returned.
+func ReceiveWithTimeout(c Conn, timeout time.Duration) (interface{}, error) {
+	cwt, ok := c.(ConnWithTimeout)
+	if !ok {
+		return nil, errTimeoutNotSupported
+	}
+	return cwt.ReceiveWithTimeout(timeout)
+}

+ 479 - 0
vendor/github.com/gomodule/redigo/redis/reply.go

@@ -0,0 +1,479 @@
+// Copyright 2012 Gary Burd
+//
+// 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, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package redis
+
+import (
+	"errors"
+	"fmt"
+	"strconv"
+)
+
+// ErrNil indicates that a reply value is nil.
+var ErrNil = errors.New("redigo: nil returned")
+
+// Int is a helper that converts a command reply to an integer. If err is not
+// equal to nil, then Int returns 0, err. Otherwise, Int converts the
+// reply to an int as follows:
+//
+//  Reply type    Result
+//  integer       int(reply), nil
+//  bulk string   parsed reply, nil
+//  nil           0, ErrNil
+//  other         0, error
+func Int(reply interface{}, err error) (int, error) {
+	if err != nil {
+		return 0, err
+	}
+	switch reply := reply.(type) {
+	case int64:
+		x := int(reply)
+		if int64(x) != reply {
+			return 0, strconv.ErrRange
+		}
+		return x, nil
+	case []byte:
+		n, err := strconv.ParseInt(string(reply), 10, 0)
+		return int(n), err
+	case nil:
+		return 0, ErrNil
+	case Error:
+		return 0, reply
+	}
+	return 0, fmt.Errorf("redigo: unexpected type for Int, got type %T", reply)
+}
+
+// Int64 is a helper that converts a command reply to 64 bit integer. If err is
+// not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the
+// reply to an int64 as follows:
+//
+//  Reply type    Result
+//  integer       reply, nil
+//  bulk string   parsed reply, nil
+//  nil           0, ErrNil
+//  other         0, error
+func Int64(reply interface{}, err error) (int64, error) {
+	if err != nil {
+		return 0, err
+	}
+	switch reply := reply.(type) {
+	case int64:
+		return reply, nil
+	case []byte:
+		n, err := strconv.ParseInt(string(reply), 10, 64)
+		return n, err
+	case nil:
+		return 0, ErrNil
+	case Error:
+		return 0, reply
+	}
+	return 0, fmt.Errorf("redigo: unexpected type for Int64, got type %T", reply)
+}
+
+var errNegativeInt = errors.New("redigo: unexpected value for Uint64")
+
+// Uint64 is a helper that converts a command reply to 64 bit integer. If err is
+// not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the
+// reply to an int64 as follows:
+//
+//  Reply type    Result
+//  integer       reply, nil
+//  bulk string   parsed reply, nil
+//  nil           0, ErrNil
+//  other         0, error
+func Uint64(reply interface{}, err error) (uint64, error) {
+	if err != nil {
+		return 0, err
+	}
+	switch reply := reply.(type) {
+	case int64:
+		if reply < 0 {
+			return 0, errNegativeInt
+		}
+		return uint64(reply), nil
+	case []byte:
+		n, err := strconv.ParseUint(string(reply), 10, 64)
+		return n, err
+	case nil:
+		return 0, ErrNil
+	case Error:
+		return 0, reply
+	}
+	return 0, fmt.Errorf("redigo: unexpected type for Uint64, got type %T", reply)
+}
+
+// Float64 is a helper that converts a command reply to 64 bit float. If err is
+// not equal to nil, then Float64 returns 0, err. Otherwise, Float64 converts
+// the reply to an int as follows:
+//
+//  Reply type    Result
+//  bulk string   parsed reply, nil
+//  nil           0, ErrNil
+//  other         0, error
+func Float64(reply interface{}, err error) (float64, error) {
+	if err != nil {
+		return 0, err
+	}
+	switch reply := reply.(type) {
+	case []byte:
+		n, err := strconv.ParseFloat(string(reply), 64)
+		return n, err
+	case nil:
+		return 0, ErrNil
+	case Error:
+		return 0, reply
+	}
+	return 0, fmt.Errorf("redigo: unexpected type for Float64, got type %T", reply)
+}
+
+// String is a helper that converts a command reply to a string. If err is not
+// equal to nil, then String returns "", err. Otherwise String converts the
+// reply to a string as follows:
+//
+//  Reply type      Result
+//  bulk string     string(reply), nil
+//  simple string   reply, nil
+//  nil             "",  ErrNil
+//  other           "",  error
+func String(reply interface{}, err error) (string, error) {
+	if err != nil {
+		return "", err
+	}
+	switch reply := reply.(type) {
+	case []byte:
+		return string(reply), nil
+	case string:
+		return reply, nil
+	case nil:
+		return "", ErrNil
+	case Error:
+		return "", reply
+	}
+	return "", fmt.Errorf("redigo: unexpected type for String, got type %T", reply)
+}
+
+// Bytes is a helper that converts a command reply to a slice of bytes. If err
+// is not equal to nil, then Bytes returns nil, err. Otherwise Bytes converts
+// the reply to a slice of bytes as follows:
+//
+//  Reply type      Result
+//  bulk string     reply, nil
+//  simple string   []byte(reply), nil
+//  nil             nil, ErrNil
+//  other           nil, error
+func Bytes(reply interface{}, err error) ([]byte, error) {
+	if err != nil {
+		return nil, err
+	}
+	switch reply := reply.(type) {
+	case []byte:
+		return reply, nil
+	case string:
+		return []byte(reply), nil
+	case nil:
+		return nil, ErrNil
+	case Error:
+		return nil, reply
+	}
+	return nil, fmt.Errorf("redigo: unexpected type for Bytes, got type %T", reply)
+}
+
+// Bool is a helper that converts a command reply to a boolean. If err is not
+// equal to nil, then Bool returns false, err. Otherwise Bool converts the
+// reply to boolean as follows:
+//
+//  Reply type      Result
+//  integer         value != 0, nil
+//  bulk string     strconv.ParseBool(reply)
+//  nil             false, ErrNil
+//  other           false, error
+func Bool(reply interface{}, err error) (bool, error) {
+	if err != nil {
+		return false, err
+	}
+	switch reply := reply.(type) {
+	case int64:
+		return reply != 0, nil
+	case []byte:
+		return strconv.ParseBool(string(reply))
+	case nil:
+		return false, ErrNil
+	case Error:
+		return false, reply
+	}
+	return false, fmt.Errorf("redigo: unexpected type for Bool, got type %T", reply)
+}
+
+// MultiBulk is a helper that converts an array command reply to a []interface{}.
+//
+// Deprecated: Use Values instead.
+func MultiBulk(reply interface{}, err error) ([]interface{}, error) { return Values(reply, err) }
+
+// Values is a helper that converts an array command reply to a []interface{}.
+// If err is not equal to nil, then Values returns nil, err. Otherwise, Values
+// converts the reply as follows:
+//
+//  Reply type      Result
+//  array           reply, nil
+//  nil             nil, ErrNil
+//  other           nil, error
+func Values(reply interface{}, err error) ([]interface{}, error) {
+	if err != nil {
+		return nil, err
+	}
+	switch reply := reply.(type) {
+	case []interface{}:
+		return reply, nil
+	case nil:
+		return nil, ErrNil
+	case Error:
+		return nil, reply
+	}
+	return nil, fmt.Errorf("redigo: unexpected type for Values, got type %T", reply)
+}
+
+func sliceHelper(reply interface{}, err error, name string, makeSlice func(int), assign func(int, interface{}) error) error {
+	if err != nil {
+		return err
+	}
+	switch reply := reply.(type) {
+	case []interface{}:
+		makeSlice(len(reply))
+		for i := range reply {
+			if reply[i] == nil {
+				continue
+			}
+			if err := assign(i, reply[i]); err != nil {
+				return err
+			}
+		}
+		return nil
+	case nil:
+		return ErrNil
+	case Error:
+		return reply
+	}
+	return fmt.Errorf("redigo: unexpected type for %s, got type %T", name, reply)
+}
+
+// Float64s is a helper that converts an array command reply to a []float64. If
+// err is not equal to nil, then Float64s returns nil, err. Nil array items are
+// converted to 0 in the output slice. Floats64 returns an error if an array
+// item is not a bulk string or nil.
+func Float64s(reply interface{}, err error) ([]float64, error) {
+	var result []float64
+	err = sliceHelper(reply, err, "Float64s", func(n int) { result = make([]float64, n) }, func(i int, v interface{}) error {
+		p, ok := v.([]byte)
+		if !ok {
+			return fmt.Errorf("redigo: unexpected element type for Floats64, got type %T", v)
+		}
+		f, err := strconv.ParseFloat(string(p), 64)
+		result[i] = f
+		return err
+	})
+	return result, err
+}
+
+// Strings is a helper that converts an array command reply to a []string. If
+// err is not equal to nil, then Strings returns nil, err. Nil array items are
+// converted to "" in the output slice. Strings returns an error if an array
+// item is not a bulk string or nil.
+func Strings(reply interface{}, err error) ([]string, error) {
+	var result []string
+	err = sliceHelper(reply, err, "Strings", func(n int) { result = make([]string, n) }, func(i int, v interface{}) error {
+		switch v := v.(type) {
+		case string:
+			result[i] = v
+			return nil
+		case []byte:
+			result[i] = string(v)
+			return nil
+		default:
+			return fmt.Errorf("redigo: unexpected element type for Strings, got type %T", v)
+		}
+	})
+	return result, err
+}
+
+// ByteSlices is a helper that converts an array command reply to a [][]byte.
+// If err is not equal to nil, then ByteSlices returns nil, err. Nil array
+// items are stay nil. ByteSlices returns an error if an array item is not a
+// bulk string or nil.
+func ByteSlices(reply interface{}, err error) ([][]byte, error) {
+	var result [][]byte
+	err = sliceHelper(reply, err, "ByteSlices", func(n int) { result = make([][]byte, n) }, func(i int, v interface{}) error {
+		p, ok := v.([]byte)
+		if !ok {
+			return fmt.Errorf("redigo: unexpected element type for ByteSlices, got type %T", v)
+		}
+		result[i] = p
+		return nil
+	})
+	return result, err
+}
+
+// Int64s is a helper that converts an array command reply to a []int64.
+// If err is not equal to nil, then Int64s returns nil, err. Nil array
+// items are stay nil. Int64s returns an error if an array item is not a
+// bulk string or nil.
+func Int64s(reply interface{}, err error) ([]int64, error) {
+	var result []int64
+	err = sliceHelper(reply, err, "Int64s", func(n int) { result = make([]int64, n) }, func(i int, v interface{}) error {
+		switch v := v.(type) {
+		case int64:
+			result[i] = v
+			return nil
+		case []byte:
+			n, err := strconv.ParseInt(string(v), 10, 64)
+			result[i] = n
+			return err
+		default:
+			return fmt.Errorf("redigo: unexpected element type for Int64s, got type %T", v)
+		}
+	})
+	return result, err
+}
+
+// Ints is a helper that converts an array command reply to a []in.
+// If err is not equal to nil, then Ints returns nil, err. Nil array
+// items are stay nil. Ints returns an error if an array item is not a
+// bulk string or nil.
+func Ints(reply interface{}, err error) ([]int, error) {
+	var result []int
+	err = sliceHelper(reply, err, "Ints", func(n int) { result = make([]int, n) }, func(i int, v interface{}) error {
+		switch v := v.(type) {
+		case int64:
+			n := int(v)
+			if int64(n) != v {
+				return strconv.ErrRange
+			}
+			result[i] = n
+			return nil
+		case []byte:
+			n, err := strconv.Atoi(string(v))
+			result[i] = n
+			return err
+		default:
+			return fmt.Errorf("redigo: unexpected element type for Ints, got type %T", v)
+		}
+	})
+	return result, err
+}
+
+// StringMap is a helper that converts an array of strings (alternating key, value)
+// into a map[string]string. The HGETALL and CONFIG GET commands return replies in this format.
+// Requires an even number of values in result.
+func StringMap(result interface{}, err error) (map[string]string, error) {
+	values, err := Values(result, err)
+	if err != nil {
+		return nil, err
+	}
+	if len(values)%2 != 0 {
+		return nil, errors.New("redigo: StringMap expects even number of values result")
+	}
+	m := make(map[string]string, len(values)/2)
+	for i := 0; i < len(values); i += 2 {
+		key, okKey := values[i].([]byte)
+		value, okValue := values[i+1].([]byte)
+		if !okKey || !okValue {
+			return nil, errors.New("redigo: StringMap key not a bulk string value")
+		}
+		m[string(key)] = string(value)
+	}
+	return m, nil
+}
+
+// IntMap is a helper that converts an array of strings (alternating key, value)
+// into a map[string]int. The HGETALL commands return replies in this format.
+// Requires an even number of values in result.
+func IntMap(result interface{}, err error) (map[string]int, error) {
+	values, err := Values(result, err)
+	if err != nil {
+		return nil, err
+	}
+	if len(values)%2 != 0 {
+		return nil, errors.New("redigo: IntMap expects even number of values result")
+	}
+	m := make(map[string]int, len(values)/2)
+	for i := 0; i < len(values); i += 2 {
+		key, ok := values[i].([]byte)
+		if !ok {
+			return nil, errors.New("redigo: IntMap key not a bulk string value")
+		}
+		value, err := Int(values[i+1], nil)
+		if err != nil {
+			return nil, err
+		}
+		m[string(key)] = value
+	}
+	return m, nil
+}
+
+// Int64Map is a helper that converts an array of strings (alternating key, value)
+// into a map[string]int64. The HGETALL commands return replies in this format.
+// Requires an even number of values in result.
+func Int64Map(result interface{}, err error) (map[string]int64, error) {
+	values, err := Values(result, err)
+	if err != nil {
+		return nil, err
+	}
+	if len(values)%2 != 0 {
+		return nil, errors.New("redigo: Int64Map expects even number of values result")
+	}
+	m := make(map[string]int64, len(values)/2)
+	for i := 0; i < len(values); i += 2 {
+		key, ok := values[i].([]byte)
+		if !ok {
+			return nil, errors.New("redigo: Int64Map key not a bulk string value")
+		}
+		value, err := Int64(values[i+1], nil)
+		if err != nil {
+			return nil, err
+		}
+		m[string(key)] = value
+	}
+	return m, nil
+}
+
+// Positions is a helper that converts an array of positions (lat, long)
+// into a [][2]float64. The GEOPOS command returns replies in this format.
+func Positions(result interface{}, err error) ([]*[2]float64, error) {
+	values, err := Values(result, err)
+	if err != nil {
+		return nil, err
+	}
+	positions := make([]*[2]float64, len(values))
+	for i := range values {
+		if values[i] == nil {
+			continue
+		}
+		p, ok := values[i].([]interface{})
+		if !ok {
+			return nil, fmt.Errorf("redigo: unexpected element type for interface slice, got type %T", values[i])
+		}
+		if len(p) != 2 {
+			return nil, fmt.Errorf("redigo: unexpected number of values for a member position, got %d", len(p))
+		}
+		lat, err := Float64(p[0], nil)
+		if err != nil {
+			return nil, err
+		}
+		long, err := Float64(p[1], nil)
+		if err != nil {
+			return nil, err
+		}
+		positions[i] = &[2]float64{lat, long}
+	}
+	return positions, nil
+}

+ 585 - 0
vendor/github.com/gomodule/redigo/redis/scan.go

@@ -0,0 +1,585 @@
+// Copyright 2012 Gary Burd
+//
+// 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, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package redis
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"strconv"
+	"strings"
+	"sync"
+)
+
+func ensureLen(d reflect.Value, n int) {
+	if n > d.Cap() {
+		d.Set(reflect.MakeSlice(d.Type(), n, n))
+	} else {
+		d.SetLen(n)
+	}
+}
+
+func cannotConvert(d reflect.Value, s interface{}) error {
+	var sname string
+	switch s.(type) {
+	case string:
+		sname = "Redis simple string"
+	case Error:
+		sname = "Redis error"
+	case int64:
+		sname = "Redis integer"
+	case []byte:
+		sname = "Redis bulk string"
+	case []interface{}:
+		sname = "Redis array"
+	default:
+		sname = reflect.TypeOf(s).String()
+	}
+	return fmt.Errorf("cannot convert from %s to %s", sname, d.Type())
+}
+
+func convertAssignBulkString(d reflect.Value, s []byte) (err error) {
+	switch d.Type().Kind() {
+	case reflect.Float32, reflect.Float64:
+		var x float64
+		x, err = strconv.ParseFloat(string(s), d.Type().Bits())
+		d.SetFloat(x)
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		var x int64
+		x, err = strconv.ParseInt(string(s), 10, d.Type().Bits())
+		d.SetInt(x)
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		var x uint64
+		x, err = strconv.ParseUint(string(s), 10, d.Type().Bits())
+		d.SetUint(x)
+	case reflect.Bool:
+		var x bool
+		x, err = strconv.ParseBool(string(s))
+		d.SetBool(x)
+	case reflect.String:
+		d.SetString(string(s))
+	case reflect.Slice:
+		if d.Type().Elem().Kind() != reflect.Uint8 {
+			err = cannotConvert(d, s)
+		} else {
+			d.SetBytes(s)
+		}
+	default:
+		err = cannotConvert(d, s)
+	}
+	return
+}
+
+func convertAssignInt(d reflect.Value, s int64) (err error) {
+	switch d.Type().Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		d.SetInt(s)
+		if d.Int() != s {
+			err = strconv.ErrRange
+			d.SetInt(0)
+		}
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		if s < 0 {
+			err = strconv.ErrRange
+		} else {
+			x := uint64(s)
+			d.SetUint(x)
+			if d.Uint() != x {
+				err = strconv.ErrRange
+				d.SetUint(0)
+			}
+		}
+	case reflect.Bool:
+		d.SetBool(s != 0)
+	default:
+		err = cannotConvert(d, s)
+	}
+	return
+}
+
+func convertAssignValue(d reflect.Value, s interface{}) (err error) {
+	if d.Kind() != reflect.Ptr {
+		if d.CanAddr() {
+			d2 := d.Addr()
+			if d2.CanInterface() {
+				if scanner, ok := d2.Interface().(Scanner); ok {
+					return scanner.RedisScan(s)
+				}
+			}
+		}
+	} else if d.CanInterface() {
+		// Already a reflect.Ptr
+		if d.IsNil() {
+			d.Set(reflect.New(d.Type().Elem()))
+		}
+		if scanner, ok := d.Interface().(Scanner); ok {
+			return scanner.RedisScan(s)
+		}
+	}
+
+	switch s := s.(type) {
+	case []byte:
+		err = convertAssignBulkString(d, s)
+	case int64:
+		err = convertAssignInt(d, s)
+	default:
+		err = cannotConvert(d, s)
+	}
+	return err
+}
+
+func convertAssignArray(d reflect.Value, s []interface{}) error {
+	if d.Type().Kind() != reflect.Slice {
+		return cannotConvert(d, s)
+	}
+	ensureLen(d, len(s))
+	for i := 0; i < len(s); i++ {
+		if err := convertAssignValue(d.Index(i), s[i]); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func convertAssign(d interface{}, s interface{}) (err error) {
+	if scanner, ok := d.(Scanner); ok {
+		return scanner.RedisScan(s)
+	}
+
+	// Handle the most common destination types using type switches and
+	// fall back to reflection for all other types.
+	switch s := s.(type) {
+	case nil:
+		// ignore
+	case []byte:
+		switch d := d.(type) {
+		case *string:
+			*d = string(s)
+		case *int:
+			*d, err = strconv.Atoi(string(s))
+		case *bool:
+			*d, err = strconv.ParseBool(string(s))
+		case *[]byte:
+			*d = s
+		case *interface{}:
+			*d = s
+		case nil:
+			// skip value
+		default:
+			if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
+				err = cannotConvert(d, s)
+			} else {
+				err = convertAssignBulkString(d.Elem(), s)
+			}
+		}
+	case int64:
+		switch d := d.(type) {
+		case *int:
+			x := int(s)
+			if int64(x) != s {
+				err = strconv.ErrRange
+				x = 0
+			}
+			*d = x
+		case *bool:
+			*d = s != 0
+		case *interface{}:
+			*d = s
+		case nil:
+			// skip value
+		default:
+			if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
+				err = cannotConvert(d, s)
+			} else {
+				err = convertAssignInt(d.Elem(), s)
+			}
+		}
+	case string:
+		switch d := d.(type) {
+		case *string:
+			*d = s
+		case *interface{}:
+			*d = s
+		case nil:
+			// skip value
+		default:
+			err = cannotConvert(reflect.ValueOf(d), s)
+		}
+	case []interface{}:
+		switch d := d.(type) {
+		case *[]interface{}:
+			*d = s
+		case *interface{}:
+			*d = s
+		case nil:
+			// skip value
+		default:
+			if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
+				err = cannotConvert(d, s)
+			} else {
+				err = convertAssignArray(d.Elem(), s)
+			}
+		}
+	case Error:
+		err = s
+	default:
+		err = cannotConvert(reflect.ValueOf(d), s)
+	}
+	return
+}
+
+// Scan copies from src to the values pointed at by dest.
+//
+// Scan uses RedisScan if available otherwise:
+//
+// The values pointed at by dest must be an integer, float, boolean, string,
+// []byte, interface{} or slices of these types. Scan uses the standard strconv
+// package to convert bulk strings to numeric and boolean types.
+//
+// If a dest value is nil, then the corresponding src value is skipped.
+//
+// If a src element is nil, then the corresponding dest value is not modified.
+//
+// To enable easy use of Scan in a loop, Scan returns the slice of src
+// following the copied values.
+func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error) {
+	if len(src) < len(dest) {
+		return nil, errors.New("redigo.Scan: array short")
+	}
+	var err error
+	for i, d := range dest {
+		err = convertAssign(d, src[i])
+		if err != nil {
+			err = fmt.Errorf("redigo.Scan: cannot assign to dest %d: %v", i, err)
+			break
+		}
+	}
+	return src[len(dest):], err
+}
+
+type fieldSpec struct {
+	name      string
+	index     []int
+	omitEmpty bool
+}
+
+type structSpec struct {
+	m map[string]*fieldSpec
+	l []*fieldSpec
+}
+
+func (ss *structSpec) fieldSpec(name []byte) *fieldSpec {
+	return ss.m[string(name)]
+}
+
+func compileStructSpec(t reflect.Type, depth map[string]int, index []int, ss *structSpec) {
+	for i := 0; i < t.NumField(); i++ {
+		f := t.Field(i)
+		switch {
+		case f.PkgPath != "" && !f.Anonymous:
+			// Ignore unexported fields.
+		case f.Anonymous:
+			// TODO: Handle pointers. Requires change to decoder and
+			// protection against infinite recursion.
+			if f.Type.Kind() == reflect.Struct {
+				compileStructSpec(f.Type, depth, append(index, i), ss)
+			}
+		default:
+			fs := &fieldSpec{name: f.Name}
+			tag := f.Tag.Get("redis")
+			p := strings.Split(tag, ",")
+			if len(p) > 0 {
+				if p[0] == "-" {
+					continue
+				}
+				if len(p[0]) > 0 {
+					fs.name = p[0]
+				}
+				for _, s := range p[1:] {
+					switch s {
+					case "omitempty":
+						fs.omitEmpty = true
+					default:
+						panic(fmt.Errorf("redigo: unknown field tag %s for type %s", s, t.Name()))
+					}
+				}
+			}
+			d, found := depth[fs.name]
+			if !found {
+				d = 1 << 30
+			}
+			switch {
+			case len(index) == d:
+				// At same depth, remove from result.
+				delete(ss.m, fs.name)
+				j := 0
+				for i := 0; i < len(ss.l); i++ {
+					if fs.name != ss.l[i].name {
+						ss.l[j] = ss.l[i]
+						j += 1
+					}
+				}
+				ss.l = ss.l[:j]
+			case len(index) < d:
+				fs.index = make([]int, len(index)+1)
+				copy(fs.index, index)
+				fs.index[len(index)] = i
+				depth[fs.name] = len(index)
+				ss.m[fs.name] = fs
+				ss.l = append(ss.l, fs)
+			}
+		}
+	}
+}
+
+var (
+	structSpecMutex  sync.RWMutex
+	structSpecCache  = make(map[reflect.Type]*structSpec)
+	defaultFieldSpec = &fieldSpec{}
+)
+
+func structSpecForType(t reflect.Type) *structSpec {
+
+	structSpecMutex.RLock()
+	ss, found := structSpecCache[t]
+	structSpecMutex.RUnlock()
+	if found {
+		return ss
+	}
+
+	structSpecMutex.Lock()
+	defer structSpecMutex.Unlock()
+	ss, found = structSpecCache[t]
+	if found {
+		return ss
+	}
+
+	ss = &structSpec{m: make(map[string]*fieldSpec)}
+	compileStructSpec(t, make(map[string]int), nil, ss)
+	structSpecCache[t] = ss
+	return ss
+}
+
+var errScanStructValue = errors.New("redigo.ScanStruct: value must be non-nil pointer to a struct")
+
+// ScanStruct scans alternating names and values from src to a struct. The
+// HGETALL and CONFIG GET commands return replies in this format.
+//
+// ScanStruct uses exported field names to match values in the response. Use
+// 'redis' field tag to override the name:
+//
+//      Field int `redis:"myName"`
+//
+// Fields with the tag redis:"-" are ignored.
+//
+// Each field uses RedisScan if available otherwise:
+// Integer, float, boolean, string and []byte fields are supported. Scan uses the
+// standard strconv package to convert bulk string values to numeric and
+// boolean types.
+//
+// If a src element is nil, then the corresponding field is not modified.
+func ScanStruct(src []interface{}, dest interface{}) error {
+	d := reflect.ValueOf(dest)
+	if d.Kind() != reflect.Ptr || d.IsNil() {
+		return errScanStructValue
+	}
+	d = d.Elem()
+	if d.Kind() != reflect.Struct {
+		return errScanStructValue
+	}
+	ss := structSpecForType(d.Type())
+
+	if len(src)%2 != 0 {
+		return errors.New("redigo.ScanStruct: number of values not a multiple of 2")
+	}
+
+	for i := 0; i < len(src); i += 2 {
+		s := src[i+1]
+		if s == nil {
+			continue
+		}
+		name, ok := src[i].([]byte)
+		if !ok {
+			return fmt.Errorf("redigo.ScanStruct: key %d not a bulk string value", i)
+		}
+		fs := ss.fieldSpec(name)
+		if fs == nil {
+			continue
+		}
+		if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil {
+			return fmt.Errorf("redigo.ScanStruct: cannot assign field %s: %v", fs.name, err)
+		}
+	}
+	return nil
+}
+
+var (
+	errScanSliceValue = errors.New("redigo.ScanSlice: dest must be non-nil pointer to a struct")
+)
+
+// ScanSlice scans src to the slice pointed to by dest. The elements the dest
+// slice must be integer, float, boolean, string, struct or pointer to struct
+// values.
+//
+// Struct fields must be integer, float, boolean or string values. All struct
+// fields are used unless a subset is specified using fieldNames.
+func ScanSlice(src []interface{}, dest interface{}, fieldNames ...string) error {
+	d := reflect.ValueOf(dest)
+	if d.Kind() != reflect.Ptr || d.IsNil() {
+		return errScanSliceValue
+	}
+	d = d.Elem()
+	if d.Kind() != reflect.Slice {
+		return errScanSliceValue
+	}
+
+	isPtr := false
+	t := d.Type().Elem()
+	if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct {
+		isPtr = true
+		t = t.Elem()
+	}
+
+	if t.Kind() != reflect.Struct {
+		ensureLen(d, len(src))
+		for i, s := range src {
+			if s == nil {
+				continue
+			}
+			if err := convertAssignValue(d.Index(i), s); err != nil {
+				return fmt.Errorf("redigo.ScanSlice: cannot assign element %d: %v", i, err)
+			}
+		}
+		return nil
+	}
+
+	ss := structSpecForType(t)
+	fss := ss.l
+	if len(fieldNames) > 0 {
+		fss = make([]*fieldSpec, len(fieldNames))
+		for i, name := range fieldNames {
+			fss[i] = ss.m[name]
+			if fss[i] == nil {
+				return fmt.Errorf("redigo.ScanSlice: ScanSlice bad field name %s", name)
+			}
+		}
+	}
+
+	if len(fss) == 0 {
+		return errors.New("redigo.ScanSlice: no struct fields")
+	}
+
+	n := len(src) / len(fss)
+	if n*len(fss) != len(src) {
+		return errors.New("redigo.ScanSlice: length not a multiple of struct field count")
+	}
+
+	ensureLen(d, n)
+	for i := 0; i < n; i++ {
+		d := d.Index(i)
+		if isPtr {
+			if d.IsNil() {
+				d.Set(reflect.New(t))
+			}
+			d = d.Elem()
+		}
+		for j, fs := range fss {
+			s := src[i*len(fss)+j]
+			if s == nil {
+				continue
+			}
+			if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil {
+				return fmt.Errorf("redigo.ScanSlice: cannot assign element %d to field %s: %v", i*len(fss)+j, fs.name, err)
+			}
+		}
+	}
+	return nil
+}
+
+// Args is a helper for constructing command arguments from structured values.
+type Args []interface{}
+
+// Add returns the result of appending value to args.
+func (args Args) Add(value ...interface{}) Args {
+	return append(args, value...)
+}
+
+// AddFlat returns the result of appending the flattened value of v to args.
+//
+// Maps are flattened by appending the alternating keys and map values to args.
+//
+// Slices are flattened by appending the slice elements to args.
+//
+// Structs are flattened by appending the alternating names and values of
+// exported fields to args. If v is a nil struct pointer, then nothing is
+// appended. The 'redis' field tag overrides struct field names. See ScanStruct
+// for more information on the use of the 'redis' field tag.
+//
+// Other types are appended to args as is.
+func (args Args) AddFlat(v interface{}) Args {
+	rv := reflect.ValueOf(v)
+	switch rv.Kind() {
+	case reflect.Struct:
+		args = flattenStruct(args, rv)
+	case reflect.Slice:
+		for i := 0; i < rv.Len(); i++ {
+			args = append(args, rv.Index(i).Interface())
+		}
+	case reflect.Map:
+		for _, k := range rv.MapKeys() {
+			args = append(args, k.Interface(), rv.MapIndex(k).Interface())
+		}
+	case reflect.Ptr:
+		if rv.Type().Elem().Kind() == reflect.Struct {
+			if !rv.IsNil() {
+				args = flattenStruct(args, rv.Elem())
+			}
+		} else {
+			args = append(args, v)
+		}
+	default:
+		args = append(args, v)
+	}
+	return args
+}
+
+func flattenStruct(args Args, v reflect.Value) Args {
+	ss := structSpecForType(v.Type())
+	for _, fs := range ss.l {
+		fv := v.FieldByIndex(fs.index)
+		if fs.omitEmpty {
+			var empty = false
+			switch fv.Kind() {
+			case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+				empty = fv.Len() == 0
+			case reflect.Bool:
+				empty = !fv.Bool()
+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+				empty = fv.Int() == 0
+			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+				empty = fv.Uint() == 0
+			case reflect.Float32, reflect.Float64:
+				empty = fv.Float() == 0
+			case reflect.Interface, reflect.Ptr:
+				empty = fv.IsNil()
+			}
+			if empty {
+				continue
+			}
+		}
+		args = append(args, fs.name, fv.Interface())
+	}
+	return args
+}

+ 91 - 0
vendor/github.com/gomodule/redigo/redis/script.go

@@ -0,0 +1,91 @@
+// Copyright 2012 Gary Burd
+//
+// 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, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package redis
+
+import (
+	"crypto/sha1"
+	"encoding/hex"
+	"io"
+	"strings"
+)
+
+// Script encapsulates the source, hash and key count for a Lua script. See
+// http://redis.io/commands/eval for information on scripts in Redis.
+type Script struct {
+	keyCount int
+	src      string
+	hash     string
+}
+
+// NewScript returns a new script object. If keyCount is greater than or equal
+// to zero, then the count is automatically inserted in the EVAL command
+// argument list. If keyCount is less than zero, then the application supplies
+// the count as the first value in the keysAndArgs argument to the Do, Send and
+// SendHash methods.
+func NewScript(keyCount int, src string) *Script {
+	h := sha1.New()
+	io.WriteString(h, src)
+	return &Script{keyCount, src, hex.EncodeToString(h.Sum(nil))}
+}
+
+func (s *Script) args(spec string, keysAndArgs []interface{}) []interface{} {
+	var args []interface{}
+	if s.keyCount < 0 {
+		args = make([]interface{}, 1+len(keysAndArgs))
+		args[0] = spec
+		copy(args[1:], keysAndArgs)
+	} else {
+		args = make([]interface{}, 2+len(keysAndArgs))
+		args[0] = spec
+		args[1] = s.keyCount
+		copy(args[2:], keysAndArgs)
+	}
+	return args
+}
+
+// Hash returns the script hash.
+func (s *Script) Hash() string {
+	return s.hash
+}
+
+// Do evaluates the script. Under the covers, Do optimistically evaluates the
+// script using the EVALSHA command. If the command fails because the script is
+// not loaded, then Do evaluates the script using the EVAL command (thus
+// causing the script to load).
+func (s *Script) Do(c Conn, keysAndArgs ...interface{}) (interface{}, error) {
+	v, err := c.Do("EVALSHA", s.args(s.hash, keysAndArgs)...)
+	if e, ok := err.(Error); ok && strings.HasPrefix(string(e), "NOSCRIPT ") {
+		v, err = c.Do("EVAL", s.args(s.src, keysAndArgs)...)
+	}
+	return v, err
+}
+
+// SendHash evaluates the script without waiting for the reply. The script is
+// evaluated with the EVALSHA command. The application must ensure that the
+// script is loaded by a previous call to Send, Do or Load methods.
+func (s *Script) SendHash(c Conn, keysAndArgs ...interface{}) error {
+	return c.Send("EVALSHA", s.args(s.hash, keysAndArgs)...)
+}
+
+// Send evaluates the script without waiting for the reply.
+func (s *Script) Send(c Conn, keysAndArgs ...interface{}) error {
+	return c.Send("EVAL", s.args(s.src, keysAndArgs)...)
+}
+
+// Load loads the script without evaluating it.
+func (s *Script) Load(c Conn) error {
+	_, err := c.Do("SCRIPT", "LOAD", s.src)
+	return err
+}

+ 4 - 0
vendor/github.com/mattn/go-sqlite3/.codecov.yml

@@ -0,0 +1,4 @@
+coverage:
+  status:
+    project: off
+    patch: off

+ 14 - 0
vendor/github.com/mattn/go-sqlite3/.gitignore

@@ -0,0 +1,14 @@
+*.db
+*.exe
+*.dll
+*.o
+
+# VSCode
+.vscode
+
+# Exclude from upgrade
+upgrade/*.c
+upgrade/*.h
+
+# Exclude upgrade binary
+upgrade/upgrade

+ 21 - 0
vendor/github.com/mattn/go-sqlite3/LICENSE

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Yasuhiro Matsumoto
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

File diff suppressed because it is too large
+ 592 - 0
vendor/github.com/mattn/go-sqlite3/README.md


+ 85 - 0
vendor/github.com/mattn/go-sqlite3/backup.go

@@ -0,0 +1,85 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package sqlite3
+
+/*
+#ifndef USE_LIBSQLITE3
+#include <sqlite3-binding.h>
+#else
+#include <sqlite3.h>
+#endif
+#include <stdlib.h>
+*/
+import "C"
+import (
+	"runtime"
+	"unsafe"
+)
+
+// SQLiteBackup implement interface of Backup.
+type SQLiteBackup struct {
+	b *C.sqlite3_backup
+}
+
+// Backup make backup from src to dest.
+func (destConn *SQLiteConn) Backup(dest string, srcConn *SQLiteConn, src string) (*SQLiteBackup, error) {
+	destptr := C.CString(dest)
+	defer C.free(unsafe.Pointer(destptr))
+	srcptr := C.CString(src)
+	defer C.free(unsafe.Pointer(srcptr))
+
+	if b := C.sqlite3_backup_init(destConn.db, destptr, srcConn.db, srcptr); b != nil {
+		bb := &SQLiteBackup{b: b}
+		runtime.SetFinalizer(bb, (*SQLiteBackup).Finish)
+		return bb, nil
+	}
+	return nil, destConn.lastError()
+}
+
+// Step to backs up for one step. Calls the underlying `sqlite3_backup_step`
+// function.  This function returns a boolean indicating if the backup is done
+// and an error signalling any other error. Done is returned if the underlying
+// C function returns SQLITE_DONE (Code 101)
+func (b *SQLiteBackup) Step(p int) (bool, error) {
+	ret := C.sqlite3_backup_step(b.b, C.int(p))
+	if ret == C.SQLITE_DONE {
+		return true, nil
+	} else if ret != 0 && ret != C.SQLITE_LOCKED && ret != C.SQLITE_BUSY {
+		return false, Error{Code: ErrNo(ret)}
+	}
+	return false, nil
+}
+
+// Remaining return whether have the rest for backup.
+func (b *SQLiteBackup) Remaining() int {
+	return int(C.sqlite3_backup_remaining(b.b))
+}
+
+// PageCount return count of pages.
+func (b *SQLiteBackup) PageCount() int {
+	return int(C.sqlite3_backup_pagecount(b.b))
+}
+
+// Finish close backup.
+func (b *SQLiteBackup) Finish() error {
+	return b.Close()
+}
+
+// Close close backup.
+func (b *SQLiteBackup) Close() error {
+	ret := C.sqlite3_backup_finish(b.b)
+
+	// sqlite3_backup_finish() never fails, it just returns the
+	// error code from previous operations, so clean up before
+	// checking and returning an error
+	b.b = nil
+	runtime.SetFinalizer(b, nil)
+
+	if ret != 0 {
+		return Error{Code: ErrNo(ret)}
+	}
+	return nil
+}

+ 392 - 0
vendor/github.com/mattn/go-sqlite3/callback.go

@@ -0,0 +1,392 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package sqlite3
+
+// You can't export a Go function to C and have definitions in the C
+// preamble in the same file, so we have to have callbackTrampoline in
+// its own file. Because we need a separate file anyway, the support
+// code for SQLite custom functions is in here.
+
+/*
+#ifndef USE_LIBSQLITE3
+#include <sqlite3-binding.h>
+#else
+#include <sqlite3.h>
+#endif
+#include <stdlib.h>
+
+void _sqlite3_result_text(sqlite3_context* ctx, const char* s);
+void _sqlite3_result_blob(sqlite3_context* ctx, const void* b, int l);
+*/
+import "C"
+
+import (
+	"errors"
+	"fmt"
+	"math"
+	"reflect"
+	"sync"
+	"unsafe"
+)
+
+//export callbackTrampoline
+func callbackTrampoline(ctx *C.sqlite3_context, argc int, argv **C.sqlite3_value) {
+	args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc]
+	fi := lookupHandle(C.sqlite3_user_data(ctx)).(*functionInfo)
+	fi.Call(ctx, args)
+}
+
+//export stepTrampoline
+func stepTrampoline(ctx *C.sqlite3_context, argc C.int, argv **C.sqlite3_value) {
+	args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:int(argc):int(argc)]
+	ai := lookupHandle(C.sqlite3_user_data(ctx)).(*aggInfo)
+	ai.Step(ctx, args)
+}
+
+//export doneTrampoline
+func doneTrampoline(ctx *C.sqlite3_context) {
+	ai := lookupHandle(C.sqlite3_user_data(ctx)).(*aggInfo)
+	ai.Done(ctx)
+}
+
+//export compareTrampoline
+func compareTrampoline(handlePtr unsafe.Pointer, la C.int, a *C.char, lb C.int, b *C.char) C.int {
+	cmp := lookupHandle(handlePtr).(func(string, string) int)
+	return C.int(cmp(C.GoStringN(a, la), C.GoStringN(b, lb)))
+}
+
+//export commitHookTrampoline
+func commitHookTrampoline(handle unsafe.Pointer) int {
+	callback := lookupHandle(handle).(func() int)
+	return callback()
+}
+
+//export rollbackHookTrampoline
+func rollbackHookTrampoline(handle unsafe.Pointer) {
+	callback := lookupHandle(handle).(func())
+	callback()
+}
+
+//export updateHookTrampoline
+func updateHookTrampoline(handle unsafe.Pointer, op int, db *C.char, table *C.char, rowid int64) {
+	callback := lookupHandle(handle).(func(int, string, string, int64))
+	callback(op, C.GoString(db), C.GoString(table), rowid)
+}
+
+//export authorizerTrampoline
+func authorizerTrampoline(handle unsafe.Pointer, op int, arg1 *C.char, arg2 *C.char, arg3 *C.char) int {
+	callback := lookupHandle(handle).(func(int, string, string, string) int)
+	return callback(op, C.GoString(arg1), C.GoString(arg2), C.GoString(arg3))
+}
+
+//export preUpdateHookTrampoline
+func preUpdateHookTrampoline(handle unsafe.Pointer, dbHandle uintptr, op int, db *C.char, table *C.char, oldrowid int64, newrowid int64) {
+	hval := lookupHandleVal(handle)
+	data := SQLitePreUpdateData{
+		Conn:         hval.db,
+		Op:           op,
+		DatabaseName: C.GoString(db),
+		TableName:    C.GoString(table),
+		OldRowID:     oldrowid,
+		NewRowID:     newrowid,
+	}
+	callback := hval.val.(func(SQLitePreUpdateData))
+	callback(data)
+}
+
+// Use handles to avoid passing Go pointers to C.
+type handleVal struct {
+	db  *SQLiteConn
+	val interface{}
+}
+
+var handleLock sync.Mutex
+var handleVals = make(map[unsafe.Pointer]handleVal)
+
+func newHandle(db *SQLiteConn, v interface{}) unsafe.Pointer {
+	handleLock.Lock()
+	defer handleLock.Unlock()
+	val := handleVal{db: db, val: v}
+	var p unsafe.Pointer = C.malloc(C.size_t(1))
+	if p == nil {
+		panic("can't allocate 'cgo-pointer hack index pointer': ptr == nil")
+	}
+	handleVals[p] = val
+	return p
+}
+
+func lookupHandleVal(handle unsafe.Pointer) handleVal {
+	handleLock.Lock()
+	defer handleLock.Unlock()
+	return handleVals[handle]
+}
+
+func lookupHandle(handle unsafe.Pointer) interface{} {
+	return lookupHandleVal(handle).val
+}
+
+func deleteHandles(db *SQLiteConn) {
+	handleLock.Lock()
+	defer handleLock.Unlock()
+	for handle, val := range handleVals {
+		if val.db == db {
+			delete(handleVals, handle)
+			C.free(handle)
+		}
+	}
+}
+
+// This is only here so that tests can refer to it.
+type callbackArgRaw C.sqlite3_value
+
+type callbackArgConverter func(*C.sqlite3_value) (reflect.Value, error)
+
+type callbackArgCast struct {
+	f   callbackArgConverter
+	typ reflect.Type
+}
+
+func (c callbackArgCast) Run(v *C.sqlite3_value) (reflect.Value, error) {
+	val, err := c.f(v)
+	if err != nil {
+		return reflect.Value{}, err
+	}
+	if !val.Type().ConvertibleTo(c.typ) {
+		return reflect.Value{}, fmt.Errorf("cannot convert %s to %s", val.Type(), c.typ)
+	}
+	return val.Convert(c.typ), nil
+}
+
+func callbackArgInt64(v *C.sqlite3_value) (reflect.Value, error) {
+	if C.sqlite3_value_type(v) != C.SQLITE_INTEGER {
+		return reflect.Value{}, fmt.Errorf("argument must be an INTEGER")
+	}
+	return reflect.ValueOf(int64(C.sqlite3_value_int64(v))), nil
+}
+
+func callbackArgBool(v *C.sqlite3_value) (reflect.Value, error) {
+	if C.sqlite3_value_type(v) != C.SQLITE_INTEGER {
+		return reflect.Value{}, fmt.Errorf("argument must be an INTEGER")
+	}
+	i := int64(C.sqlite3_value_int64(v))
+	val := false
+	if i != 0 {
+		val = true
+	}
+	return reflect.ValueOf(val), nil
+}
+
+func callbackArgFloat64(v *C.sqlite3_value) (reflect.Value, error) {
+	if C.sqlite3_value_type(v) != C.SQLITE_FLOAT {
+		return reflect.Value{}, fmt.Errorf("argument must be a FLOAT")
+	}
+	return reflect.ValueOf(float64(C.sqlite3_value_double(v))), nil
+}
+
+func callbackArgBytes(v *C.sqlite3_value) (reflect.Value, error) {
+	switch C.sqlite3_value_type(v) {
+	case C.SQLITE_BLOB:
+		l := C.sqlite3_value_bytes(v)
+		p := C.sqlite3_value_blob(v)
+		return reflect.ValueOf(C.GoBytes(p, l)), nil
+	case C.SQLITE_TEXT:
+		l := C.sqlite3_value_bytes(v)
+		c := unsafe.Pointer(C.sqlite3_value_text(v))
+		return reflect.ValueOf(C.GoBytes(c, l)), nil
+	default:
+		return reflect.Value{}, fmt.Errorf("argument must be BLOB or TEXT")
+	}
+}
+
+func callbackArgString(v *C.sqlite3_value) (reflect.Value, error) {
+	switch C.sqlite3_value_type(v) {
+	case C.SQLITE_BLOB:
+		l := C.sqlite3_value_bytes(v)
+		p := (*C.char)(C.sqlite3_value_blob(v))
+		return reflect.ValueOf(C.GoStringN(p, l)), nil
+	case C.SQLITE_TEXT:
+		c := (*C.char)(unsafe.Pointer(C.sqlite3_value_text(v)))
+		return reflect.ValueOf(C.GoString(c)), nil
+	default:
+		return reflect.Value{}, fmt.Errorf("argument must be BLOB or TEXT")
+	}
+}
+
+func callbackArgGeneric(v *C.sqlite3_value) (reflect.Value, error) {
+	switch C.sqlite3_value_type(v) {
+	case C.SQLITE_INTEGER:
+		return callbackArgInt64(v)
+	case C.SQLITE_FLOAT:
+		return callbackArgFloat64(v)
+	case C.SQLITE_TEXT:
+		return callbackArgString(v)
+	case C.SQLITE_BLOB:
+		return callbackArgBytes(v)
+	case C.SQLITE_NULL:
+		// Interpret NULL as a nil byte slice.
+		var ret []byte
+		return reflect.ValueOf(ret), nil
+	default:
+		panic("unreachable")
+	}
+}
+
+func callbackArg(typ reflect.Type) (callbackArgConverter, error) {
+	switch typ.Kind() {
+	case reflect.Interface:
+		if typ.NumMethod() != 0 {
+			return nil, errors.New("the only supported interface type is interface{}")
+		}
+		return callbackArgGeneric, nil
+	case reflect.Slice:
+		if typ.Elem().Kind() != reflect.Uint8 {
+			return nil, errors.New("the only supported slice type is []byte")
+		}
+		return callbackArgBytes, nil
+	case reflect.String:
+		return callbackArgString, nil
+	case reflect.Bool:
+		return callbackArgBool, nil
+	case reflect.Int64:
+		return callbackArgInt64, nil
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Uint:
+		c := callbackArgCast{callbackArgInt64, typ}
+		return c.Run, nil
+	case reflect.Float64:
+		return callbackArgFloat64, nil
+	case reflect.Float32:
+		c := callbackArgCast{callbackArgFloat64, typ}
+		return c.Run, nil
+	default:
+		return nil, fmt.Errorf("don't know how to convert to %s", typ)
+	}
+}
+
+func callbackConvertArgs(argv []*C.sqlite3_value, converters []callbackArgConverter, variadic callbackArgConverter) ([]reflect.Value, error) {
+	var args []reflect.Value
+
+	if len(argv) < len(converters) {
+		return nil, fmt.Errorf("function requires at least %d arguments", len(converters))
+	}
+
+	for i, arg := range argv[:len(converters)] {
+		v, err := converters[i](arg)
+		if err != nil {
+			return nil, err
+		}
+		args = append(args, v)
+	}
+
+	if variadic != nil {
+		for _, arg := range argv[len(converters):] {
+			v, err := variadic(arg)
+			if err != nil {
+				return nil, err
+			}
+			args = append(args, v)
+		}
+	}
+	return args, nil
+}
+
+type callbackRetConverter func(*C.sqlite3_context, reflect.Value) error
+
+func callbackRetInteger(ctx *C.sqlite3_context, v reflect.Value) error {
+	switch v.Type().Kind() {
+	case reflect.Int64:
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Uint:
+		v = v.Convert(reflect.TypeOf(int64(0)))
+	case reflect.Bool:
+		b := v.Interface().(bool)
+		if b {
+			v = reflect.ValueOf(int64(1))
+		} else {
+			v = reflect.ValueOf(int64(0))
+		}
+	default:
+		return fmt.Errorf("cannot convert %s to INTEGER", v.Type())
+	}
+
+	C.sqlite3_result_int64(ctx, C.sqlite3_int64(v.Interface().(int64)))
+	return nil
+}
+
+func callbackRetFloat(ctx *C.sqlite3_context, v reflect.Value) error {
+	switch v.Type().Kind() {
+	case reflect.Float64:
+	case reflect.Float32:
+		v = v.Convert(reflect.TypeOf(float64(0)))
+	default:
+		return fmt.Errorf("cannot convert %s to FLOAT", v.Type())
+	}
+
+	C.sqlite3_result_double(ctx, C.double(v.Interface().(float64)))
+	return nil
+}
+
+func callbackRetBlob(ctx *C.sqlite3_context, v reflect.Value) error {
+	if v.Type().Kind() != reflect.Slice || v.Type().Elem().Kind() != reflect.Uint8 {
+		return fmt.Errorf("cannot convert %s to BLOB", v.Type())
+	}
+	i := v.Interface()
+	if i == nil || len(i.([]byte)) == 0 {
+		C.sqlite3_result_null(ctx)
+	} else {
+		bs := i.([]byte)
+		C._sqlite3_result_blob(ctx, unsafe.Pointer(&bs[0]), C.int(len(bs)))
+	}
+	return nil
+}
+
+func callbackRetText(ctx *C.sqlite3_context, v reflect.Value) error {
+	if v.Type().Kind() != reflect.String {
+		return fmt.Errorf("cannot convert %s to TEXT", v.Type())
+	}
+	C._sqlite3_result_text(ctx, C.CString(v.Interface().(string)))
+	return nil
+}
+
+func callbackRetNil(ctx *C.sqlite3_context, v reflect.Value) error {
+	return nil
+}
+
+func callbackRet(typ reflect.Type) (callbackRetConverter, error) {
+	switch typ.Kind() {
+	case reflect.Interface:
+		errorInterface := reflect.TypeOf((*error)(nil)).Elem()
+		if typ.Implements(errorInterface) {
+			return callbackRetNil, nil
+		}
+		fallthrough
+	case reflect.Slice:
+		if typ.Elem().Kind() != reflect.Uint8 {
+			return nil, errors.New("the only supported slice type is []byte")
+		}
+		return callbackRetBlob, nil
+	case reflect.String:
+		return callbackRetText, nil
+	case reflect.Bool, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Int, reflect.Uint:
+		return callbackRetInteger, nil
+	case reflect.Float32, reflect.Float64:
+		return callbackRetFloat, nil
+	default:
+		return nil, fmt.Errorf("don't know how to convert to %s", typ)
+	}
+}
+
+func callbackError(ctx *C.sqlite3_context, err error) {
+	cstr := C.CString(err.Error())
+	defer C.free(unsafe.Pointer(cstr))
+	C.sqlite3_result_error(ctx, cstr, C.int(-1))
+}
+
+// Test support code. Tests are not allowed to import "C", so we can't
+// declare any functions that use C.sqlite3_value.
+func callbackSyntheticForTests(v reflect.Value, err error) callbackArgConverter {
+	return func(*C.sqlite3_value) (reflect.Value, error) {
+		return v, err
+	}
+}

+ 299 - 0
vendor/github.com/mattn/go-sqlite3/convert.go

@@ -0,0 +1,299 @@
+// Extracted from Go database/sql source code
+
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Type conversions for Scan.
+
+package sqlite3
+
+import (
+	"database/sql"
+	"database/sql/driver"
+	"errors"
+	"fmt"
+	"reflect"
+	"strconv"
+	"time"
+)
+
+var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
+
+// convertAssign copies to dest the value in src, converting it if possible.
+// An error is returned if the copy would result in loss of information.
+// dest should be a pointer type.
+func convertAssign(dest, src interface{}) error {
+	// Common cases, without reflect.
+	switch s := src.(type) {
+	case string:
+		switch d := dest.(type) {
+		case *string:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = s
+			return nil
+		case *[]byte:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = []byte(s)
+			return nil
+		case *sql.RawBytes:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = append((*d)[:0], s...)
+			return nil
+		}
+	case []byte:
+		switch d := dest.(type) {
+		case *string:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = string(s)
+			return nil
+		case *interface{}:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = cloneBytes(s)
+			return nil
+		case *[]byte:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = cloneBytes(s)
+			return nil
+		case *sql.RawBytes:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = s
+			return nil
+		}
+	case time.Time:
+		switch d := dest.(type) {
+		case *time.Time:
+			*d = s
+			return nil
+		case *string:
+			*d = s.Format(time.RFC3339Nano)
+			return nil
+		case *[]byte:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = []byte(s.Format(time.RFC3339Nano))
+			return nil
+		case *sql.RawBytes:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = s.AppendFormat((*d)[:0], time.RFC3339Nano)
+			return nil
+		}
+	case nil:
+		switch d := dest.(type) {
+		case *interface{}:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = nil
+			return nil
+		case *[]byte:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = nil
+			return nil
+		case *sql.RawBytes:
+			if d == nil {
+				return errNilPtr
+			}
+			*d = nil
+			return nil
+		}
+	}
+
+	var sv reflect.Value
+
+	switch d := dest.(type) {
+	case *string:
+		sv = reflect.ValueOf(src)
+		switch sv.Kind() {
+		case reflect.Bool,
+			reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+			reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+			reflect.Float32, reflect.Float64:
+			*d = asString(src)
+			return nil
+		}
+	case *[]byte:
+		sv = reflect.ValueOf(src)
+		if b, ok := asBytes(nil, sv); ok {
+			*d = b
+			return nil
+		}
+	case *sql.RawBytes:
+		sv = reflect.ValueOf(src)
+		if b, ok := asBytes([]byte(*d)[:0], sv); ok {
+			*d = sql.RawBytes(b)
+			return nil
+		}
+	case *bool:
+		bv, err := driver.Bool.ConvertValue(src)
+		if err == nil {
+			*d = bv.(bool)
+		}
+		return err
+	case *interface{}:
+		*d = src
+		return nil
+	}
+
+	if scanner, ok := dest.(sql.Scanner); ok {
+		return scanner.Scan(src)
+	}
+
+	dpv := reflect.ValueOf(dest)
+	if dpv.Kind() != reflect.Ptr {
+		return errors.New("destination not a pointer")
+	}
+	if dpv.IsNil() {
+		return errNilPtr
+	}
+
+	if !sv.IsValid() {
+		sv = reflect.ValueOf(src)
+	}
+
+	dv := reflect.Indirect(dpv)
+	if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) {
+		switch b := src.(type) {
+		case []byte:
+			dv.Set(reflect.ValueOf(cloneBytes(b)))
+		default:
+			dv.Set(sv)
+		}
+		return nil
+	}
+
+	if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) {
+		dv.Set(sv.Convert(dv.Type()))
+		return nil
+	}
+
+	// The following conversions use a string value as an intermediate representation
+	// to convert between various numeric types.
+	//
+	// This also allows scanning into user defined types such as "type Int int64".
+	// For symmetry, also check for string destination types.
+	switch dv.Kind() {
+	case reflect.Ptr:
+		if src == nil {
+			dv.Set(reflect.Zero(dv.Type()))
+			return nil
+		}
+		dv.Set(reflect.New(dv.Type().Elem()))
+		return convertAssign(dv.Interface(), src)
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		s := asString(src)
+		i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
+		if err != nil {
+			err = strconvErr(err)
+			return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
+		}
+		dv.SetInt(i64)
+		return nil
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		s := asString(src)
+		u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
+		if err != nil {
+			err = strconvErr(err)
+			return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
+		}
+		dv.SetUint(u64)
+		return nil
+	case reflect.Float32, reflect.Float64:
+		s := asString(src)
+		f64, err := strconv.ParseFloat(s, dv.Type().Bits())
+		if err != nil {
+			err = strconvErr(err)
+			return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
+		}
+		dv.SetFloat(f64)
+		return nil
+	case reflect.String:
+		switch v := src.(type) {
+		case string:
+			dv.SetString(v)
+			return nil
+		case []byte:
+			dv.SetString(string(v))
+			return nil
+		}
+	}
+
+	return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest)
+}
+
+func strconvErr(err error) error {
+	if ne, ok := err.(*strconv.NumError); ok {
+		return ne.Err
+	}
+	return err
+}
+
+func cloneBytes(b []byte) []byte {
+	if b == nil {
+		return nil
+	}
+	c := make([]byte, len(b))
+	copy(c, b)
+	return c
+}
+
+func asString(src interface{}) string {
+	switch v := src.(type) {
+	case string:
+		return v
+	case []byte:
+		return string(v)
+	}
+	rv := reflect.ValueOf(src)
+	switch rv.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return strconv.FormatInt(rv.Int(), 10)
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		return strconv.FormatUint(rv.Uint(), 10)
+	case reflect.Float64:
+		return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
+	case reflect.Float32:
+		return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
+	case reflect.Bool:
+		return strconv.FormatBool(rv.Bool())
+	}
+	return fmt.Sprintf("%v", src)
+}
+
+func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) {
+	switch rv.Kind() {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return strconv.AppendInt(buf, rv.Int(), 10), true
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		return strconv.AppendUint(buf, rv.Uint(), 10), true
+	case reflect.Float32:
+		return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true
+	case reflect.Float64:
+		return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true
+	case reflect.Bool:
+		return strconv.AppendBool(buf, rv.Bool()), true
+	case reflect.String:
+		s := rv.String()
+		return append(buf, s...), true
+	}
+	return
+}

+ 135 - 0
vendor/github.com/mattn/go-sqlite3/doc.go

@@ -0,0 +1,135 @@
+/*
+Package sqlite3 provides interface to SQLite3 databases.
+
+This works as a driver for database/sql.
+
+Installation
+
+    go get github.com/mattn/go-sqlite3
+
+Supported Types
+
+Currently, go-sqlite3 supports the following data types.
+
+    +------------------------------+
+    |go        | sqlite3           |
+    |----------|-------------------|
+    |nil       | null              |
+    |int       | integer           |
+    |int64     | integer           |
+    |float64   | float             |
+    |bool      | integer           |
+    |[]byte    | blob              |
+    |string    | text              |
+    |time.Time | timestamp/datetime|
+    +------------------------------+
+
+SQLite3 Extension
+
+You can write your own extension module for sqlite3. For example, below is an
+extension for a Regexp matcher operation.
+
+    #include <pcre.h>
+    #include <string.h>
+    #include <stdio.h>
+    #include <sqlite3ext.h>
+
+    SQLITE_EXTENSION_INIT1
+    static void regexp_func(sqlite3_context *context, int argc, sqlite3_value **argv) {
+      if (argc >= 2) {
+        const char *target  = (const char *)sqlite3_value_text(argv[1]);
+        const char *pattern = (const char *)sqlite3_value_text(argv[0]);
+        const char* errstr = NULL;
+        int erroff = 0;
+        int vec[500];
+        int n, rc;
+        pcre* re = pcre_compile(pattern, 0, &errstr, &erroff, NULL);
+        rc = pcre_exec(re, NULL, target, strlen(target), 0, 0, vec, 500);
+        if (rc <= 0) {
+          sqlite3_result_error(context, errstr, 0);
+          return;
+        }
+        sqlite3_result_int(context, 1);
+      }
+    }
+
+    #ifdef _WIN32
+    __declspec(dllexport)
+    #endif
+    int sqlite3_extension_init(sqlite3 *db, char **errmsg,
+          const sqlite3_api_routines *api) {
+      SQLITE_EXTENSION_INIT2(api);
+      return sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8,
+          (void*)db, regexp_func, NULL, NULL);
+    }
+
+It needs to be built as a so/dll shared library. And you need to register
+the extension module like below.
+
+	sql.Register("sqlite3_with_extensions",
+		&sqlite3.SQLiteDriver{
+			Extensions: []string{
+				"sqlite3_mod_regexp",
+			},
+		})
+
+Then, you can use this extension.
+
+	rows, err := db.Query("select text from mytable where name regexp '^golang'")
+
+Connection Hook
+
+You can hook and inject your code when the connection is established by setting
+ConnectHook to get the SQLiteConn.
+
+	sql.Register("sqlite3_with_hook_example",
+			&sqlite3.SQLiteDriver{
+					ConnectHook: func(conn *sqlite3.SQLiteConn) error {
+						sqlite3conn = append(sqlite3conn, conn)
+						return nil
+					},
+			})
+
+You can also use database/sql.Conn.Raw (Go >= 1.13):
+
+	conn, err := db.Conn(context.Background())
+	// if err != nil { ... }
+	defer conn.Close()
+	err = conn.Raw(func (driverConn interface{}) error {
+		sqliteConn := driverConn.(*sqlite3.SQLiteConn)
+		// ... use sqliteConn
+	})
+	// if err != nil { ... }
+
+Go SQlite3 Extensions
+
+If you want to register Go functions as SQLite extension functions
+you can make a custom driver by calling RegisterFunction from
+ConnectHook.
+
+	regex = func(re, s string) (bool, error) {
+		return regexp.MatchString(re, s)
+	}
+	sql.Register("sqlite3_extended",
+			&sqlite3.SQLiteDriver{
+					ConnectHook: func(conn *sqlite3.SQLiteConn) error {
+						return conn.RegisterFunc("regexp", regex, true)
+					},
+			})
+
+You can then use the custom driver by passing its name to sql.Open.
+
+	var i int
+	conn, err := sql.Open("sqlite3_extended", "./foo.db")
+	if err != nil {
+		panic(err)
+	}
+	err = db.QueryRow(`SELECT regexp("foo.*", "seafood")`).Scan(&i)
+	if err != nil {
+		panic(err)
+	}
+
+See the documentation of RegisterFunc for more details.
+
+*/
+package sqlite3

+ 150 - 0
vendor/github.com/mattn/go-sqlite3/error.go

@@ -0,0 +1,150 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package sqlite3
+
+/*
+#ifndef USE_LIBSQLITE3
+#include <sqlite3-binding.h>
+#else
+#include <sqlite3.h>
+#endif
+*/
+import "C"
+import "syscall"
+
+// ErrNo inherit errno.
+type ErrNo int
+
+// ErrNoMask is mask code.
+const ErrNoMask C.int = 0xff
+
+// ErrNoExtended is extended errno.
+type ErrNoExtended int
+
+// Error implement sqlite error code.
+type Error struct {
+	Code         ErrNo         /* The error code returned by SQLite */
+	ExtendedCode ErrNoExtended /* The extended error code returned by SQLite */
+	SystemErrno  syscall.Errno /* The system errno returned by the OS through SQLite, if applicable */
+	err          string        /* The error string returned by sqlite3_errmsg(),
+	this usually contains more specific details. */
+}
+
+// result codes from http://www.sqlite.org/c3ref/c_abort.html
+var (
+	ErrError      = ErrNo(1)  /* SQL error or missing database */
+	ErrInternal   = ErrNo(2)  /* Internal logic error in SQLite */
+	ErrPerm       = ErrNo(3)  /* Access permission denied */
+	ErrAbort      = ErrNo(4)  /* Callback routine requested an abort */
+	ErrBusy       = ErrNo(5)  /* The database file is locked */
+	ErrLocked     = ErrNo(6)  /* A table in the database is locked */
+	ErrNomem      = ErrNo(7)  /* A malloc() failed */
+	ErrReadonly   = ErrNo(8)  /* Attempt to write a readonly database */
+	ErrInterrupt  = ErrNo(9)  /* Operation terminated by sqlite3_interrupt() */
+	ErrIoErr      = ErrNo(10) /* Some kind of disk I/O error occurred */
+	ErrCorrupt    = ErrNo(11) /* The database disk image is malformed */
+	ErrNotFound   = ErrNo(12) /* Unknown opcode in sqlite3_file_control() */
+	ErrFull       = ErrNo(13) /* Insertion failed because database is full */
+	ErrCantOpen   = ErrNo(14) /* Unable to open the database file */
+	ErrProtocol   = ErrNo(15) /* Database lock protocol error */
+	ErrEmpty      = ErrNo(16) /* Database is empty */
+	ErrSchema     = ErrNo(17) /* The database schema changed */
+	ErrTooBig     = ErrNo(18) /* String or BLOB exceeds size limit */
+	ErrConstraint = ErrNo(19) /* Abort due to constraint violation */
+	ErrMismatch   = ErrNo(20) /* Data type mismatch */
+	ErrMisuse     = ErrNo(21) /* Library used incorrectly */
+	ErrNoLFS      = ErrNo(22) /* Uses OS features not supported on host */
+	ErrAuth       = ErrNo(23) /* Authorization denied */
+	ErrFormat     = ErrNo(24) /* Auxiliary database format error */
+	ErrRange      = ErrNo(25) /* 2nd parameter to sqlite3_bind out of range */
+	ErrNotADB     = ErrNo(26) /* File opened that is not a database file */
+	ErrNotice     = ErrNo(27) /* Notifications from sqlite3_log() */
+	ErrWarning    = ErrNo(28) /* Warnings from sqlite3_log() */
+)
+
+// Error return error message from errno.
+func (err ErrNo) Error() string {
+	return Error{Code: err}.Error()
+}
+
+// Extend return extended errno.
+func (err ErrNo) Extend(by int) ErrNoExtended {
+	return ErrNoExtended(int(err) | (by << 8))
+}
+
+// Error return error message that is extended code.
+func (err ErrNoExtended) Error() string {
+	return Error{Code: ErrNo(C.int(err) & ErrNoMask), ExtendedCode: err}.Error()
+}
+
+func (err Error) Error() string {
+	var str string
+	if err.err != "" {
+		str = err.err
+	} else {
+		str = C.GoString(C.sqlite3_errstr(C.int(err.Code)))
+	}
+	if err.SystemErrno != 0 {
+		str += ": " + err.SystemErrno.Error()
+	}
+	return str
+}
+
+// result codes from http://www.sqlite.org/c3ref/c_abort_rollback.html
+var (
+	ErrIoErrRead              = ErrIoErr.Extend(1)
+	ErrIoErrShortRead         = ErrIoErr.Extend(2)
+	ErrIoErrWrite             = ErrIoErr.Extend(3)
+	ErrIoErrFsync             = ErrIoErr.Extend(4)
+	ErrIoErrDirFsync          = ErrIoErr.Extend(5)
+	ErrIoErrTruncate          = ErrIoErr.Extend(6)
+	ErrIoErrFstat             = ErrIoErr.Extend(7)
+	ErrIoErrUnlock            = ErrIoErr.Extend(8)
+	ErrIoErrRDlock            = ErrIoErr.Extend(9)
+	ErrIoErrDelete            = ErrIoErr.Extend(10)
+	ErrIoErrBlocked           = ErrIoErr.Extend(11)
+	ErrIoErrNoMem             = ErrIoErr.Extend(12)
+	ErrIoErrAccess            = ErrIoErr.Extend(13)
+	ErrIoErrCheckReservedLock = ErrIoErr.Extend(14)
+	ErrIoErrLock              = ErrIoErr.Extend(15)
+	ErrIoErrClose             = ErrIoErr.Extend(16)
+	ErrIoErrDirClose          = ErrIoErr.Extend(17)
+	ErrIoErrSHMOpen           = ErrIoErr.Extend(18)
+	ErrIoErrSHMSize           = ErrIoErr.Extend(19)
+	ErrIoErrSHMLock           = ErrIoErr.Extend(20)
+	ErrIoErrSHMMap            = ErrIoErr.Extend(21)
+	ErrIoErrSeek              = ErrIoErr.Extend(22)
+	ErrIoErrDeleteNoent       = ErrIoErr.Extend(23)
+	ErrIoErrMMap              = ErrIoErr.Extend(24)
+	ErrIoErrGetTempPath       = ErrIoErr.Extend(25)
+	ErrIoErrConvPath          = ErrIoErr.Extend(26)
+	ErrLockedSharedCache      = ErrLocked.Extend(1)
+	ErrBusyRecovery           = ErrBusy.Extend(1)
+	ErrBusySnapshot           = ErrBusy.Extend(2)
+	ErrCantOpenNoTempDir      = ErrCantOpen.Extend(1)
+	ErrCantOpenIsDir          = ErrCantOpen.Extend(2)
+	ErrCantOpenFullPath       = ErrCantOpen.Extend(3)
+	ErrCantOpenConvPath       = ErrCantOpen.Extend(4)
+	ErrCorruptVTab            = ErrCorrupt.Extend(1)
+	ErrReadonlyRecovery       = ErrReadonly.Extend(1)
+	ErrReadonlyCantLock       = ErrReadonly.Extend(2)
+	ErrReadonlyRollback       = ErrReadonly.Extend(3)
+	ErrReadonlyDbMoved        = ErrReadonly.Extend(4)
+	ErrAbortRollback          = ErrAbort.Extend(2)
+	ErrConstraintCheck        = ErrConstraint.Extend(1)
+	ErrConstraintCommitHook   = ErrConstraint.Extend(2)
+	ErrConstraintForeignKey   = ErrConstraint.Extend(3)
+	ErrConstraintFunction     = ErrConstraint.Extend(4)
+	ErrConstraintNotNull      = ErrConstraint.Extend(5)
+	ErrConstraintPrimaryKey   = ErrConstraint.Extend(6)
+	ErrConstraintTrigger      = ErrConstraint.Extend(7)
+	ErrConstraintUnique       = ErrConstraint.Extend(8)
+	ErrConstraintVTab         = ErrConstraint.Extend(9)
+	ErrConstraintRowID        = ErrConstraint.Extend(10)
+	ErrNoticeRecoverWAL       = ErrNotice.Extend(1)
+	ErrNoticeRecoverRollback  = ErrNotice.Extend(2)
+	ErrWarningAutoIndex       = ErrWarning.Extend(1)
+)

+ 3 - 0
vendor/github.com/mattn/go-sqlite3/go.mod

@@ -0,0 +1,3 @@
+module github.com/mattn/go-sqlite3
+
+go 1.12

+ 0 - 0
vendor/github.com/mattn/go-sqlite3/go.sum


File diff suppressed because it is too large
+ 234589 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c


File diff suppressed because it is too large
+ 12365 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h


File diff suppressed because it is too large
+ 2183 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3.go


+ 103 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_context.go

@@ -0,0 +1,103 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package sqlite3
+
+/*
+
+#ifndef USE_LIBSQLITE3
+#include <sqlite3-binding.h>
+#else
+#include <sqlite3.h>
+#endif
+#include <stdlib.h>
+// These wrappers are necessary because SQLITE_TRANSIENT
+// is a pointer constant, and cgo doesn't translate them correctly.
+
+static inline void my_result_text(sqlite3_context *ctx, char *p, int np) {
+	sqlite3_result_text(ctx, p, np, SQLITE_TRANSIENT);
+}
+
+static inline void my_result_blob(sqlite3_context *ctx, void *p, int np) {
+	sqlite3_result_blob(ctx, p, np, SQLITE_TRANSIENT);
+}
+*/
+import "C"
+
+import (
+	"math"
+	"reflect"
+	"unsafe"
+)
+
+const i64 = unsafe.Sizeof(int(0)) > 4
+
+// SQLiteContext behave sqlite3_context
+type SQLiteContext C.sqlite3_context
+
+// ResultBool sets the result of an SQL function.
+func (c *SQLiteContext) ResultBool(b bool) {
+	if b {
+		c.ResultInt(1)
+	} else {
+		c.ResultInt(0)
+	}
+}
+
+// ResultBlob sets the result of an SQL function.
+// See: sqlite3_result_blob, http://sqlite.org/c3ref/result_blob.html
+func (c *SQLiteContext) ResultBlob(b []byte) {
+	if i64 && len(b) > math.MaxInt32 {
+		C.sqlite3_result_error_toobig((*C.sqlite3_context)(c))
+		return
+	}
+	var p *byte
+	if len(b) > 0 {
+		p = &b[0]
+	}
+	C.my_result_blob((*C.sqlite3_context)(c), unsafe.Pointer(p), C.int(len(b)))
+}
+
+// ResultDouble sets the result of an SQL function.
+// See: sqlite3_result_double, http://sqlite.org/c3ref/result_blob.html
+func (c *SQLiteContext) ResultDouble(d float64) {
+	C.sqlite3_result_double((*C.sqlite3_context)(c), C.double(d))
+}
+
+// ResultInt sets the result of an SQL function.
+// See: sqlite3_result_int, http://sqlite.org/c3ref/result_blob.html
+func (c *SQLiteContext) ResultInt(i int) {
+	if i64 && (i > math.MaxInt32 || i < math.MinInt32) {
+		C.sqlite3_result_int64((*C.sqlite3_context)(c), C.sqlite3_int64(i))
+	} else {
+		C.sqlite3_result_int((*C.sqlite3_context)(c), C.int(i))
+	}
+}
+
+// ResultInt64 sets the result of an SQL function.
+// See: sqlite3_result_int64, http://sqlite.org/c3ref/result_blob.html
+func (c *SQLiteContext) ResultInt64(i int64) {
+	C.sqlite3_result_int64((*C.sqlite3_context)(c), C.sqlite3_int64(i))
+}
+
+// ResultNull sets the result of an SQL function.
+// See: sqlite3_result_null, http://sqlite.org/c3ref/result_blob.html
+func (c *SQLiteContext) ResultNull() {
+	C.sqlite3_result_null((*C.sqlite3_context)(c))
+}
+
+// ResultText sets the result of an SQL function.
+// See: sqlite3_result_text, http://sqlite.org/c3ref/result_blob.html
+func (c *SQLiteContext) ResultText(s string) {
+	h := (*reflect.StringHeader)(unsafe.Pointer(&s))
+	cs, l := (*C.char)(unsafe.Pointer(h.Data)), C.int(h.Len)
+	C.my_result_text((*C.sqlite3_context)(c), cs, l)
+}
+
+// ResultZeroblob sets the result of an SQL function.
+// See: sqlite3_result_zeroblob, http://sqlite.org/c3ref/result_blob.html
+func (c *SQLiteContext) ResultZeroblob(n int) {
+	C.sqlite3_result_zeroblob((*C.sqlite3_context)(c), C.int(n))
+}

+ 120 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_func_crypt.go

@@ -0,0 +1,120 @@
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package sqlite3
+
+import (
+	"crypto/sha1"
+	"crypto/sha256"
+	"crypto/sha512"
+)
+
+// This file provides several different implementations for the
+// default embedded sqlite_crypt function.
+// This function is uses a caesar-cypher by default
+// and is used within the UserAuthentication module to encode
+// the password.
+//
+// The provided functions can be used as an overload to the sqlite_crypt
+// function through the use of the RegisterFunc on the connection.
+//
+// Because the functions can serv a purpose to an end-user
+// without using the UserAuthentication module
+// the functions are default compiled in.
+//
+// From SQLITE3 - user-auth.txt
+// The sqlite_user.pw field is encoded by a built-in SQL function
+// "sqlite_crypt(X,Y)".  The two arguments are both BLOBs.  The first argument
+// is the plaintext password supplied to the sqlite3_user_authenticate()
+// interface.  The second argument is the sqlite_user.pw value and is supplied
+// so that the function can extract the "salt" used by the password encoder.
+// The result of sqlite_crypt(X,Y) is another blob which is the value that
+// ends up being stored in sqlite_user.pw.  To verify credentials X supplied
+// by the sqlite3_user_authenticate() routine, SQLite runs:
+//
+//     sqlite_user.pw == sqlite_crypt(X, sqlite_user.pw)
+//
+// To compute an appropriate sqlite_user.pw value from a new or modified
+// password X, sqlite_crypt(X,NULL) is run.  A new random salt is selected
+// when the second argument is NULL.
+//
+// The built-in version of of sqlite_crypt() uses a simple Caesar-cypher
+// which prevents passwords from being revealed by searching the raw database
+// for ASCII text, but is otherwise trivally broken.  For better password
+// security, the database should be encrypted using the SQLite Encryption
+// Extension or similar technology.  Or, the application can use the
+// sqlite3_create_function() interface to provide an alternative
+// implementation of sqlite_crypt() that computes a stronger password hash,
+// perhaps using a cryptographic hash function like SHA1.
+
+// CryptEncoderSHA1 encodes a password with SHA1
+func CryptEncoderSHA1(pass []byte, hash interface{}) []byte {
+	h := sha1.Sum(pass)
+	return h[:]
+}
+
+// CryptEncoderSSHA1 encodes a password with SHA1 with the
+// configured salt.
+func CryptEncoderSSHA1(salt string) func(pass []byte, hash interface{}) []byte {
+	return func(pass []byte, hash interface{}) []byte {
+		s := []byte(salt)
+		p := append(pass, s...)
+		h := sha1.Sum(p)
+		return h[:]
+	}
+}
+
+// CryptEncoderSHA256 encodes a password with SHA256
+func CryptEncoderSHA256(pass []byte, hash interface{}) []byte {
+	h := sha256.Sum256(pass)
+	return h[:]
+}
+
+// CryptEncoderSSHA256 encodes a password with SHA256
+// with the configured salt
+func CryptEncoderSSHA256(salt string) func(pass []byte, hash interface{}) []byte {
+	return func(pass []byte, hash interface{}) []byte {
+		s := []byte(salt)
+		p := append(pass, s...)
+		h := sha256.Sum256(p)
+		return h[:]
+	}
+}
+
+// CryptEncoderSHA384 encodes a password with SHA384
+func CryptEncoderSHA384(pass []byte, hash interface{}) []byte {
+	h := sha512.Sum384(pass)
+	return h[:]
+}
+
+// CryptEncoderSSHA384 encodes a password with SHA384
+// with the configured salt
+func CryptEncoderSSHA384(salt string) func(pass []byte, hash interface{}) []byte {
+	return func(pass []byte, hash interface{}) []byte {
+		s := []byte(salt)
+		p := append(pass, s...)
+		h := sha512.Sum384(p)
+		return h[:]
+	}
+}
+
+// CryptEncoderSHA512 encodes a password with SHA512
+func CryptEncoderSHA512(pass []byte, hash interface{}) []byte {
+	h := sha512.Sum512(pass)
+	return h[:]
+}
+
+// CryptEncoderSSHA512 encodes a password with SHA512
+// with the configured salt
+func CryptEncoderSSHA512(salt string) func(pass []byte, hash interface{}) []byte {
+	return func(pass []byte, hash interface{}) []byte {
+		s := []byte(salt)
+		p := append(pass, s...)
+		h := sha512.Sum512(p)
+		return h[:]
+	}
+}
+
+// EOF

+ 70 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_go18.go

@@ -0,0 +1,70 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build cgo
+// +build go1.8
+
+package sqlite3
+
+import (
+	"database/sql/driver"
+
+	"context"
+)
+
+// Ping implement Pinger.
+func (c *SQLiteConn) Ping(ctx context.Context) error {
+	if c.db == nil {
+		// must be ErrBadConn for sql to close the database
+		return driver.ErrBadConn
+	}
+	return nil
+}
+
+// QueryContext implement QueryerContext.
+func (c *SQLiteConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
+	list := make([]namedValue, len(args))
+	for i, nv := range args {
+		list[i] = namedValue(nv)
+	}
+	return c.query(ctx, query, list)
+}
+
+// ExecContext implement ExecerContext.
+func (c *SQLiteConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
+	list := make([]namedValue, len(args))
+	for i, nv := range args {
+		list[i] = namedValue(nv)
+	}
+	return c.exec(ctx, query, list)
+}
+
+// PrepareContext implement ConnPrepareContext.
+func (c *SQLiteConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
+	return c.prepare(ctx, query)
+}
+
+// BeginTx implement ConnBeginTx.
+func (c *SQLiteConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
+	return c.begin(ctx)
+}
+
+// QueryContext implement QueryerContext.
+func (s *SQLiteStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
+	list := make([]namedValue, len(args))
+	for i, nv := range args {
+		list[i] = namedValue(nv)
+	}
+	return s.query(ctx, list)
+}
+
+// ExecContext implement ExecerContext.
+func (s *SQLiteStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
+	list := make([]namedValue, len(args))
+	for i, nv := range args {
+		list[i] = namedValue(nv)
+	}
+	return s.exec(ctx, list)
+}

+ 19 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go

@@ -0,0 +1,19 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build libsqlite3
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DUSE_LIBSQLITE3
+#cgo linux LDFLAGS: -lsqlite3
+#cgo darwin LDFLAGS: -L/usr/local/opt/sqlite/lib -lsqlite3
+#cgo darwin CFLAGS: -I/usr/local/opt/sqlite/include
+#cgo openbsd LDFLAGS: -lsqlite3
+#cgo solaris LDFLAGS: -lsqlite3
+#cgo windows LDFLAGS: -lsqlite3
+*/
+import "C"

+ 84 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension.go

@@ -0,0 +1,84 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build !sqlite_omit_load_extension
+
+package sqlite3
+
+/*
+#ifndef USE_LIBSQLITE3
+#include <sqlite3-binding.h>
+#else
+#include <sqlite3.h>
+#endif
+#include <stdlib.h>
+*/
+import "C"
+import (
+	"errors"
+	"unsafe"
+)
+
+func (c *SQLiteConn) loadExtensions(extensions []string) error {
+	rv := C.sqlite3_enable_load_extension(c.db, 1)
+	if rv != C.SQLITE_OK {
+		return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
+	}
+
+	for _, extension := range extensions {
+		if err := c.loadExtension(extension, nil); err != nil {
+			C.sqlite3_enable_load_extension(c.db, 0)
+			return err
+		}
+	}
+
+	rv = C.sqlite3_enable_load_extension(c.db, 0)
+	if rv != C.SQLITE_OK {
+		return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
+	}
+
+	return nil
+}
+
+// LoadExtension load the sqlite3 extension.
+func (c *SQLiteConn) LoadExtension(lib string, entry string) error {
+	rv := C.sqlite3_enable_load_extension(c.db, 1)
+	if rv != C.SQLITE_OK {
+		return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
+	}
+
+	if err := c.loadExtension(lib, &entry); err != nil {
+		C.sqlite3_enable_load_extension(c.db, 0)
+		return err
+	}
+
+	rv = C.sqlite3_enable_load_extension(c.db, 0)
+	if rv != C.SQLITE_OK {
+		return errors.New(C.GoString(C.sqlite3_errmsg(c.db)))
+	}
+
+	return nil
+}
+
+func (c *SQLiteConn) loadExtension(lib string, entry *string) error {
+	clib := C.CString(lib)
+	defer C.free(unsafe.Pointer(clib))
+
+	var centry *C.char
+	if entry != nil {
+		centry = C.CString(*entry)
+		defer C.free(unsafe.Pointer(centry))
+	}
+
+	var errMsg *C.char
+	defer C.sqlite3_free(unsafe.Pointer(errMsg))
+
+	rv := C.sqlite3_load_extension(c.db, clib, centry, &errMsg)
+	if rv != C.SQLITE_OK {
+		return errors.New(C.GoString(errMsg))
+	}
+
+	return nil
+}

+ 24 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension_omit.go

@@ -0,0 +1,24 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_omit_load_extension
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_OMIT_LOAD_EXTENSION
+*/
+import "C"
+import (
+	"errors"
+)
+
+func (c *SQLiteConn) loadExtensions(extensions []string) error {
+	return errors.New("Extensions have been disabled for static builds")
+}
+
+func (c *SQLiteConn) LoadExtension(lib string, entry string) error {
+	return errors.New("Extensions have been disabled for static builds")
+}

+ 15 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_allow_uri_authority.go

@@ -0,0 +1,15 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_allow_uri_authority
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_ALLOW_URI_AUTHORITY
+#cgo LDFLAGS: -lm
+*/
+import "C"

+ 16 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_app_armor.go

@@ -0,0 +1,16 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build !windows
+// +build sqlite_app_armor
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_ENABLE_API_ARMOR
+#cgo LDFLAGS: -lm
+*/
+import "C"

+ 21 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_column_metadata.go

@@ -0,0 +1,21 @@
+// +build sqlite_column_metadata
+
+package sqlite3
+
+/*
+#ifndef USE_LIBSQLITE3
+#cgo CFLAGS: -DSQLITE_ENABLE_COLUMN_METADATA
+#include <sqlite3-binding.h>
+#else
+#include <sqlite3.h>
+#endif
+*/
+import "C"
+
+// ColumnTableName returns the table that is the origin of a particular result
+// column in a SELECT statement.
+//
+// See https://www.sqlite.org/c3ref/column_database_name.html
+func (s *SQLiteStmt) ColumnTableName(n int) string {
+	return C.GoString(C.sqlite3_column_table_name(s.s, C.int(n)))
+}

+ 15 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_foreign_keys.go

@@ -0,0 +1,15 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_foreign_keys
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_DEFAULT_FOREIGN_KEYS=1
+#cgo LDFLAGS: -lm
+*/
+import "C"

+ 14 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_fts5.go

@@ -0,0 +1,14 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_fts5 fts5
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_ENABLE_FTS5
+#cgo LDFLAGS: -lm
+*/
+import "C"

+ 17 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_icu.go

@@ -0,0 +1,17 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_icu icu
+
+package sqlite3
+
+/*
+#cgo LDFLAGS: -licuuc -licui18n
+#cgo CFLAGS: -DSQLITE_ENABLE_ICU
+#cgo darwin CFLAGS: -I/usr/local/opt/icu4c/include
+#cgo darwin LDFLAGS: -L/usr/local/opt/icu4c/lib
+#cgo openbsd LDFLAGS: -lsqlite3
+*/
+import "C"

+ 15 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_introspect.go

@@ -0,0 +1,15 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_introspect
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_INTROSPECTION_PRAGMAS
+#cgo LDFLAGS: -lm
+*/
+import "C"

+ 13 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_json1.go

@@ -0,0 +1,13 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_json sqlite_json1 json1
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_ENABLE_JSON1
+*/
+import "C"

+ 20 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate.go

@@ -0,0 +1,20 @@
+// Copyright (C) 2019 G.J.R. Timmer <gjr.timmer@gmail.com>.
+// Copyright (C) 2018 segment.com <friends@segment.com>
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build cgo
+
+package sqlite3
+
+// SQLitePreUpdateData represents all of the data available during a
+// pre-update hook call.
+type SQLitePreUpdateData struct {
+	Conn         *SQLiteConn
+	Op           int
+	DatabaseName string
+	TableName    string
+	OldRowID     int64
+	NewRowID     int64
+}

+ 112 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_hook.go

@@ -0,0 +1,112 @@
+// Copyright (C) 2019 G.J.R. Timmer <gjr.timmer@gmail.com>.
+// Copyright (C) 2018 segment.com <friends@segment.com>
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_preupdate_hook
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_ENABLE_PREUPDATE_HOOK
+#cgo LDFLAGS: -lm
+
+#ifndef USE_LIBSQLITE3
+#include <sqlite3-binding.h>
+#else
+#include <sqlite3.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+void preUpdateHookTrampoline(void*, sqlite3 *, int, char *, char *, sqlite3_int64, sqlite3_int64);
+*/
+import "C"
+import (
+	"errors"
+	"unsafe"
+)
+
+// RegisterPreUpdateHook sets the pre-update hook for a connection.
+//
+// The callback is passed a SQLitePreUpdateData struct with the data for
+// the update, as well as methods for fetching copies of impacted data.
+//
+// If there is an existing update hook for this connection, it will be
+// removed. If callback is nil the existing hook (if any) will be removed
+// without creating a new one.
+func (c *SQLiteConn) RegisterPreUpdateHook(callback func(SQLitePreUpdateData)) {
+	if callback == nil {
+		C.sqlite3_preupdate_hook(c.db, nil, nil)
+	} else {
+		C.sqlite3_preupdate_hook(c.db, (*[0]byte)(unsafe.Pointer(C.preUpdateHookTrampoline)), unsafe.Pointer(newHandle(c, callback)))
+	}
+}
+
+// Depth returns the source path of the write, see sqlite3_preupdate_depth()
+func (d *SQLitePreUpdateData) Depth() int {
+	return int(C.sqlite3_preupdate_depth(d.Conn.db))
+}
+
+// Count returns the number of columns in the row
+func (d *SQLitePreUpdateData) Count() int {
+	return int(C.sqlite3_preupdate_count(d.Conn.db))
+}
+
+func (d *SQLitePreUpdateData) row(dest []interface{}, new bool) error {
+	for i := 0; i < d.Count() && i < len(dest); i++ {
+		var val *C.sqlite3_value
+		var src interface{}
+
+		// Initially I tried making this just a function pointer argument, but
+		// it's absurdly complicated to pass C function pointers.
+		if new {
+			C.sqlite3_preupdate_new(d.Conn.db, C.int(i), &val)
+		} else {
+			C.sqlite3_preupdate_old(d.Conn.db, C.int(i), &val)
+		}
+
+		switch C.sqlite3_value_type(val) {
+		case C.SQLITE_INTEGER:
+			src = int64(C.sqlite3_value_int64(val))
+		case C.SQLITE_FLOAT:
+			src = float64(C.sqlite3_value_double(val))
+		case C.SQLITE_BLOB:
+			len := C.sqlite3_value_bytes(val)
+			blobptr := C.sqlite3_value_blob(val)
+			src = C.GoBytes(blobptr, len)
+		case C.SQLITE_TEXT:
+			len := C.sqlite3_value_bytes(val)
+			cstrptr := unsafe.Pointer(C.sqlite3_value_text(val))
+			src = C.GoBytes(cstrptr, len)
+		case C.SQLITE_NULL:
+			src = nil
+		}
+
+		err := convertAssign(&dest[i], src)
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+// Old populates dest with the row data to be replaced. This works similar to
+// database/sql's Rows.Scan()
+func (d *SQLitePreUpdateData) Old(dest ...interface{}) error {
+	if d.Op == SQLITE_INSERT {
+		return errors.New("There is no old row for INSERT operations")
+	}
+	return d.row(dest, false)
+}
+
+// New populates dest with the replacement row data. This works similar to
+// database/sql's Rows.Scan()
+func (d *SQLitePreUpdateData) New(dest ...interface{}) error {
+	if d.Op == SQLITE_DELETE {
+		return errors.New("There is no new row for DELETE operations")
+	}
+	return d.row(dest, true)
+}

+ 21 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_omit.go

@@ -0,0 +1,21 @@
+// Copyright (C) 2019 G.J.R. Timmer <gjr.timmer@gmail.com>.
+// Copyright (C) 2018 segment.com <friends@segment.com>
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build !sqlite_preupdate_hook,cgo
+
+package sqlite3
+
+// RegisterPreUpdateHook sets the pre-update hook for a connection.
+//
+// The callback is passed a SQLitePreUpdateData struct with the data for
+// the update, as well as methods for fetching copies of impacted data.
+//
+// If there is an existing update hook for this connection, it will be
+// removed. If callback is nil the existing hook (if any) will be removed
+// without creating a new one.
+func (c *SQLiteConn) RegisterPreUpdateHook(callback func(SQLitePreUpdateData)) {
+	// NOOP
+}

+ 15 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_secure_delete.go

@@ -0,0 +1,15 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_secure_delete
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_SECURE_DELETE=1
+#cgo LDFLAGS: -lm
+*/
+import "C"

+ 15 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_secure_delete_fast.go

@@ -0,0 +1,15 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_secure_delete_fast
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_SECURE_DELETE=FAST
+#cgo LDFLAGS: -lm
+*/
+import "C"

+ 15 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_stat4.go

@@ -0,0 +1,15 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_stat4
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_ENABLE_STAT4
+#cgo LDFLAGS: -lm
+*/
+import "C"

+ 85 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.c

@@ -0,0 +1,85 @@
+// Copyright (C) 2018 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
+#include <stdio.h>
+#include <sqlite3-binding.h>
+
+extern int unlock_notify_wait(sqlite3 *db);
+
+int
+_sqlite3_step_blocking(sqlite3_stmt *stmt)
+{
+  int rv;
+  sqlite3* db;
+
+  db = sqlite3_db_handle(stmt);
+  for (;;) {
+    rv = sqlite3_step(stmt);
+    if (rv != SQLITE_LOCKED) {
+      break;
+    }
+    if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) {
+      break;
+    }
+    rv = unlock_notify_wait(db);
+    if (rv != SQLITE_OK) {
+      break;
+    }
+    sqlite3_reset(stmt);
+  }
+
+  return rv;
+}
+
+int
+_sqlite3_step_row_blocking(sqlite3_stmt* stmt, long long* rowid, long long* changes)
+{
+  int rv;
+  sqlite3* db;
+
+  db = sqlite3_db_handle(stmt);
+  for (;;) {
+    rv = sqlite3_step(stmt);
+    if (rv!=SQLITE_LOCKED) {
+      break;
+    }
+    if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) {
+      break;
+    }
+    rv = unlock_notify_wait(db);
+    if (rv != SQLITE_OK) {
+      break;
+    }
+    sqlite3_reset(stmt);
+  }
+
+  *rowid = (long long) sqlite3_last_insert_rowid(db);
+  *changes = (long long) sqlite3_changes(db);
+  return rv;
+}
+
+int
+_sqlite3_prepare_v2_blocking(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail)
+{
+  int rv;
+
+  for (;;) {
+    rv = sqlite3_prepare_v2(db, zSql, nBytes, ppStmt, pzTail);
+    if (rv!=SQLITE_LOCKED) {
+      break;
+    }
+    if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) {
+      break;
+    }
+    rv = unlock_notify_wait(db);
+    if (rv != SQLITE_OK) {
+      break;
+    }
+  }
+
+  return rv;
+}
+#endif

+ 93 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.go

@@ -0,0 +1,93 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build cgo
+// +build sqlite_unlock_notify
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_ENABLE_UNLOCK_NOTIFY
+
+#include <stdlib.h>
+#include <sqlite3-binding.h>
+
+extern void unlock_notify_callback(void *arg, int argc);
+*/
+import "C"
+import (
+	"fmt"
+	"math"
+	"sync"
+	"unsafe"
+)
+
+type unlock_notify_table struct {
+	sync.Mutex
+	seqnum uint
+	table  map[uint]chan struct{}
+}
+
+var unt unlock_notify_table = unlock_notify_table{table: make(map[uint]chan struct{})}
+
+func (t *unlock_notify_table) add(c chan struct{}) uint {
+	t.Lock()
+	defer t.Unlock()
+	h := t.seqnum
+	t.table[h] = c
+	t.seqnum++
+	return h
+}
+
+func (t *unlock_notify_table) remove(h uint) {
+	t.Lock()
+	defer t.Unlock()
+	delete(t.table, h)
+}
+
+func (t *unlock_notify_table) get(h uint) chan struct{} {
+	t.Lock()
+	defer t.Unlock()
+	c, ok := t.table[h]
+	if !ok {
+		panic(fmt.Sprintf("Non-existent key for unlcok-notify channel: %d", h))
+	}
+	return c
+}
+
+//export unlock_notify_callback
+func unlock_notify_callback(argv unsafe.Pointer, argc C.int) {
+	for i := 0; i < int(argc); i++ {
+		parg := ((*(*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.uint)(nil))]*[1]uint)(argv))[i])
+		arg := *parg
+		h := arg[0]
+		c := unt.get(h)
+		c <- struct{}{}
+	}
+}
+
+//export unlock_notify_wait
+func unlock_notify_wait(db *C.sqlite3) C.int {
+	// It has to be a bufferred channel to not block in sqlite_unlock_notify
+	// as sqlite_unlock_notify could invoke the callback before it returns.
+	c := make(chan struct{}, 1)
+	defer close(c)
+
+	h := unt.add(c)
+	defer unt.remove(h)
+
+	pargv := C.malloc(C.sizeof_uint)
+	defer C.free(pargv)
+
+	argv := (*[1]uint)(pargv)
+	argv[0] = h
+	if rv := C.sqlite3_unlock_notify(db, (*[0]byte)(C.unlock_notify_callback), unsafe.Pointer(pargv)); rv != C.SQLITE_OK {
+		return rv
+	}
+
+	<-c
+
+	return C.SQLITE_OK
+}

+ 289 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_userauth.go

@@ -0,0 +1,289 @@
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_userauth
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_USER_AUTHENTICATION
+#cgo LDFLAGS: -lm
+#ifndef USE_LIBSQLITE3
+#include <sqlite3-binding.h>
+#else
+#include <sqlite3.h>
+#endif
+#include <stdlib.h>
+
+static int
+_sqlite3_user_authenticate(sqlite3* db, const char* zUsername, const char* aPW, int nPW)
+{
+  return sqlite3_user_authenticate(db, zUsername, aPW, nPW);
+}
+
+static int
+_sqlite3_user_add(sqlite3* db, const char* zUsername, const char* aPW, int nPW, int isAdmin)
+{
+  return sqlite3_user_add(db, zUsername, aPW, nPW, isAdmin);
+}
+
+static int
+_sqlite3_user_change(sqlite3* db, const char* zUsername, const char* aPW, int nPW, int isAdmin)
+{
+  return sqlite3_user_change(db, zUsername, aPW, nPW, isAdmin);
+}
+
+static int
+_sqlite3_user_delete(sqlite3* db, const char* zUsername)
+{
+  return sqlite3_user_delete(db, zUsername);
+}
+
+static int
+_sqlite3_auth_enabled(sqlite3* db)
+{
+	int exists = -1;
+
+	sqlite3_stmt *stmt;
+	sqlite3_prepare_v2(db, "select count(type) from sqlite_master WHERE type='table' and name='sqlite_user';", -1, &stmt, NULL);
+
+	while ( sqlite3_step(stmt) == SQLITE_ROW) {
+		exists = sqlite3_column_int(stmt, 0);
+	}
+
+	sqlite3_finalize(stmt);
+
+	return exists;
+}
+*/
+import "C"
+import (
+	"errors"
+	"unsafe"
+)
+
+const (
+	SQLITE_AUTH = C.SQLITE_AUTH
+)
+
+var (
+	ErrUnauthorized  = errors.New("SQLITE_AUTH: Unauthorized")
+	ErrAdminRequired = errors.New("SQLITE_AUTH: Unauthorized; Admin Privileges Required")
+)
+
+// Authenticate will perform an authentication of the provided username
+// and password against the database.
+//
+// If a database contains the SQLITE_USER table, then the
+// call to Authenticate must be invoked with an
+// appropriate username and password prior to enable read and write
+//access to the database.
+//
+// Return SQLITE_OK on success or SQLITE_ERROR if the username/password
+// combination is incorrect or unknown.
+//
+// If the SQLITE_USER table is not present in the database file, then
+// this interface is a harmless no-op returnning SQLITE_OK.
+func (c *SQLiteConn) Authenticate(username, password string) error {
+	rv := c.authenticate(username, password)
+	switch rv {
+	case C.SQLITE_ERROR, C.SQLITE_AUTH:
+		return ErrUnauthorized
+	case C.SQLITE_OK:
+		return nil
+	default:
+		return c.lastError()
+	}
+}
+
+// authenticate provides the actual authentication to SQLite.
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+//	C.SQLITE_OK (0)
+//	C.SQLITE_ERROR (1)
+//  C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authenticate(username, password string) int {
+	// Allocate C Variables
+	cuser := C.CString(username)
+	cpass := C.CString(password)
+
+	// Free C Variables
+	defer func() {
+		C.free(unsafe.Pointer(cuser))
+		C.free(unsafe.Pointer(cpass))
+	}()
+
+	return int(C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password))))
+}
+
+// AuthUserAdd can be used (by an admin user only)
+// to create a new user. When called on a no-authentication-required
+// database, this routine converts the database into an authentication-
+// required database, automatically makes the added user an
+// administrator, and logs in the current connection as that user.
+// The AuthUserAdd only works for the "main" database, not
+// for any ATTACH-ed databases. Any call to AuthUserAdd by a
+// non-admin user results in an error.
+func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
+	isAdmin := 0
+	if admin {
+		isAdmin = 1
+	}
+
+	rv := c.authUserAdd(username, password, isAdmin)
+	switch rv {
+	case C.SQLITE_ERROR, C.SQLITE_AUTH:
+		return ErrAdminRequired
+	case C.SQLITE_OK:
+		return nil
+	default:
+		return c.lastError()
+	}
+}
+
+// authUserAdd enables the User Authentication if not enabled.
+// Otherwise it will add a user.
+//
+// When user authentication is already enabled then this function
+// can only be called by an admin.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+//	C.SQLITE_OK (0)
+//	C.SQLITE_ERROR (1)
+//  C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
+	// Allocate C Variables
+	cuser := C.CString(username)
+	cpass := C.CString(password)
+
+	// Free C Variables
+	defer func() {
+		C.free(unsafe.Pointer(cuser))
+		C.free(unsafe.Pointer(cpass))
+	}()
+
+	return int(C._sqlite3_user_add(c.db, cuser, cpass, C.int(len(password)), C.int(admin)))
+}
+
+// AuthUserChange can be used to change a users
+// login credentials or admin privilege.  Any user can change their own
+// login credentials. Only an admin user can change another users login
+// credentials or admin privilege setting. No user may change their own
+// admin privilege setting.
+func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error {
+	isAdmin := 0
+	if admin {
+		isAdmin = 1
+	}
+
+	rv := c.authUserChange(username, password, isAdmin)
+	switch rv {
+	case C.SQLITE_ERROR, C.SQLITE_AUTH:
+		return ErrAdminRequired
+	case C.SQLITE_OK:
+		return nil
+	default:
+		return c.lastError()
+	}
+}
+
+// authUserChange allows to modify a user.
+// Users can change their own password.
+//
+// Only admins can change passwords for other users
+// and modify the admin flag.
+//
+// The admin flag of the current logged in user cannot be changed.
+// THis ensures that their is always an admin.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+//	C.SQLITE_OK (0)
+//	C.SQLITE_ERROR (1)
+//  C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authUserChange(username, password string, admin int) int {
+	// Allocate C Variables
+	cuser := C.CString(username)
+	cpass := C.CString(password)
+
+	// Free C Variables
+	defer func() {
+		C.free(unsafe.Pointer(cuser))
+		C.free(unsafe.Pointer(cpass))
+	}()
+
+	return int(C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(admin)))
+}
+
+// AuthUserDelete can be used (by an admin user only)
+// to delete a user. The currently logged-in user cannot be deleted,
+// which guarantees that there is always an admin user and hence that
+// the database cannot be converted into a no-authentication-required
+// database.
+func (c *SQLiteConn) AuthUserDelete(username string) error {
+	rv := c.authUserDelete(username)
+	switch rv {
+	case C.SQLITE_ERROR, C.SQLITE_AUTH:
+		return ErrAdminRequired
+	case C.SQLITE_OK:
+		return nil
+	default:
+		return c.lastError()
+	}
+}
+
+// authUserDelete can be used to delete a user.
+//
+// This function can only be executed by an admin.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+//	C.SQLITE_OK (0)
+//	C.SQLITE_ERROR (1)
+//  C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authUserDelete(username string) int {
+	// Allocate C Variables
+	cuser := C.CString(username)
+
+	// Free C Variables
+	defer func() {
+		C.free(unsafe.Pointer(cuser))
+	}()
+
+	return int(C._sqlite3_user_delete(c.db, cuser))
+}
+
+// AuthEnabled checks if the database is protected by user authentication
+func (c *SQLiteConn) AuthEnabled() (exists bool) {
+	rv := c.authEnabled()
+	if rv == 1 {
+		exists = true
+	}
+
+	return
+}
+
+// authEnabled perform the actual check for user authentication.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+//	0 - Disabled
+//  1 - Enabled
+func (c *SQLiteConn) authEnabled() int {
+	return int(C._sqlite3_auth_enabled(c.db))
+}
+
+// EOF

+ 152 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_userauth_omit.go

@@ -0,0 +1,152 @@
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build !sqlite_userauth
+
+package sqlite3
+
+import (
+	"C"
+)
+
+// Authenticate will perform an authentication of the provided username
+// and password against the database.
+//
+// If a database contains the SQLITE_USER table, then the
+// call to Authenticate must be invoked with an
+// appropriate username and password prior to enable read and write
+//access to the database.
+//
+// Return SQLITE_OK on success or SQLITE_ERROR if the username/password
+// combination is incorrect or unknown.
+//
+// If the SQLITE_USER table is not present in the database file, then
+// this interface is a harmless no-op returnning SQLITE_OK.
+func (c *SQLiteConn) Authenticate(username, password string) error {
+	// NOOP
+	return nil
+}
+
+// authenticate provides the actual authentication to SQLite.
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+//	C.SQLITE_OK (0)
+//	C.SQLITE_ERROR (1)
+//  C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authenticate(username, password string) int {
+	// NOOP
+	return 0
+}
+
+// AuthUserAdd can be used (by an admin user only)
+// to create a new user.  When called on a no-authentication-required
+// database, this routine converts the database into an authentication-
+// required database, automatically makes the added user an
+// administrator, and logs in the current connection as that user.
+// The AuthUserAdd only works for the "main" database, not
+// for any ATTACH-ed databases. Any call to AuthUserAdd by a
+// non-admin user results in an error.
+func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
+	// NOOP
+	return nil
+}
+
+// authUserAdd enables the User Authentication if not enabled.
+// Otherwise it will add a user.
+//
+// When user authentication is already enabled then this function
+// can only be called by an admin.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+//	C.SQLITE_OK (0)
+//	C.SQLITE_ERROR (1)
+//  C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
+	// NOOP
+	return 0
+}
+
+// AuthUserChange can be used to change a users
+// login credentials or admin privilege.  Any user can change their own
+// login credentials.  Only an admin user can change another users login
+// credentials or admin privilege setting.  No user may change their own
+// admin privilege setting.
+func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error {
+	// NOOP
+	return nil
+}
+
+// authUserChange allows to modify a user.
+// Users can change their own password.
+//
+// Only admins can change passwords for other users
+// and modify the admin flag.
+//
+// The admin flag of the current logged in user cannot be changed.
+// THis ensures that their is always an admin.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+//	C.SQLITE_OK (0)
+//	C.SQLITE_ERROR (1)
+//  C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authUserChange(username, password string, admin int) int {
+	// NOOP
+	return 0
+}
+
+// AuthUserDelete can be used (by an admin user only)
+// to delete a user.  The currently logged-in user cannot be deleted,
+// which guarantees that there is always an admin user and hence that
+// the database cannot be converted into a no-authentication-required
+// database.
+func (c *SQLiteConn) AuthUserDelete(username string) error {
+	// NOOP
+	return nil
+}
+
+// authUserDelete can be used to delete a user.
+//
+// This function can only be executed by an admin.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+//	C.SQLITE_OK (0)
+//	C.SQLITE_ERROR (1)
+//  C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authUserDelete(username string) int {
+	// NOOP
+	return 0
+}
+
+// AuthEnabled checks if the database is protected by user authentication
+func (c *SQLiteConn) AuthEnabled() (exists bool) {
+	// NOOP
+	return false
+}
+
+// authEnabled perform the actual check for user authentication.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+//	0 - Disabled
+//  1 - Enabled
+func (c *SQLiteConn) authEnabled() int {
+	// NOOP
+	return 0
+}
+
+// EOF

+ 15 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vacuum_full.go

@@ -0,0 +1,15 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_vacuum_full
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_DEFAULT_AUTOVACUUM=1
+#cgo LDFLAGS: -lm
+*/
+import "C"

+ 15 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vacuum_incr.go

@@ -0,0 +1,15 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_vacuum_incr
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -DSQLITE_DEFAULT_AUTOVACUUM=2
+#cgo LDFLAGS: -lm
+*/
+import "C"

+ 709 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vtable.go

@@ -0,0 +1,709 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_vtable vtable
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -std=gnu99
+#cgo CFLAGS: -DSQLITE_ENABLE_RTREE
+#cgo CFLAGS: -DSQLITE_THREADSAFE
+#cgo CFLAGS: -DSQLITE_ENABLE_FTS3
+#cgo CFLAGS: -DSQLITE_ENABLE_FTS3_PARENTHESIS
+#cgo CFLAGS: -DSQLITE_ENABLE_FTS4_UNICODE61
+#cgo CFLAGS: -DSQLITE_TRACE_SIZE_LIMIT=15
+#cgo CFLAGS: -DSQLITE_ENABLE_COLUMN_METADATA=1
+#cgo CFLAGS: -Wno-deprecated-declarations
+
+#ifndef USE_LIBSQLITE3
+#include <sqlite3-binding.h>
+#else
+#include <sqlite3.h>
+#endif
+#include <stdlib.h>
+#include <stdint.h>
+#include <memory.h>
+
+static inline char *_sqlite3_mprintf(char *zFormat, char *arg) {
+  return sqlite3_mprintf(zFormat, arg);
+}
+
+typedef struct goVTab goVTab;
+
+struct goVTab {
+	sqlite3_vtab base;
+	void *vTab;
+};
+
+uintptr_t goMInit(void *db, void *pAux, int argc, char **argv, char **pzErr, int isCreate);
+
+static int cXInit(sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char **pzErr, int isCreate) {
+	void *vTab = (void *)goMInit(db, pAux, argc, (char**)argv, pzErr, isCreate);
+	if (!vTab || *pzErr) {
+		return SQLITE_ERROR;
+	}
+	goVTab *pvTab = (goVTab *)sqlite3_malloc(sizeof(goVTab));
+	if (!pvTab) {
+		*pzErr = sqlite3_mprintf("%s", "Out of memory");
+		return SQLITE_NOMEM;
+	}
+	memset(pvTab, 0, sizeof(goVTab));
+	pvTab->vTab = vTab;
+
+	*ppVTab = (sqlite3_vtab *)pvTab;
+	*pzErr = 0;
+	return SQLITE_OK;
+}
+
+static inline int cXCreate(sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char **pzErr) {
+	return cXInit(db, pAux, argc, argv, ppVTab, pzErr, 1);
+}
+static inline int cXConnect(sqlite3 *db, void *pAux, int argc, const char *const*argv, sqlite3_vtab **ppVTab, char **pzErr) {
+	return cXInit(db, pAux, argc, argv, ppVTab, pzErr, 0);
+}
+
+char* goVBestIndex(void *pVTab, void *icp);
+
+static inline int cXBestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *info) {
+	char *pzErr = goVBestIndex(((goVTab*)pVTab)->vTab, info);
+	if (pzErr) {
+		if (pVTab->zErrMsg)
+			sqlite3_free(pVTab->zErrMsg);
+		pVTab->zErrMsg = pzErr;
+		return SQLITE_ERROR;
+	}
+	return SQLITE_OK;
+}
+
+char* goVRelease(void *pVTab, int isDestroy);
+
+static int cXRelease(sqlite3_vtab *pVTab, int isDestroy) {
+	char *pzErr = goVRelease(((goVTab*)pVTab)->vTab, isDestroy);
+	if (pzErr) {
+		if (pVTab->zErrMsg)
+			sqlite3_free(pVTab->zErrMsg);
+		pVTab->zErrMsg = pzErr;
+		return SQLITE_ERROR;
+	}
+	if (pVTab->zErrMsg)
+		sqlite3_free(pVTab->zErrMsg);
+	sqlite3_free(pVTab);
+	return SQLITE_OK;
+}
+
+static inline int cXDisconnect(sqlite3_vtab *pVTab) {
+	return cXRelease(pVTab, 0);
+}
+static inline int cXDestroy(sqlite3_vtab *pVTab) {
+	return cXRelease(pVTab, 1);
+}
+
+typedef struct goVTabCursor goVTabCursor;
+
+struct goVTabCursor {
+	sqlite3_vtab_cursor base;
+	void *vTabCursor;
+};
+
+uintptr_t goVOpen(void *pVTab, char **pzErr);
+
+static int cXOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) {
+	void *vTabCursor = (void *)goVOpen(((goVTab*)pVTab)->vTab, &(pVTab->zErrMsg));
+	goVTabCursor *pCursor = (goVTabCursor *)sqlite3_malloc(sizeof(goVTabCursor));
+	if (!pCursor) {
+		return SQLITE_NOMEM;
+	}
+	memset(pCursor, 0, sizeof(goVTabCursor));
+	pCursor->vTabCursor = vTabCursor;
+	*ppCursor = (sqlite3_vtab_cursor *)pCursor;
+	return SQLITE_OK;
+}
+
+static int setErrMsg(sqlite3_vtab_cursor *pCursor, char *pzErr) {
+	if (pCursor->pVtab->zErrMsg)
+		sqlite3_free(pCursor->pVtab->zErrMsg);
+	pCursor->pVtab->zErrMsg = pzErr;
+	return SQLITE_ERROR;
+}
+
+char* goVClose(void *pCursor);
+
+static int cXClose(sqlite3_vtab_cursor *pCursor) {
+	char *pzErr = goVClose(((goVTabCursor*)pCursor)->vTabCursor);
+	if (pzErr) {
+		return setErrMsg(pCursor, pzErr);
+	}
+	sqlite3_free(pCursor);
+	return SQLITE_OK;
+}
+
+char* goVFilter(void *pCursor, int idxNum, char* idxName, int argc, sqlite3_value **argv);
+
+static int cXFilter(sqlite3_vtab_cursor *pCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv) {
+	char *pzErr = goVFilter(((goVTabCursor*)pCursor)->vTabCursor, idxNum, (char*)idxStr, argc, argv);
+	if (pzErr) {
+		return setErrMsg(pCursor, pzErr);
+	}
+	return SQLITE_OK;
+}
+
+char* goVNext(void *pCursor);
+
+static int cXNext(sqlite3_vtab_cursor *pCursor) {
+	char *pzErr = goVNext(((goVTabCursor*)pCursor)->vTabCursor);
+	if (pzErr) {
+		return setErrMsg(pCursor, pzErr);
+	}
+	return SQLITE_OK;
+}
+
+int goVEof(void *pCursor);
+
+static inline int cXEof(sqlite3_vtab_cursor *pCursor) {
+	return goVEof(((goVTabCursor*)pCursor)->vTabCursor);
+}
+
+char* goVColumn(void *pCursor, void *cp, int col);
+
+static int cXColumn(sqlite3_vtab_cursor *pCursor, sqlite3_context *ctx, int i) {
+	char *pzErr = goVColumn(((goVTabCursor*)pCursor)->vTabCursor, ctx, i);
+	if (pzErr) {
+		return setErrMsg(pCursor, pzErr);
+	}
+	return SQLITE_OK;
+}
+
+char* goVRowid(void *pCursor, sqlite3_int64 *pRowid);
+
+static int cXRowid(sqlite3_vtab_cursor *pCursor, sqlite3_int64 *pRowid) {
+	char *pzErr = goVRowid(((goVTabCursor*)pCursor)->vTabCursor, pRowid);
+	if (pzErr) {
+		return setErrMsg(pCursor, pzErr);
+	}
+	return SQLITE_OK;
+}
+
+char* goVUpdate(void *pVTab, int argc, sqlite3_value **argv, sqlite3_int64 *pRowid);
+
+static int cXUpdate(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv, sqlite3_int64 *pRowid) {
+	char *pzErr = goVUpdate(((goVTab*)pVTab)->vTab, argc, argv, pRowid);
+	if (pzErr) {
+		if (pVTab->zErrMsg)
+			sqlite3_free(pVTab->zErrMsg);
+		pVTab->zErrMsg = pzErr;
+		return SQLITE_ERROR;
+	}
+	return SQLITE_OK;
+}
+
+static sqlite3_module goModule = {
+	0,                       // iVersion
+	cXCreate,                // xCreate - create a table
+	cXConnect,               // xConnect - connect to an existing table
+	cXBestIndex,             // xBestIndex - Determine search strategy
+	cXDisconnect,            // xDisconnect - Disconnect from a table
+	cXDestroy,               // xDestroy - Drop a table
+	cXOpen,                  // xOpen - open a cursor
+	cXClose,                 // xClose - close a cursor
+	cXFilter,                // xFilter - configure scan constraints
+	cXNext,                  // xNext - advance a cursor
+	cXEof,                   // xEof
+	cXColumn,                // xColumn - read data
+	cXRowid,                 // xRowid - read data
+	cXUpdate,                // xUpdate - write data
+// Not implemented
+	0,                       // xBegin - begin transaction
+	0,                       // xSync - sync transaction
+	0,                       // xCommit - commit transaction
+	0,                       // xRollback - rollback transaction
+	0,                       // xFindFunction - function overloading
+	0,                       // xRename - rename the table
+	0,                       // xSavepoint
+	0,                       // xRelease
+	0	                     // xRollbackTo
+};
+
+// See https://sqlite.org/vtab.html#eponymous_only_virtual_tables
+static sqlite3_module goModuleEponymousOnly = {
+	0,                       // iVersion
+	0,                       // xCreate - create a table, which here is null
+	cXConnect,               // xConnect - connect to an existing table
+	cXBestIndex,             // xBestIndex - Determine search strategy
+	cXDisconnect,            // xDisconnect - Disconnect from a table
+	cXDestroy,               // xDestroy - Drop a table
+	cXOpen,                  // xOpen - open a cursor
+	cXClose,                 // xClose - close a cursor
+	cXFilter,                // xFilter - configure scan constraints
+	cXNext,                  // xNext - advance a cursor
+	cXEof,                   // xEof
+	cXColumn,                // xColumn - read data
+	cXRowid,                 // xRowid - read data
+	cXUpdate,                // xUpdate - write data
+// Not implemented
+	0,                       // xBegin - begin transaction
+	0,                       // xSync - sync transaction
+	0,                       // xCommit - commit transaction
+	0,                       // xRollback - rollback transaction
+	0,                       // xFindFunction - function overloading
+	0,                       // xRename - rename the table
+	0,                       // xSavepoint
+	0,                       // xRelease
+	0	                     // xRollbackTo
+};
+
+void goMDestroy(void*);
+
+static int _sqlite3_create_module(sqlite3 *db, const char *zName, uintptr_t pClientData) {
+  return sqlite3_create_module_v2(db, zName, &goModule, (void*) pClientData, goMDestroy);
+}
+
+static int _sqlite3_create_module_eponymous_only(sqlite3 *db, const char *zName, uintptr_t pClientData) {
+  return sqlite3_create_module_v2(db, zName, &goModuleEponymousOnly, (void*) pClientData, goMDestroy);
+}
+*/
+import "C"
+
+import (
+	"fmt"
+	"math"
+	"reflect"
+	"unsafe"
+)
+
+type sqliteModule struct {
+	c      *SQLiteConn
+	name   string
+	module Module
+}
+
+type sqliteVTab struct {
+	module *sqliteModule
+	vTab   VTab
+}
+
+type sqliteVTabCursor struct {
+	vTab       *sqliteVTab
+	vTabCursor VTabCursor
+}
+
+// Op is type of operations.
+type Op uint8
+
+// Op mean identity of operations.
+const (
+	OpEQ         Op = 2
+	OpGT            = 4
+	OpLE            = 8
+	OpLT            = 16
+	OpGE            = 32
+	OpMATCH         = 64
+	OpLIKE          = 65 /* 3.10.0 and later only */
+	OpGLOB          = 66 /* 3.10.0 and later only */
+	OpREGEXP        = 67 /* 3.10.0 and later only */
+	OpScanUnique    = 1  /* Scan visits at most 1 row */
+)
+
+// InfoConstraint give information of constraint.
+type InfoConstraint struct {
+	Column int
+	Op     Op
+	Usable bool
+}
+
+// InfoOrderBy give information of order-by.
+type InfoOrderBy struct {
+	Column int
+	Desc   bool
+}
+
+func constraints(info *C.sqlite3_index_info) []InfoConstraint {
+	slice := *(*[]C.struct_sqlite3_index_constraint)(unsafe.Pointer(&reflect.SliceHeader{
+		Data: uintptr(unsafe.Pointer(info.aConstraint)),
+		Len:  int(info.nConstraint),
+		Cap:  int(info.nConstraint),
+	}))
+
+	cst := make([]InfoConstraint, 0, len(slice))
+	for _, c := range slice {
+		var usable bool
+		if c.usable > 0 {
+			usable = true
+		}
+		cst = append(cst, InfoConstraint{
+			Column: int(c.iColumn),
+			Op:     Op(c.op),
+			Usable: usable,
+		})
+	}
+	return cst
+}
+
+func orderBys(info *C.sqlite3_index_info) []InfoOrderBy {
+	slice := *(*[]C.struct_sqlite3_index_orderby)(unsafe.Pointer(&reflect.SliceHeader{
+		Data: uintptr(unsafe.Pointer(info.aOrderBy)),
+		Len:  int(info.nOrderBy),
+		Cap:  int(info.nOrderBy),
+	}))
+
+	ob := make([]InfoOrderBy, 0, len(slice))
+	for _, c := range slice {
+		var desc bool
+		if c.desc > 0 {
+			desc = true
+		}
+		ob = append(ob, InfoOrderBy{
+			Column: int(c.iColumn),
+			Desc:   desc,
+		})
+	}
+	return ob
+}
+
+// IndexResult is a Go struct representation of what eventually ends up in the
+// output fields for `sqlite3_index_info`
+// See: https://www.sqlite.org/c3ref/index_info.html
+type IndexResult struct {
+	Used           []bool // aConstraintUsage
+	IdxNum         int
+	IdxStr         string
+	AlreadyOrdered bool // orderByConsumed
+	EstimatedCost  float64
+	EstimatedRows  float64
+}
+
+// mPrintf is a utility wrapper around sqlite3_mprintf
+func mPrintf(format, arg string) *C.char {
+	cf := C.CString(format)
+	defer C.free(unsafe.Pointer(cf))
+	ca := C.CString(arg)
+	defer C.free(unsafe.Pointer(ca))
+	return C._sqlite3_mprintf(cf, ca)
+}
+
+//export goMInit
+func goMInit(db, pClientData unsafe.Pointer, argc C.int, argv **C.char, pzErr **C.char, isCreate C.int) C.uintptr_t {
+	m := lookupHandle(pClientData).(*sqliteModule)
+	if m.c.db != (*C.sqlite3)(db) {
+		*pzErr = mPrintf("%s", "Inconsistent db handles")
+		return 0
+	}
+	args := make([]string, argc)
+	var A []*C.char
+	slice := reflect.SliceHeader{Data: uintptr(unsafe.Pointer(argv)), Len: int(argc), Cap: int(argc)}
+	a := reflect.NewAt(reflect.TypeOf(A), unsafe.Pointer(&slice)).Elem().Interface()
+	for i, s := range a.([]*C.char) {
+		args[i] = C.GoString(s)
+	}
+	var vTab VTab
+	var err error
+	if isCreate == 1 {
+		vTab, err = m.module.Create(m.c, args)
+	} else {
+		vTab, err = m.module.Connect(m.c, args)
+	}
+
+	if err != nil {
+		*pzErr = mPrintf("%s", err.Error())
+		return 0
+	}
+	vt := sqliteVTab{m, vTab}
+	*pzErr = nil
+	return C.uintptr_t(uintptr(newHandle(m.c, &vt)))
+}
+
+//export goVRelease
+func goVRelease(pVTab unsafe.Pointer, isDestroy C.int) *C.char {
+	vt := lookupHandle(pVTab).(*sqliteVTab)
+	var err error
+	if isDestroy == 1 {
+		err = vt.vTab.Destroy()
+	} else {
+		err = vt.vTab.Disconnect()
+	}
+	if err != nil {
+		return mPrintf("%s", err.Error())
+	}
+	return nil
+}
+
+//export goVOpen
+func goVOpen(pVTab unsafe.Pointer, pzErr **C.char) C.uintptr_t {
+	vt := lookupHandle(pVTab).(*sqliteVTab)
+	vTabCursor, err := vt.vTab.Open()
+	if err != nil {
+		*pzErr = mPrintf("%s", err.Error())
+		return 0
+	}
+	vtc := sqliteVTabCursor{vt, vTabCursor}
+	*pzErr = nil
+	return C.uintptr_t(uintptr(newHandle(vt.module.c, &vtc)))
+}
+
+//export goVBestIndex
+func goVBestIndex(pVTab unsafe.Pointer, icp unsafe.Pointer) *C.char {
+	vt := lookupHandle(pVTab).(*sqliteVTab)
+	info := (*C.sqlite3_index_info)(icp)
+	csts := constraints(info)
+	res, err := vt.vTab.BestIndex(csts, orderBys(info))
+	if err != nil {
+		return mPrintf("%s", err.Error())
+	}
+	if len(res.Used) != len(csts) {
+		return mPrintf("Result.Used != expected value", "")
+	}
+
+	// Get a pointer to constraint_usage struct so we can update in place.
+
+	slice := *(*[]C.struct_sqlite3_index_constraint_usage)(unsafe.Pointer(&reflect.SliceHeader{
+		Data: uintptr(unsafe.Pointer(info.aConstraintUsage)),
+		Len:  int(info.nConstraint),
+		Cap:  int(info.nConstraint),
+	}))
+	index := 1
+	for i := range slice {
+		if res.Used[i] {
+			slice[i].argvIndex = C.int(index)
+			slice[i].omit = C.uchar(1)
+			index++
+		}
+	}
+
+	info.idxNum = C.int(res.IdxNum)
+	idxStr := C.CString(res.IdxStr)
+	defer C.free(unsafe.Pointer(idxStr))
+	info.idxStr = idxStr
+	info.needToFreeIdxStr = C.int(0)
+	if res.AlreadyOrdered {
+		info.orderByConsumed = C.int(1)
+	}
+	info.estimatedCost = C.double(res.EstimatedCost)
+	info.estimatedRows = C.sqlite3_int64(res.EstimatedRows)
+
+	return nil
+}
+
+//export goVClose
+func goVClose(pCursor unsafe.Pointer) *C.char {
+	vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
+	err := vtc.vTabCursor.Close()
+	if err != nil {
+		return mPrintf("%s", err.Error())
+	}
+	return nil
+}
+
+//export goMDestroy
+func goMDestroy(pClientData unsafe.Pointer) {
+	m := lookupHandle(pClientData).(*sqliteModule)
+	m.module.DestroyModule()
+}
+
+//export goVFilter
+func goVFilter(pCursor unsafe.Pointer, idxNum C.int, idxName *C.char, argc C.int, argv **C.sqlite3_value) *C.char {
+	vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
+	args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc]
+	vals := make([]interface{}, 0, argc)
+	for _, v := range args {
+		conv, err := callbackArgGeneric(v)
+		if err != nil {
+			return mPrintf("%s", err.Error())
+		}
+		vals = append(vals, conv.Interface())
+	}
+	err := vtc.vTabCursor.Filter(int(idxNum), C.GoString(idxName), vals)
+	if err != nil {
+		return mPrintf("%s", err.Error())
+	}
+	return nil
+}
+
+//export goVNext
+func goVNext(pCursor unsafe.Pointer) *C.char {
+	vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
+	err := vtc.vTabCursor.Next()
+	if err != nil {
+		return mPrintf("%s", err.Error())
+	}
+	return nil
+}
+
+//export goVEof
+func goVEof(pCursor unsafe.Pointer) C.int {
+	vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
+	err := vtc.vTabCursor.EOF()
+	if err {
+		return 1
+	}
+	return 0
+}
+
+//export goVColumn
+func goVColumn(pCursor, cp unsafe.Pointer, col C.int) *C.char {
+	vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
+	c := (*SQLiteContext)(cp)
+	err := vtc.vTabCursor.Column(c, int(col))
+	if err != nil {
+		return mPrintf("%s", err.Error())
+	}
+	return nil
+}
+
+//export goVRowid
+func goVRowid(pCursor unsafe.Pointer, pRowid *C.sqlite3_int64) *C.char {
+	vtc := lookupHandle(pCursor).(*sqliteVTabCursor)
+	rowid, err := vtc.vTabCursor.Rowid()
+	if err != nil {
+		return mPrintf("%s", err.Error())
+	}
+	*pRowid = C.sqlite3_int64(rowid)
+	return nil
+}
+
+//export goVUpdate
+func goVUpdate(pVTab unsafe.Pointer, argc C.int, argv **C.sqlite3_value, pRowid *C.sqlite3_int64) *C.char {
+	vt := lookupHandle(pVTab).(*sqliteVTab)
+
+	var tname string
+	if n, ok := vt.vTab.(interface {
+		TableName() string
+	}); ok {
+		tname = n.TableName() + " "
+	}
+
+	err := fmt.Errorf("virtual %s table %sis read-only", vt.module.name, tname)
+	if v, ok := vt.vTab.(VTabUpdater); ok {
+		// convert argv
+		args := (*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.sqlite3_value)(nil))]*C.sqlite3_value)(unsafe.Pointer(argv))[:argc:argc]
+		vals := make([]interface{}, 0, argc)
+		for _, v := range args {
+			conv, err := callbackArgGeneric(v)
+			if err != nil {
+				return mPrintf("%s", err.Error())
+			}
+
+			// work around for SQLITE_NULL
+			x := conv.Interface()
+			if z, ok := x.([]byte); ok && z == nil {
+				x = nil
+			}
+
+			vals = append(vals, x)
+		}
+
+		switch {
+		case argc == 1:
+			err = v.Delete(vals[0])
+
+		case argc > 1 && vals[0] == nil:
+			var id int64
+			id, err = v.Insert(vals[1], vals[2:])
+			if err == nil {
+				*pRowid = C.sqlite3_int64(id)
+			}
+
+		case argc > 1:
+			err = v.Update(vals[1], vals[2:])
+		}
+	}
+
+	if err != nil {
+		return mPrintf("%s", err.Error())
+	}
+
+	return nil
+}
+
+// Module is a "virtual table module", it defines the implementation of a
+// virtual tables. See: http://sqlite.org/c3ref/module.html
+type Module interface {
+	// http://sqlite.org/vtab.html#xcreate
+	Create(c *SQLiteConn, args []string) (VTab, error)
+	// http://sqlite.org/vtab.html#xconnect
+	Connect(c *SQLiteConn, args []string) (VTab, error)
+	// http://sqlite.org/c3ref/create_module.html
+	DestroyModule()
+}
+
+// EponymousOnlyModule is a "virtual table module" (as above), but
+// for defining "eponymous only" virtual tables See: https://sqlite.org/vtab.html#eponymous_only_virtual_tables
+type EponymousOnlyModule interface {
+	Module
+	EponymousOnlyModule()
+}
+
+// VTab describes a particular instance of the virtual table.
+// See: http://sqlite.org/c3ref/vtab.html
+type VTab interface {
+	// http://sqlite.org/vtab.html#xbestindex
+	BestIndex([]InfoConstraint, []InfoOrderBy) (*IndexResult, error)
+	// http://sqlite.org/vtab.html#xdisconnect
+	Disconnect() error
+	// http://sqlite.org/vtab.html#sqlite3_module.xDestroy
+	Destroy() error
+	// http://sqlite.org/vtab.html#xopen
+	Open() (VTabCursor, error)
+}
+
+// VTabUpdater is a type that allows a VTab to be inserted, updated, or
+// deleted.
+// See: https://sqlite.org/vtab.html#xupdate
+type VTabUpdater interface {
+	Delete(interface{}) error
+	Insert(interface{}, []interface{}) (int64, error)
+	Update(interface{}, []interface{}) error
+}
+
+// VTabCursor describes cursors that point into the virtual table and are used
+// to loop through the virtual table. See: http://sqlite.org/c3ref/vtab_cursor.html
+type VTabCursor interface {
+	// http://sqlite.org/vtab.html#xclose
+	Close() error
+	// http://sqlite.org/vtab.html#xfilter
+	Filter(idxNum int, idxStr string, vals []interface{}) error
+	// http://sqlite.org/vtab.html#xnext
+	Next() error
+	// http://sqlite.org/vtab.html#xeof
+	EOF() bool
+	// http://sqlite.org/vtab.html#xcolumn
+	Column(c *SQLiteContext, col int) error
+	// http://sqlite.org/vtab.html#xrowid
+	Rowid() (int64, error)
+}
+
+// DeclareVTab declares the Schema of a virtual table.
+// See: http://sqlite.org/c3ref/declare_vtab.html
+func (c *SQLiteConn) DeclareVTab(sql string) error {
+	zSQL := C.CString(sql)
+	defer C.free(unsafe.Pointer(zSQL))
+	rv := C.sqlite3_declare_vtab(c.db, zSQL)
+	if rv != C.SQLITE_OK {
+		return c.lastError()
+	}
+	return nil
+}
+
+// CreateModule registers a virtual table implementation.
+// See: http://sqlite.org/c3ref/create_module.html
+func (c *SQLiteConn) CreateModule(moduleName string, module Module) error {
+	mname := C.CString(moduleName)
+	defer C.free(unsafe.Pointer(mname))
+	udm := sqliteModule{c, moduleName, module}
+	switch module.(type) {
+	case EponymousOnlyModule:
+		rv := C._sqlite3_create_module_eponymous_only(c.db, mname, C.uintptr_t(uintptr(newHandle(c, &udm))))
+		if rv != C.SQLITE_OK {
+			return c.lastError()
+		}
+		return nil
+	case Module:
+		rv := C._sqlite3_create_module(c.db, mname, C.uintptr_t(uintptr(newHandle(c, &udm))))
+		if rv != C.SQLITE_OK {
+			return c.lastError()
+		}
+		return nil
+	}
+	return nil
+}

+ 17 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_other.go

@@ -0,0 +1,17 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build !windows
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -I.
+#cgo linux LDFLAGS: -ldl
+#cgo linux,ppc LDFLAGS: -lpthread
+#cgo linux,ppc64 LDFLAGS: -lpthread
+#cgo linux,ppc64le LDFLAGS: -lpthread
+*/
+import "C"

+ 14 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_solaris.go

@@ -0,0 +1,14 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build solaris
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -D__EXTENSIONS__=1
+#cgo LDFLAGS: -lc
+*/
+import "C"

+ 287 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_trace.go

@@ -0,0 +1,287 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build sqlite_trace trace
+
+package sqlite3
+
+/*
+#ifndef USE_LIBSQLITE3
+#include <sqlite3-binding.h>
+#else
+#include <sqlite3.h>
+#endif
+#include <stdlib.h>
+
+int traceCallbackTrampoline(unsigned int traceEventCode, void *ctx, void *p, void *x);
+*/
+import "C"
+
+import (
+	"fmt"
+	"strings"
+	"sync"
+	"unsafe"
+)
+
+// Trace... constants identify the possible events causing callback invocation.
+// Values are same as the corresponding SQLite Trace Event Codes.
+const (
+	TraceStmt    = uint32(C.SQLITE_TRACE_STMT)
+	TraceProfile = uint32(C.SQLITE_TRACE_PROFILE)
+	TraceRow     = uint32(C.SQLITE_TRACE_ROW)
+	TraceClose   = uint32(C.SQLITE_TRACE_CLOSE)
+)
+
+type TraceInfo struct {
+	// Pack together the shorter fields, to keep the struct smaller.
+	// On a 64-bit machine there would be padding
+	// between EventCode and ConnHandle; having AutoCommit here is "free":
+	EventCode  uint32
+	AutoCommit bool
+	ConnHandle uintptr
+
+	// Usually filled, unless EventCode = TraceClose = SQLITE_TRACE_CLOSE:
+	// identifier for a prepared statement:
+	StmtHandle uintptr
+
+	// Two strings filled when EventCode = TraceStmt = SQLITE_TRACE_STMT:
+	// (1) either the unexpanded SQL text of the prepared statement, or
+	//     an SQL comment that indicates the invocation of a trigger;
+	// (2) expanded SQL, if requested and if (1) is not an SQL comment.
+	StmtOrTrigger string
+	ExpandedSQL   string // only if requested (TraceConfig.WantExpandedSQL = true)
+
+	// filled when EventCode = TraceProfile = SQLITE_TRACE_PROFILE:
+	// estimated number of nanoseconds that the prepared statement took to run:
+	RunTimeNanosec int64
+
+	DBError Error
+}
+
+// TraceUserCallback gives the signature for a trace function
+// provided by the user (Go application programmer).
+// SQLite 3.14 documentation (as of September 2, 2016)
+// for SQL Trace Hook = sqlite3_trace_v2():
+// The integer return value from the callback is currently ignored,
+// though this may change in future releases. Callback implementations
+// should return zero to ensure future compatibility.
+type TraceUserCallback func(TraceInfo) int
+
+type TraceConfig struct {
+	Callback        TraceUserCallback
+	EventMask       uint32
+	WantExpandedSQL bool
+}
+
+func fillDBError(dbErr *Error, db *C.sqlite3) {
+	// See SQLiteConn.lastError(), in file 'sqlite3.go' at the time of writing (Sept 5, 2016)
+	dbErr.Code = ErrNo(C.sqlite3_errcode(db))
+	dbErr.ExtendedCode = ErrNoExtended(C.sqlite3_extended_errcode(db))
+	dbErr.err = C.GoString(C.sqlite3_errmsg(db))
+}
+
+func fillExpandedSQL(info *TraceInfo, db *C.sqlite3, pStmt unsafe.Pointer) {
+	if pStmt == nil {
+		panic("No SQLite statement pointer in P arg of trace_v2 callback")
+	}
+
+	expSQLiteCStr := C.sqlite3_expanded_sql((*C.sqlite3_stmt)(pStmt))
+	defer C.sqlite3_free(unsafe.Pointer(expSQLiteCStr))
+	if expSQLiteCStr == nil {
+		fillDBError(&info.DBError, db)
+		return
+	}
+	info.ExpandedSQL = C.GoString(expSQLiteCStr)
+}
+
+//export traceCallbackTrampoline
+func traceCallbackTrampoline(
+	traceEventCode C.uint,
+	// Parameter named 'C' in SQLite docs = Context given at registration:
+	ctx unsafe.Pointer,
+	// Parameter named 'P' in SQLite docs (Primary event data?):
+	p unsafe.Pointer,
+	// Parameter named 'X' in SQLite docs (eXtra event data?):
+	xValue unsafe.Pointer) C.int {
+
+	eventCode := uint32(traceEventCode)
+
+	if ctx == nil {
+		panic(fmt.Sprintf("No context (ev 0x%x)", traceEventCode))
+	}
+
+	contextDB := (*C.sqlite3)(ctx)
+	connHandle := uintptr(ctx)
+
+	var traceConf TraceConfig
+	var found bool
+	if eventCode == TraceClose {
+		// clean up traceMap: 'pop' means get and delete
+		traceConf, found = popTraceMapping(connHandle)
+	} else {
+		traceConf, found = lookupTraceMapping(connHandle)
+	}
+
+	if !found {
+		panic(fmt.Sprintf("Mapping not found for handle 0x%x (ev 0x%x)",
+			connHandle, eventCode))
+	}
+
+	var info TraceInfo
+
+	info.EventCode = eventCode
+	info.AutoCommit = (int(C.sqlite3_get_autocommit(contextDB)) != 0)
+	info.ConnHandle = connHandle
+
+	switch eventCode {
+	case TraceStmt:
+		info.StmtHandle = uintptr(p)
+
+		var xStr string
+		if xValue != nil {
+			xStr = C.GoString((*C.char)(xValue))
+		}
+		info.StmtOrTrigger = xStr
+		if !strings.HasPrefix(xStr, "--") {
+			// Not SQL comment, therefore the current event
+			// is not related to a trigger.
+			// The user might want to receive the expanded SQL;
+			// let's check:
+			if traceConf.WantExpandedSQL {
+				fillExpandedSQL(&info, contextDB, p)
+			}
+		}
+
+	case TraceProfile:
+		info.StmtHandle = uintptr(p)
+
+		if xValue == nil {
+			panic("NULL pointer in X arg of trace_v2 callback for SQLITE_TRACE_PROFILE event")
+		}
+
+		info.RunTimeNanosec = *(*int64)(xValue)
+
+		// sample the error //TODO: is it safe? is it useful?
+		fillDBError(&info.DBError, contextDB)
+
+	case TraceRow:
+		info.StmtHandle = uintptr(p)
+
+	case TraceClose:
+		handle := uintptr(p)
+		if handle != info.ConnHandle {
+			panic(fmt.Sprintf("Different conn handle 0x%x (expected 0x%x) in SQLITE_TRACE_CLOSE event.",
+				handle, info.ConnHandle))
+		}
+
+	default:
+		// Pass unsupported events to the user callback (if configured);
+		// let the user callback decide whether to panic or ignore them.
+	}
+
+	// Do not execute user callback when the event was not requested by user!
+	// Remember that the Close event is always selected when
+	// registering this callback trampoline with SQLite --- for cleanup.
+	// In the future there may be more events forced to "selected" in SQLite
+	// for the driver's needs.
+	if traceConf.EventMask&eventCode == 0 {
+		return 0
+	}
+
+	r := 0
+	if traceConf.Callback != nil {
+		r = traceConf.Callback(info)
+	}
+	return C.int(r)
+}
+
+type traceMapEntry struct {
+	config TraceConfig
+}
+
+var traceMapLock sync.Mutex
+var traceMap = make(map[uintptr]traceMapEntry)
+
+func addTraceMapping(connHandle uintptr, traceConf TraceConfig) {
+	traceMapLock.Lock()
+	defer traceMapLock.Unlock()
+
+	oldEntryCopy, found := traceMap[connHandle]
+	if found {
+		panic(fmt.Sprintf("Adding trace config %v: handle 0x%x already registered (%v).",
+			traceConf, connHandle, oldEntryCopy.config))
+	}
+	traceMap[connHandle] = traceMapEntry{config: traceConf}
+}
+
+func lookupTraceMapping(connHandle uintptr) (TraceConfig, bool) {
+	traceMapLock.Lock()
+	defer traceMapLock.Unlock()
+
+	entryCopy, found := traceMap[connHandle]
+	return entryCopy.config, found
+}
+
+// 'pop' = get and delete from map before returning the value to the caller
+func popTraceMapping(connHandle uintptr) (TraceConfig, bool) {
+	traceMapLock.Lock()
+	defer traceMapLock.Unlock()
+
+	entryCopy, found := traceMap[connHandle]
+	if found {
+		delete(traceMap, connHandle)
+	}
+	return entryCopy.config, found
+}
+
+// SetTrace installs or removes the trace callback for the given database connection.
+// It's not named 'RegisterTrace' because only one callback can be kept and called.
+// Calling SetTrace a second time on same database connection
+// overrides (cancels) any prior callback and all its settings:
+// event mask, etc.
+func (c *SQLiteConn) SetTrace(requested *TraceConfig) error {
+	connHandle := uintptr(unsafe.Pointer(c.db))
+
+	_, _ = popTraceMapping(connHandle)
+
+	if requested == nil {
+		// The traceMap entry was deleted already by popTraceMapping():
+		// can disable all events now, no need to watch for TraceClose.
+		err := c.setSQLiteTrace(0)
+		return err
+	}
+
+	reqCopy := *requested
+
+	// Disable potentially expensive operations
+	// if their result will not be used. We are doing this
+	// just in case the caller provided nonsensical input.
+	if reqCopy.EventMask&TraceStmt == 0 {
+		reqCopy.WantExpandedSQL = false
+	}
+
+	addTraceMapping(connHandle, reqCopy)
+
+	// The callback trampoline function does cleanup on Close event,
+	// regardless of the presence or absence of the user callback.
+	// Therefore it needs the Close event to be selected:
+	actualEventMask := uint(reqCopy.EventMask | TraceClose)
+	err := c.setSQLiteTrace(actualEventMask)
+	return err
+}
+
+func (c *SQLiteConn) setSQLiteTrace(sqliteEventMask uint) error {
+	rv := C.sqlite3_trace_v2(c.db,
+		C.uint(sqliteEventMask),
+		(*[0]byte)(unsafe.Pointer(C.traceCallbackTrampoline)),
+		unsafe.Pointer(c.db)) // Fourth arg is same as first: we are
+	// passing the database connection handle as callback context.
+
+	if rv != C.SQLITE_OK {
+		return c.lastError()
+	}
+	return nil
+}

+ 62 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_type.go

@@ -0,0 +1,62 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+package sqlite3
+
+/*
+#ifndef USE_LIBSQLITE3
+#include <sqlite3-binding.h>
+#else
+#include <sqlite3.h>
+#endif
+*/
+import "C"
+import (
+	"reflect"
+	"time"
+)
+
+// ColumnTypeDatabaseTypeName implement RowsColumnTypeDatabaseTypeName.
+func (rc *SQLiteRows) ColumnTypeDatabaseTypeName(i int) string {
+	return C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i)))
+}
+
+/*
+func (rc *SQLiteRows) ColumnTypeLength(index int) (length int64, ok bool) {
+	return 0, false
+}
+
+func (rc *SQLiteRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) {
+	return 0, 0, false
+}
+
+// ColumnTypeNullable implement RowsColumnTypeNullable.
+func (rc *SQLiteRows) ColumnTypeNullable(i int) (nullable, ok bool) {
+	return false, false
+}
+*/
+
+// ColumnTypeScanType implement RowsColumnTypeScanType.
+func (rc *SQLiteRows) ColumnTypeScanType(i int) reflect.Type {
+	switch C.sqlite3_column_type(rc.s.s, C.int(i)) {
+	case C.SQLITE_INTEGER:
+		switch C.GoString(C.sqlite3_column_decltype(rc.s.s, C.int(i))) {
+		case "timestamp", "datetime", "date":
+			return reflect.TypeOf(time.Time{})
+		case "boolean":
+			return reflect.TypeOf(false)
+		}
+		return reflect.TypeOf(int64(0))
+	case C.SQLITE_FLOAT:
+		return reflect.TypeOf(float64(0))
+	case C.SQLITE_BLOB:
+		return reflect.SliceOf(reflect.TypeOf(byte(0)))
+	case C.SQLITE_NULL:
+		return reflect.TypeOf(nil)
+	case C.SQLITE_TEXT:
+		return reflect.TypeOf("")
+	}
+	return reflect.SliceOf(reflect.TypeOf(byte(0)))
+}

+ 41 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_usleep_windows.go

@@ -0,0 +1,41 @@
+// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build cgo
+
+package sqlite3
+
+// usleep is a function available on *nix based systems.
+// This function is not present in Windows.
+// Windows has a sleep function but this works with seconds
+// and not with microseconds as usleep.
+//
+// This code should improve performance on windows because
+// without the presence of usleep SQLite waits 1 second.
+//
+// Source:  https://github.com/php/php-src/blob/PHP-5.0/win32/time.c
+// License: https://github.com/php/php-src/blob/PHP-5.0/LICENSE
+// Details: https://stackoverflow.com/questions/5801813/c-usleep-is-obsolete-workarounds-for-windows-mingw?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
+
+/*
+#include <windows.h>
+
+void usleep(__int64 usec)
+{
+    HANDLE timer;
+    LARGE_INTEGER ft;
+
+    // Convert to 100 nanosecond interval, negative value indicates relative time
+    ft.QuadPart = -(10*usec);
+
+    timer = CreateWaitableTimer(NULL, TRUE, NULL);
+    SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
+    WaitForSingleObject(timer, INFINITE);
+    CloseHandle(timer);
+}
+*/
+import "C"
+
+// EOF

+ 18 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3_windows.go

@@ -0,0 +1,18 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build windows
+
+package sqlite3
+
+/*
+#cgo CFLAGS: -I.
+#cgo CFLAGS: -fno-stack-check
+#cgo CFLAGS: -fno-stack-protector
+#cgo CFLAGS: -mno-stack-arg-probe
+#cgo LDFLAGS: -lmingwex -lmingw32
+#cgo windows,386 CFLAGS: -D_USE_32BIT_TIME_T
+*/
+import "C"

+ 668 - 0
vendor/github.com/mattn/go-sqlite3/sqlite3ext.h

@@ -0,0 +1,668 @@
+#ifndef USE_LIBSQLITE3
+/*
+** 2006 June 7
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This header file defines the SQLite interface for use by
+** shared libraries that want to be imported as extensions into
+** an SQLite instance.  Shared libraries that intend to be loaded
+** as extensions by SQLite should #include this file instead of 
+** sqlite3.h.
+*/
+#ifndef SQLITE3EXT_H
+#define SQLITE3EXT_H
+#include "sqlite3-binding.h"
+
+/*
+** The following structure holds pointers to all of the SQLite API
+** routines.
+**
+** WARNING:  In order to maintain backwards compatibility, add new
+** interfaces to the end of this structure only.  If you insert new
+** interfaces in the middle of this structure, then older different
+** versions of SQLite will not be able to load each other's shared
+** libraries!
+*/
+struct sqlite3_api_routines {
+  void * (*aggregate_context)(sqlite3_context*,int nBytes);
+  int  (*aggregate_count)(sqlite3_context*);
+  int  (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*));
+  int  (*bind_double)(sqlite3_stmt*,int,double);
+  int  (*bind_int)(sqlite3_stmt*,int,int);
+  int  (*bind_int64)(sqlite3_stmt*,int,sqlite_int64);
+  int  (*bind_null)(sqlite3_stmt*,int);
+  int  (*bind_parameter_count)(sqlite3_stmt*);
+  int  (*bind_parameter_index)(sqlite3_stmt*,const char*zName);
+  const char * (*bind_parameter_name)(sqlite3_stmt*,int);
+  int  (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*));
+  int  (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*));
+  int  (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*);
+  int  (*busy_handler)(sqlite3*,int(*)(void*,int),void*);
+  int  (*busy_timeout)(sqlite3*,int ms);
+  int  (*changes)(sqlite3*);
+  int  (*close)(sqlite3*);
+  int  (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*,
+                           int eTextRep,const char*));
+  int  (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*,
+                             int eTextRep,const void*));
+  const void * (*column_blob)(sqlite3_stmt*,int iCol);
+  int  (*column_bytes)(sqlite3_stmt*,int iCol);
+  int  (*column_bytes16)(sqlite3_stmt*,int iCol);
+  int  (*column_count)(sqlite3_stmt*pStmt);
+  const char * (*column_database_name)(sqlite3_stmt*,int);
+  const void * (*column_database_name16)(sqlite3_stmt*,int);
+  const char * (*column_decltype)(sqlite3_stmt*,int i);
+  const void * (*column_decltype16)(sqlite3_stmt*,int);
+  double  (*column_double)(sqlite3_stmt*,int iCol);
+  int  (*column_int)(sqlite3_stmt*,int iCol);
+  sqlite_int64  (*column_int64)(sqlite3_stmt*,int iCol);
+  const char * (*column_name)(sqlite3_stmt*,int);
+  const void * (*column_name16)(sqlite3_stmt*,int);
+  const char * (*column_origin_name)(sqlite3_stmt*,int);
+  const void * (*column_origin_name16)(sqlite3_stmt*,int);
+  const char * (*column_table_name)(sqlite3_stmt*,int);
+  const void * (*column_table_name16)(sqlite3_stmt*,int);
+  const unsigned char * (*column_text)(sqlite3_stmt*,int iCol);
+  const void * (*column_text16)(sqlite3_stmt*,int iCol);
+  int  (*column_type)(sqlite3_stmt*,int iCol);
+  sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol);
+  void * (*commit_hook)(sqlite3*,int(*)(void*),void*);
+  int  (*complete)(const char*sql);
+  int  (*complete16)(const void*sql);
+  int  (*create_collation)(sqlite3*,const char*,int,void*,
+                           int(*)(void*,int,const void*,int,const void*));
+  int  (*create_collation16)(sqlite3*,const void*,int,void*,
+                             int(*)(void*,int,const void*,int,const void*));
+  int  (*create_function)(sqlite3*,const char*,int,int,void*,
+                          void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+                          void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+                          void (*xFinal)(sqlite3_context*));
+  int  (*create_function16)(sqlite3*,const void*,int,int,void*,
+                            void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+                            void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+                            void (*xFinal)(sqlite3_context*));
+  int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
+  int  (*data_count)(sqlite3_stmt*pStmt);
+  sqlite3 * (*db_handle)(sqlite3_stmt*);
+  int (*declare_vtab)(sqlite3*,const char*);
+  int  (*enable_shared_cache)(int);
+  int  (*errcode)(sqlite3*db);
+  const char * (*errmsg)(sqlite3*);
+  const void * (*errmsg16)(sqlite3*);
+  int  (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**);
+  int  (*expired)(sqlite3_stmt*);
+  int  (*finalize)(sqlite3_stmt*pStmt);
+  void  (*free)(void*);
+  void  (*free_table)(char**result);
+  int  (*get_autocommit)(sqlite3*);
+  void * (*get_auxdata)(sqlite3_context*,int);
+  int  (*get_table)(sqlite3*,const char*,char***,int*,int*,char**);
+  int  (*global_recover)(void);
+  void  (*interruptx)(sqlite3*);
+  sqlite_int64  (*last_insert_rowid)(sqlite3*);
+  const char * (*libversion)(void);
+  int  (*libversion_number)(void);
+  void *(*malloc)(int);
+  char * (*mprintf)(const char*,...);
+  int  (*open)(const char*,sqlite3**);
+  int  (*open16)(const void*,sqlite3**);
+  int  (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
+  int  (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
+  void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*);
+  void  (*progress_handler)(sqlite3*,int,int(*)(void*),void*);
+  void *(*realloc)(void*,int);
+  int  (*reset)(sqlite3_stmt*pStmt);
+  void  (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*));
+  void  (*result_double)(sqlite3_context*,double);
+  void  (*result_error)(sqlite3_context*,const char*,int);
+  void  (*result_error16)(sqlite3_context*,const void*,int);
+  void  (*result_int)(sqlite3_context*,int);
+  void  (*result_int64)(sqlite3_context*,sqlite_int64);
+  void  (*result_null)(sqlite3_context*);
+  void  (*result_text)(sqlite3_context*,const char*,int,void(*)(void*));
+  void  (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*));
+  void  (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
+  void  (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
+  void  (*result_value)(sqlite3_context*,sqlite3_value*);
+  void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
+  int  (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
+                         const char*,const char*),void*);
+  void  (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
+  char * (*xsnprintf)(int,char*,const char*,...);
+  int  (*step)(sqlite3_stmt*);
+  int  (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
+                                char const**,char const**,int*,int*,int*);
+  void  (*thread_cleanup)(void);
+  int  (*total_changes)(sqlite3*);
+  void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
+  int  (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
+  void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*,
+                                         sqlite_int64),void*);
+  void * (*user_data)(sqlite3_context*);
+  const void * (*value_blob)(sqlite3_value*);
+  int  (*value_bytes)(sqlite3_value*);
+  int  (*value_bytes16)(sqlite3_value*);
+  double  (*value_double)(sqlite3_value*);
+  int  (*value_int)(sqlite3_value*);
+  sqlite_int64  (*value_int64)(sqlite3_value*);
+  int  (*value_numeric_type)(sqlite3_value*);
+  const unsigned char * (*value_text)(sqlite3_value*);
+  const void * (*value_text16)(sqlite3_value*);
+  const void * (*value_text16be)(sqlite3_value*);
+  const void * (*value_text16le)(sqlite3_value*);
+  int  (*value_type)(sqlite3_value*);
+  char *(*vmprintf)(const char*,va_list);
+  /* Added ??? */
+  int (*overload_function)(sqlite3*, const char *zFuncName, int nArg);
+  /* Added by 3.3.13 */
+  int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**);
+  int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**);
+  int (*clear_bindings)(sqlite3_stmt*);
+  /* Added by 3.4.1 */
+  int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*,
+                          void (*xDestroy)(void *));
+  /* Added by 3.5.0 */
+  int (*bind_zeroblob)(sqlite3_stmt*,int,int);
+  int (*blob_bytes)(sqlite3_blob*);
+  int (*blob_close)(sqlite3_blob*);
+  int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64,
+                   int,sqlite3_blob**);
+  int (*blob_read)(sqlite3_blob*,void*,int,int);
+  int (*blob_write)(sqlite3_blob*,const void*,int,int);
+  int (*create_collation_v2)(sqlite3*,const char*,int,void*,
+                             int(*)(void*,int,const void*,int,const void*),
+                             void(*)(void*));
+  int (*file_control)(sqlite3*,const char*,int,void*);
+  sqlite3_int64 (*memory_highwater)(int);
+  sqlite3_int64 (*memory_used)(void);
+  sqlite3_mutex *(*mutex_alloc)(int);
+  void (*mutex_enter)(sqlite3_mutex*);
+  void (*mutex_free)(sqlite3_mutex*);
+  void (*mutex_leave)(sqlite3_mutex*);
+  int (*mutex_try)(sqlite3_mutex*);
+  int (*open_v2)(const char*,sqlite3**,int,const char*);
+  int (*release_memory)(int);
+  void (*result_error_nomem)(sqlite3_context*);
+  void (*result_error_toobig)(sqlite3_context*);
+  int (*sleep)(int);
+  void (*soft_heap_limit)(int);
+  sqlite3_vfs *(*vfs_find)(const char*);
+  int (*vfs_register)(sqlite3_vfs*,int);
+  int (*vfs_unregister)(sqlite3_vfs*);
+  int (*xthreadsafe)(void);
+  void (*result_zeroblob)(sqlite3_context*,int);
+  void (*result_error_code)(sqlite3_context*,int);
+  int (*test_control)(int, ...);
+  void (*randomness)(int,void*);
+  sqlite3 *(*context_db_handle)(sqlite3_context*);
+  int (*extended_result_codes)(sqlite3*,int);
+  int (*limit)(sqlite3*,int,int);
+  sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
+  const char *(*sql)(sqlite3_stmt*);
+  int (*status)(int,int*,int*,int);
+  int (*backup_finish)(sqlite3_backup*);
+  sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
+  int (*backup_pagecount)(sqlite3_backup*);
+  int (*backup_remaining)(sqlite3_backup*);
+  int (*backup_step)(sqlite3_backup*,int);
+  const char *(*compileoption_get)(int);
+  int (*compileoption_used)(const char*);
+  int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
+                            void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
+                            void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+                            void (*xFinal)(sqlite3_context*),
+                            void(*xDestroy)(void*));
+  int (*db_config)(sqlite3*,int,...);
+  sqlite3_mutex *(*db_mutex)(sqlite3*);
+  int (*db_status)(sqlite3*,int,int*,int*,int);
+  int (*extended_errcode)(sqlite3*);
+  void (*log)(int,const char*,...);
+  sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64);
+  const char *(*sourceid)(void);
+  int (*stmt_status)(sqlite3_stmt*,int,int);
+  int (*strnicmp)(const char*,const char*,int);
+  int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*);
+  int (*wal_autocheckpoint)(sqlite3*,int);
+  int (*wal_checkpoint)(sqlite3*,const char*);
+  void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
+  int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
+  int (*vtab_config)(sqlite3*,int op,...);
+  int (*vtab_on_conflict)(sqlite3*);
+  /* Version 3.7.16 and later */
+  int (*close_v2)(sqlite3*);
+  const char *(*db_filename)(sqlite3*,const char*);
+  int (*db_readonly)(sqlite3*,const char*);
+  int (*db_release_memory)(sqlite3*);
+  const char *(*errstr)(int);
+  int (*stmt_busy)(sqlite3_stmt*);
+  int (*stmt_readonly)(sqlite3_stmt*);
+  int (*stricmp)(const char*,const char*);
+  int (*uri_boolean)(const char*,const char*,int);
+  sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
+  const char *(*uri_parameter)(const char*,const char*);
+  char *(*xvsnprintf)(int,char*,const char*,va_list);
+  int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
+  /* Version 3.8.7 and later */
+  int (*auto_extension)(void(*)(void));
+  int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
+                     void(*)(void*));
+  int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
+                      void(*)(void*),unsigned char);
+  int (*cancel_auto_extension)(void(*)(void));
+  int (*load_extension)(sqlite3*,const char*,const char*,char**);
+  void *(*malloc64)(sqlite3_uint64);
+  sqlite3_uint64 (*msize)(void*);
+  void *(*realloc64)(void*,sqlite3_uint64);
+  void (*reset_auto_extension)(void);
+  void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
+                        void(*)(void*));
+  void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
+                         void(*)(void*), unsigned char);
+  int (*strglob)(const char*,const char*);
+  /* Version 3.8.11 and later */
+  sqlite3_value *(*value_dup)(const sqlite3_value*);
+  void (*value_free)(sqlite3_value*);
+  int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
+  int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
+  /* Version 3.9.0 and later */
+  unsigned int (*value_subtype)(sqlite3_value*);
+  void (*result_subtype)(sqlite3_context*,unsigned int);
+  /* Version 3.10.0 and later */
+  int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
+  int (*strlike)(const char*,const char*,unsigned int);
+  int (*db_cacheflush)(sqlite3*);
+  /* Version 3.12.0 and later */
+  int (*system_errno)(sqlite3*);
+  /* Version 3.14.0 and later */
+  int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
+  char *(*expanded_sql)(sqlite3_stmt*);
+  /* Version 3.18.0 and later */
+  void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
+  /* Version 3.20.0 and later */
+  int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
+                    sqlite3_stmt**,const char**);
+  int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
+                      sqlite3_stmt**,const void**);
+  int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
+  void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
+  void *(*value_pointer)(sqlite3_value*,const char*);
+  int (*vtab_nochange)(sqlite3_context*);
+  int (*value_nochange)(sqlite3_value*);
+  const char *(*vtab_collation)(sqlite3_index_info*,int);
+  /* Version 3.24.0 and later */
+  int (*keyword_count)(void);
+  int (*keyword_name)(int,const char**,int*);
+  int (*keyword_check)(const char*,int);
+  sqlite3_str *(*str_new)(sqlite3*);
+  char *(*str_finish)(sqlite3_str*);
+  void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
+  void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
+  void (*str_append)(sqlite3_str*, const char *zIn, int N);
+  void (*str_appendall)(sqlite3_str*, const char *zIn);
+  void (*str_appendchar)(sqlite3_str*, int N, char C);
+  void (*str_reset)(sqlite3_str*);
+  int (*str_errcode)(sqlite3_str*);
+  int (*str_length)(sqlite3_str*);
+  char *(*str_value)(sqlite3_str*);
+  /* Version 3.25.0 and later */
+  int (*create_window_function)(sqlite3*,const char*,int,int,void*,
+                            void (*xStep)(sqlite3_context*,int,sqlite3_value**),
+                            void (*xFinal)(sqlite3_context*),
+                            void (*xValue)(sqlite3_context*),
+                            void (*xInv)(sqlite3_context*,int,sqlite3_value**),
+                            void(*xDestroy)(void*));
+  /* Version 3.26.0 and later */
+  const char *(*normalized_sql)(sqlite3_stmt*);
+  /* Version 3.28.0 and later */
+  int (*stmt_isexplain)(sqlite3_stmt*);
+  int (*value_frombind)(sqlite3_value*);
+  /* Version 3.30.0 and later */
+  int (*drop_modules)(sqlite3*,const char**);
+  /* Version 3.31.0 and later */
+  sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
+  const char *(*uri_key)(const char*,int);
+  const char *(*filename_database)(const char*);
+  const char *(*filename_journal)(const char*);
+  const char *(*filename_wal)(const char*);
+  /* Version 3.32.0 and later */
+  char *(*create_filename)(const char*,const char*,const char*,
+                           int,const char**);
+  void (*free_filename)(char*);
+  sqlite3_file *(*database_file_object)(const char*);
+  /* Version 3.34.0 and later */
+  int (*txn_state)(sqlite3*,const char*);
+};
+
+/*
+** This is the function signature used for all extension entry points.  It
+** is also defined in the file "loadext.c".
+*/
+typedef int (*sqlite3_loadext_entry)(
+  sqlite3 *db,                       /* Handle to the database. */
+  char **pzErrMsg,                   /* Used to set error string on failure. */
+  const sqlite3_api_routines *pThunk /* Extension API function pointers. */
+);
+
+/*
+** The following macros redefine the API routines so that they are
+** redirected through the global sqlite3_api structure.
+**
+** This header file is also used by the loadext.c source file
+** (part of the main SQLite library - not an extension) so that
+** it can get access to the sqlite3_api_routines structure
+** definition.  But the main library does not want to redefine
+** the API.  So the redefinition macros are only valid if the
+** SQLITE_CORE macros is undefined.
+*/
+#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+#define sqlite3_aggregate_context      sqlite3_api->aggregate_context
+#ifndef SQLITE_OMIT_DEPRECATED
+#define sqlite3_aggregate_count        sqlite3_api->aggregate_count
+#endif
+#define sqlite3_bind_blob              sqlite3_api->bind_blob
+#define sqlite3_bind_double            sqlite3_api->bind_double
+#define sqlite3_bind_int               sqlite3_api->bind_int
+#define sqlite3_bind_int64             sqlite3_api->bind_int64
+#define sqlite3_bind_null              sqlite3_api->bind_null
+#define sqlite3_bind_parameter_count   sqlite3_api->bind_parameter_count
+#define sqlite3_bind_parameter_index   sqlite3_api->bind_parameter_index
+#define sqlite3_bind_parameter_name    sqlite3_api->bind_parameter_name
+#define sqlite3_bind_text              sqlite3_api->bind_text
+#define sqlite3_bind_text16            sqlite3_api->bind_text16
+#define sqlite3_bind_value             sqlite3_api->bind_value
+#define sqlite3_busy_handler           sqlite3_api->busy_handler
+#define sqlite3_busy_timeout           sqlite3_api->busy_timeout
+#define sqlite3_changes                sqlite3_api->changes
+#define sqlite3_close                  sqlite3_api->close
+#define sqlite3_collation_needed       sqlite3_api->collation_needed
+#define sqlite3_collation_needed16     sqlite3_api->collation_needed16
+#define sqlite3_column_blob            sqlite3_api->column_blob
+#define sqlite3_column_bytes           sqlite3_api->column_bytes
+#define sqlite3_column_bytes16         sqlite3_api->column_bytes16
+#define sqlite3_column_count           sqlite3_api->column_count
+#define sqlite3_column_database_name   sqlite3_api->column_database_name
+#define sqlite3_column_database_name16 sqlite3_api->column_database_name16
+#define sqlite3_column_decltype        sqlite3_api->column_decltype
+#define sqlite3_column_decltype16      sqlite3_api->column_decltype16
+#define sqlite3_column_double          sqlite3_api->column_double
+#define sqlite3_column_int             sqlite3_api->column_int
+#define sqlite3_column_int64           sqlite3_api->column_int64
+#define sqlite3_column_name            sqlite3_api->column_name
+#define sqlite3_column_name16          sqlite3_api->column_name16
+#define sqlite3_column_origin_name     sqlite3_api->column_origin_name
+#define sqlite3_column_origin_name16   sqlite3_api->column_origin_name16
+#define sqlite3_column_table_name      sqlite3_api->column_table_name
+#define sqlite3_column_table_name16    sqlite3_api->column_table_name16
+#define sqlite3_column_text            sqlite3_api->column_text
+#define sqlite3_column_text16          sqlite3_api->column_text16
+#define sqlite3_column_type            sqlite3_api->column_type
+#define sqlite3_column_value           sqlite3_api->column_value
+#define sqlite3_commit_hook            sqlite3_api->commit_hook
+#define sqlite3_complete               sqlite3_api->complete
+#define sqlite3_complete16             sqlite3_api->complete16
+#define sqlite3_create_collation       sqlite3_api->create_collation
+#define sqlite3_create_collation16     sqlite3_api->create_collation16
+#define sqlite3_create_function        sqlite3_api->create_function
+#define sqlite3_create_function16      sqlite3_api->create_function16
+#define sqlite3_create_module          sqlite3_api->create_module
+#define sqlite3_create_module_v2       sqlite3_api->create_module_v2
+#define sqlite3_data_count             sqlite3_api->data_count
+#define sqlite3_db_handle              sqlite3_api->db_handle
+#define sqlite3_declare_vtab           sqlite3_api->declare_vtab
+#define sqlite3_enable_shared_cache    sqlite3_api->enable_shared_cache
+#define sqlite3_errcode                sqlite3_api->errcode
+#define sqlite3_errmsg                 sqlite3_api->errmsg
+#define sqlite3_errmsg16               sqlite3_api->errmsg16
+#define sqlite3_exec                   sqlite3_api->exec
+#ifndef SQLITE_OMIT_DEPRECATED
+#define sqlite3_expired                sqlite3_api->expired
+#endif
+#define sqlite3_finalize               sqlite3_api->finalize
+#define sqlite3_free                   sqlite3_api->free
+#define sqlite3_free_table             sqlite3_api->free_table
+#define sqlite3_get_autocommit         sqlite3_api->get_autocommit
+#define sqlite3_get_auxdata            sqlite3_api->get_auxdata
+#define sqlite3_get_table              sqlite3_api->get_table
+#ifndef SQLITE_OMIT_DEPRECATED
+#define sqlite3_global_recover         sqlite3_api->global_recover
+#endif
+#define sqlite3_interrupt              sqlite3_api->interruptx
+#define sqlite3_last_insert_rowid      sqlite3_api->last_insert_rowid
+#define sqlite3_libversion             sqlite3_api->libversion
+#define sqlite3_libversion_number      sqlite3_api->libversion_number
+#define sqlite3_malloc                 sqlite3_api->malloc
+#define sqlite3_mprintf                sqlite3_api->mprintf
+#define sqlite3_open                   sqlite3_api->open
+#define sqlite3_open16                 sqlite3_api->open16
+#define sqlite3_prepare                sqlite3_api->prepare
+#define sqlite3_prepare16              sqlite3_api->prepare16
+#define sqlite3_prepare_v2             sqlite3_api->prepare_v2
+#define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2
+#define sqlite3_profile                sqlite3_api->profile
+#define sqlite3_progress_handler       sqlite3_api->progress_handler
+#define sqlite3_realloc                sqlite3_api->realloc
+#define sqlite3_reset                  sqlite3_api->reset
+#define sqlite3_result_blob            sqlite3_api->result_blob
+#define sqlite3_result_double          sqlite3_api->result_double
+#define sqlite3_result_error           sqlite3_api->result_error
+#define sqlite3_result_error16         sqlite3_api->result_error16
+#define sqlite3_result_int             sqlite3_api->result_int
+#define sqlite3_result_int64           sqlite3_api->result_int64
+#define sqlite3_result_null            sqlite3_api->result_null
+#define sqlite3_result_text            sqlite3_api->result_text
+#define sqlite3_result_text16          sqlite3_api->result_text16
+#define sqlite3_result_text16be        sqlite3_api->result_text16be
+#define sqlite3_result_text16le        sqlite3_api->result_text16le
+#define sqlite3_result_value           sqlite3_api->result_value
+#define sqlite3_rollback_hook          sqlite3_api->rollback_hook
+#define sqlite3_set_authorizer         sqlite3_api->set_authorizer
+#define sqlite3_set_auxdata            sqlite3_api->set_auxdata
+#define sqlite3_snprintf               sqlite3_api->xsnprintf
+#define sqlite3_step                   sqlite3_api->step
+#define sqlite3_table_column_metadata  sqlite3_api->table_column_metadata
+#define sqlite3_thread_cleanup         sqlite3_api->thread_cleanup
+#define sqlite3_total_changes          sqlite3_api->total_changes
+#define sqlite3_trace                  sqlite3_api->trace
+#ifndef SQLITE_OMIT_DEPRECATED
+#define sqlite3_transfer_bindings      sqlite3_api->transfer_bindings
+#endif
+#define sqlite3_update_hook            sqlite3_api->update_hook
+#define sqlite3_user_data              sqlite3_api->user_data
+#define sqlite3_value_blob             sqlite3_api->value_blob
+#define sqlite3_value_bytes            sqlite3_api->value_bytes
+#define sqlite3_value_bytes16          sqlite3_api->value_bytes16
+#define sqlite3_value_double           sqlite3_api->value_double
+#define sqlite3_value_int              sqlite3_api->value_int
+#define sqlite3_value_int64            sqlite3_api->value_int64
+#define sqlite3_value_numeric_type     sqlite3_api->value_numeric_type
+#define sqlite3_value_text             sqlite3_api->value_text
+#define sqlite3_value_text16           sqlite3_api->value_text16
+#define sqlite3_value_text16be         sqlite3_api->value_text16be
+#define sqlite3_value_text16le         sqlite3_api->value_text16le
+#define sqlite3_value_type             sqlite3_api->value_type
+#define sqlite3_vmprintf               sqlite3_api->vmprintf
+#define sqlite3_vsnprintf              sqlite3_api->xvsnprintf
+#define sqlite3_overload_function      sqlite3_api->overload_function
+#define sqlite3_prepare_v2             sqlite3_api->prepare_v2
+#define sqlite3_prepare16_v2           sqlite3_api->prepare16_v2
+#define sqlite3_clear_bindings         sqlite3_api->clear_bindings
+#define sqlite3_bind_zeroblob          sqlite3_api->bind_zeroblob
+#define sqlite3_blob_bytes             sqlite3_api->blob_bytes
+#define sqlite3_blob_close             sqlite3_api->blob_close
+#define sqlite3_blob_open              sqlite3_api->blob_open
+#define sqlite3_blob_read              sqlite3_api->blob_read
+#define sqlite3_blob_write             sqlite3_api->blob_write
+#define sqlite3_create_collation_v2    sqlite3_api->create_collation_v2
+#define sqlite3_file_control           sqlite3_api->file_control
+#define sqlite3_memory_highwater       sqlite3_api->memory_highwater
+#define sqlite3_memory_used            sqlite3_api->memory_used
+#define sqlite3_mutex_alloc            sqlite3_api->mutex_alloc
+#define sqlite3_mutex_enter            sqlite3_api->mutex_enter
+#define sqlite3_mutex_free             sqlite3_api->mutex_free
+#define sqlite3_mutex_leave            sqlite3_api->mutex_leave
+#define sqlite3_mutex_try              sqlite3_api->mutex_try
+#define sqlite3_open_v2                sqlite3_api->open_v2
+#define sqlite3_release_memory         sqlite3_api->release_memory
+#define sqlite3_result_error_nomem     sqlite3_api->result_error_nomem
+#define sqlite3_result_error_toobig    sqlite3_api->result_error_toobig
+#define sqlite3_sleep                  sqlite3_api->sleep
+#define sqlite3_soft_heap_limit        sqlite3_api->soft_heap_limit
+#define sqlite3_vfs_find               sqlite3_api->vfs_find
+#define sqlite3_vfs_register           sqlite3_api->vfs_register
+#define sqlite3_vfs_unregister         sqlite3_api->vfs_unregister
+#define sqlite3_threadsafe             sqlite3_api->xthreadsafe
+#define sqlite3_result_zeroblob        sqlite3_api->result_zeroblob
+#define sqlite3_result_error_code      sqlite3_api->result_error_code
+#define sqlite3_test_control           sqlite3_api->test_control
+#define sqlite3_randomness             sqlite3_api->randomness
+#define sqlite3_context_db_handle      sqlite3_api->context_db_handle
+#define sqlite3_extended_result_codes  sqlite3_api->extended_result_codes
+#define sqlite3_limit                  sqlite3_api->limit
+#define sqlite3_next_stmt              sqlite3_api->next_stmt
+#define sqlite3_sql                    sqlite3_api->sql
+#define sqlite3_status                 sqlite3_api->status
+#define sqlite3_backup_finish          sqlite3_api->backup_finish
+#define sqlite3_backup_init            sqlite3_api->backup_init
+#define sqlite3_backup_pagecount       sqlite3_api->backup_pagecount
+#define sqlite3_backup_remaining       sqlite3_api->backup_remaining
+#define sqlite3_backup_step            sqlite3_api->backup_step
+#define sqlite3_compileoption_get      sqlite3_api->compileoption_get
+#define sqlite3_compileoption_used     sqlite3_api->compileoption_used
+#define sqlite3_create_function_v2     sqlite3_api->create_function_v2
+#define sqlite3_db_config              sqlite3_api->db_config
+#define sqlite3_db_mutex               sqlite3_api->db_mutex
+#define sqlite3_db_status              sqlite3_api->db_status
+#define sqlite3_extended_errcode       sqlite3_api->extended_errcode
+#define sqlite3_log                    sqlite3_api->log
+#define sqlite3_soft_heap_limit64      sqlite3_api->soft_heap_limit64
+#define sqlite3_sourceid               sqlite3_api->sourceid
+#define sqlite3_stmt_status            sqlite3_api->stmt_status
+#define sqlite3_strnicmp               sqlite3_api->strnicmp
+#define sqlite3_unlock_notify          sqlite3_api->unlock_notify
+#define sqlite3_wal_autocheckpoint     sqlite3_api->wal_autocheckpoint
+#define sqlite3_wal_checkpoint         sqlite3_api->wal_checkpoint
+#define sqlite3_wal_hook               sqlite3_api->wal_hook
+#define sqlite3_blob_reopen            sqlite3_api->blob_reopen
+#define sqlite3_vtab_config            sqlite3_api->vtab_config
+#define sqlite3_vtab_on_conflict       sqlite3_api->vtab_on_conflict
+/* Version 3.7.16 and later */
+#define sqlite3_close_v2               sqlite3_api->close_v2
+#define sqlite3_db_filename            sqlite3_api->db_filename
+#define sqlite3_db_readonly            sqlite3_api->db_readonly
+#define sqlite3_db_release_memory      sqlite3_api->db_release_memory
+#define sqlite3_errstr                 sqlite3_api->errstr
+#define sqlite3_stmt_busy              sqlite3_api->stmt_busy
+#define sqlite3_stmt_readonly          sqlite3_api->stmt_readonly
+#define sqlite3_stricmp                sqlite3_api->stricmp
+#define sqlite3_uri_boolean            sqlite3_api->uri_boolean
+#define sqlite3_uri_int64              sqlite3_api->uri_int64
+#define sqlite3_uri_parameter          sqlite3_api->uri_parameter
+#define sqlite3_uri_vsnprintf          sqlite3_api->xvsnprintf
+#define sqlite3_wal_checkpoint_v2      sqlite3_api->wal_checkpoint_v2
+/* Version 3.8.7 and later */
+#define sqlite3_auto_extension         sqlite3_api->auto_extension
+#define sqlite3_bind_blob64            sqlite3_api->bind_blob64
+#define sqlite3_bind_text64            sqlite3_api->bind_text64
+#define sqlite3_cancel_auto_extension  sqlite3_api->cancel_auto_extension
+#define sqlite3_load_extension         sqlite3_api->load_extension
+#define sqlite3_malloc64               sqlite3_api->malloc64
+#define sqlite3_msize                  sqlite3_api->msize
+#define sqlite3_realloc64              sqlite3_api->realloc64
+#define sqlite3_reset_auto_extension   sqlite3_api->reset_auto_extension
+#define sqlite3_result_blob64          sqlite3_api->result_blob64
+#define sqlite3_result_text64          sqlite3_api->result_text64
+#define sqlite3_strglob                sqlite3_api->strglob
+/* Version 3.8.11 and later */
+#define sqlite3_value_dup              sqlite3_api->value_dup
+#define sqlite3_value_free             sqlite3_api->value_free
+#define sqlite3_result_zeroblob64      sqlite3_api->result_zeroblob64
+#define sqlite3_bind_zeroblob64        sqlite3_api->bind_zeroblob64
+/* Version 3.9.0 and later */
+#define sqlite3_value_subtype          sqlite3_api->value_subtype
+#define sqlite3_result_subtype         sqlite3_api->result_subtype
+/* Version 3.10.0 and later */
+#define sqlite3_status64               sqlite3_api->status64
+#define sqlite3_strlike                sqlite3_api->strlike
+#define sqlite3_db_cacheflush          sqlite3_api->db_cacheflush
+/* Version 3.12.0 and later */
+#define sqlite3_system_errno           sqlite3_api->system_errno
+/* Version 3.14.0 and later */
+#define sqlite3_trace_v2               sqlite3_api->trace_v2
+#define sqlite3_expanded_sql           sqlite3_api->expanded_sql
+/* Version 3.18.0 and later */
+#define sqlite3_set_last_insert_rowid  sqlite3_api->set_last_insert_rowid
+/* Version 3.20.0 and later */
+#define sqlite3_prepare_v3             sqlite3_api->prepare_v3
+#define sqlite3_prepare16_v3           sqlite3_api->prepare16_v3
+#define sqlite3_bind_pointer           sqlite3_api->bind_pointer
+#define sqlite3_result_pointer         sqlite3_api->result_pointer
+#define sqlite3_value_pointer          sqlite3_api->value_pointer
+/* Version 3.22.0 and later */
+#define sqlite3_vtab_nochange          sqlite3_api->vtab_nochange
+#define sqlite3_value_nochange         sqlite3_api->value_nochange
+#define sqlite3_vtab_collation         sqlite3_api->vtab_collation
+/* Version 3.24.0 and later */
+#define sqlite3_keyword_count          sqlite3_api->keyword_count
+#define sqlite3_keyword_name           sqlite3_api->keyword_name
+#define sqlite3_keyword_check          sqlite3_api->keyword_check
+#define sqlite3_str_new                sqlite3_api->str_new
+#define sqlite3_str_finish             sqlite3_api->str_finish
+#define sqlite3_str_appendf            sqlite3_api->str_appendf
+#define sqlite3_str_vappendf           sqlite3_api->str_vappendf
+#define sqlite3_str_append             sqlite3_api->str_append
+#define sqlite3_str_appendall          sqlite3_api->str_appendall
+#define sqlite3_str_appendchar         sqlite3_api->str_appendchar
+#define sqlite3_str_reset              sqlite3_api->str_reset
+#define sqlite3_str_errcode            sqlite3_api->str_errcode
+#define sqlite3_str_length             sqlite3_api->str_length
+#define sqlite3_str_value              sqlite3_api->str_value
+/* Version 3.25.0 and later */
+#define sqlite3_create_window_function sqlite3_api->create_window_function
+/* Version 3.26.0 and later */
+#define sqlite3_normalized_sql         sqlite3_api->normalized_sql
+/* Version 3.28.0 and later */
+#define sqlite3_stmt_isexplain         sqlite3_api->stmt_isexplain
+#define sqlite3_value_frombind         sqlite3_api->value_frombind
+/* Version 3.30.0 and later */
+#define sqlite3_drop_modules           sqlite3_api->drop_modules
+/* Version 3.31.0 and later */
+#define sqlite3_hard_heap_limit64      sqlite3_api->hard_heap_limit64
+#define sqlite3_uri_key                sqlite3_api->uri_key
+#define sqlite3_filename_database      sqlite3_api->filename_database
+#define sqlite3_filename_journal       sqlite3_api->filename_journal
+#define sqlite3_filename_wal           sqlite3_api->filename_wal
+/* Version 3.32.0 and later */
+#define sqlite3_create_filename        sqlite3_api->create_filename
+#define sqlite3_free_filename          sqlite3_api->free_filename
+#define sqlite3_database_file_object   sqlite3_api->database_file_object
+/* Version 3.34.0 and later */
+#define sqlite3_txn_state              sqlite3_api->txn_state
+#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
+
+#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+  /* This case when the file really is being compiled as a loadable 
+  ** extension */
+# define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
+# define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;
+# define SQLITE_EXTENSION_INIT3     \
+    extern const sqlite3_api_routines *sqlite3_api;
+#else
+  /* This case when the file is being statically linked into the 
+  ** application */
+# define SQLITE_EXTENSION_INIT1     /*no-op*/
+# define SQLITE_EXTENSION_INIT2(v)  (void)v; /* unused parameter */
+# define SQLITE_EXTENSION_INIT3     /*no-op*/
+#endif
+
+#endif /* SQLITE3EXT_H */
+#else // USE_LIBSQLITE3
+ // If users really want to link against the system sqlite3 we
+// need to make this file a noop.
+ #endif

+ 37 - 0
vendor/github.com/mattn/go-sqlite3/static_mock.go

@@ -0,0 +1,37 @@
+// Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
+//
+// Use of this source code is governed by an MIT-style
+// license that can be found in the LICENSE file.
+
+// +build !cgo
+
+package sqlite3
+
+import (
+	"database/sql"
+	"database/sql/driver"
+	"errors"
+)
+
+var errorMsg = errors.New("Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub")
+
+func init() {
+	sql.Register("sqlite3", &SQLiteDriver{})
+}
+
+type (
+	SQLiteDriver struct {
+		Extensions  []string
+		ConnectHook func(*SQLiteConn) error
+	}
+	SQLiteConn struct{}
+)
+
+func (SQLiteDriver) Open(s string) (driver.Conn, error)                        { return nil, errorMsg }
+func (c *SQLiteConn) RegisterAggregator(string, interface{}, bool) error       { return errorMsg }
+func (c *SQLiteConn) RegisterAuthorizer(func(int, string, string, string) int) {}
+func (c *SQLiteConn) RegisterCollation(string, func(string, string) int) error { return errorMsg }
+func (c *SQLiteConn) RegisterCommitHook(func() int)                            {}
+func (c *SQLiteConn) RegisterFunc(string, interface{}, bool) error             { return errorMsg }
+func (c *SQLiteConn) RegisterRollbackHook(func())                              {}
+func (c *SQLiteConn) RegisterUpdateHook(func(int, string, string, int64))      {}

+ 7 - 0
vendor/modules.txt

@@ -0,0 +1,7 @@
+# github.com/gomodule/redigo v2.0.0+incompatible
+## explicit
+github.com/gomodule/redigo/internal
+github.com/gomodule/redigo/redis
+# github.com/mattn/go-sqlite3 v1.14.7
+## explicit
+github.com/mattn/go-sqlite3