├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ ├── pull_requests.yml │ └── releases.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── go.mod ├── go.sum ├── main.go ├── scripts ├── benchmark.sh ├── ci │ ├── prepare_linux.sh │ ├── prepare_macos.sh │ └── prepare_windows.ps1 ├── fail_on_diff.sh ├── generate_test_data.js └── test.py ├── sqlite.go └── testdata ├── avro └── test_data.avro ├── bad └── not_an_array.json ├── basic_logs.csv ├── convert.csv ├── csv └── numberconvert.csv ├── excel └── multiple-sheets.xlsx ├── join ├── ages.json └── users.csv ├── logfmt └── log.logfmt ├── nested └── nested.json ├── orc └── test_data.orc ├── path └── path.json ├── regr ├── 36.json ├── 67.jsonl └── 74.csv ├── sql ├── empty.sql └── simple.sql ├── taxi.csv.7z ├── taxi_trunc.csv ├── unknown ├── userdata.csv ├── userdata.json ├── userdata.jsonl ├── userdata.ods ├── userdata.parquet ├── userdata.tsv ├── userdata.xlsx └── yaml └── userdata.yaml /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug and expected behavior** 11 | A clear and concise description of what the bug is. What should happen instead? 12 | 13 | **Reproduction steps** 14 | Please include the exact command you ran. Also include a minimal version of the data file you ran dsq against that produced the error. 15 | 16 | **Versions** 17 | - OS: [e.g. Windows version, `uname -a` on Mac/Linux] 18 | - Shell: [e.g. Powershell, bash, fish, cmd.exe, WSL, etc.] 19 | - dsq version: [e.g. 0.20.1] 20 | 21 | **Additional context, screenshots** 22 | Add any other context about the problem here. Feel free to include screenshots or stack traces as necessary. 23 | -------------------------------------------------------------------------------- /.github/workflows/pull_requests.yml: -------------------------------------------------------------------------------- 1 | name: Run tests 2 | 3 | on: 4 | pull_request: 5 | branches: [main] 6 | 7 | jobs: 8 | test: 9 | runs-on: ubuntu-latest 10 | 11 | if: github.event_name == 'pull_request' 12 | steps: 13 | - uses: actions/checkout@master 14 | with: 15 | ref: ${{ github.ref }} 16 | 17 | - run: ./scripts/ci/prepare_linux.sh 18 | - name: Run golangci-lint 19 | uses: golangci/golangci-lint-action@v3 20 | with: 21 | args: --timeout=3m --verbose 22 | - run: go test -race -cover 23 | - run: gofmt -w -s . 24 | - run: ./scripts/fail_on_diff.sh 25 | 26 | dsq-tests-ubuntu: 27 | runs-on: ubuntu-latest 28 | 29 | steps: 30 | - uses: actions/checkout@master 31 | with: 32 | ref: ${{ github.ref }} 33 | 34 | - run: ./scripts/ci/prepare_linux.sh 35 | - run: go build -trimpath -buildmode=pie -mod=readonly -modcacherw 36 | - name: Test defaults 37 | run: ./scripts/test.py 38 | - name: Test without SQLite writer 39 | run: DSQ_NO_SQLITE_WRITER=true ./scripts/test.py 40 | 41 | dsq-tests-windows: 42 | runs-on: windows-latest 43 | 44 | steps: 45 | - uses: actions/checkout@master 46 | with: 47 | ref: ${{ github.ref }} 48 | 49 | - run: ./scripts/ci/prepare_windows.ps1 50 | shell: pwsh 51 | - run: go build -trimpath -buildmode=pie -mod=readonly -modcacherw 52 | - run: ./scripts/test.py 53 | shell: bash 54 | 55 | # Subtle behavioral differences between powershell/cmd and bash. For example nested double quotes must be escaped. 56 | - name: Test with powershell 57 | run: python3 ./scripts/test.py 58 | shell: powershell 59 | - name: Test with cmd.exe 60 | run: python3 ./scripts/test.py 61 | shell: cmd 62 | 63 | dsq-tests-macos: 64 | runs-on: macos-latest 65 | 66 | steps: 67 | - uses: actions/checkout@master 68 | with: 69 | ref: ${{ github.ref }} 70 | 71 | - run: ./scripts/ci/prepare_macos.sh 72 | - run: go build -trimpath -buildmode=pie -mod=readonly -modcacherw 73 | - run: ./scripts/test.py 74 | -------------------------------------------------------------------------------- /.github/workflows/releases.yml: -------------------------------------------------------------------------------- 1 | name: Build and publish artifacts 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | build-linux: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@master 13 | with: 14 | ref: ${{ github.ref }} 15 | 16 | - run: ./scripts/ci/prepare_linux.sh 17 | - run: echo "GIT_TAG=`git tag --points-at HEAD`" >> $GITHUB_ENV 18 | - run: | 19 | echo "RELEASE_ID=`curl -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' https://api.github.com/repos/multiprocessio/dsq/releases/tags/$GIT_TAG | jq '.id'`" >> $GITHUB_ENV 20 | - run: go build -trimpath -buildmode=pie -mod=readonly -modcacherw -ldflags "-s -w -X main.Version=$GIT_TAG" 21 | - run: zip dsq-linux-x64-$GIT_TAG.zip dsq 22 | - name: Upload on release 23 | run: | 24 | curl --fail \ 25 | -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ 26 | -H "Content-Type: application/zip" \ 27 | --data-binary @./dsq-linux-x64-$GIT_TAG.zip \ 28 | "https://uploads.github.com/repos/multiprocessio/dsq/releases/$RELEASE_ID/assets?name=dsq-linux-x64-$GIT_TAG.zip" 29 | 30 | build-macos: 31 | runs-on: macos-latest 32 | 33 | steps: 34 | - uses: actions/checkout@master 35 | with: 36 | ref: ${{ github.ref }} 37 | 38 | - run: ./scripts/ci/prepare_macos.sh 39 | - run: echo "GIT_TAG=`git tag --points-at HEAD`" >> $GITHUB_ENV 40 | - run: | 41 | echo "RELEASE_ID=`curl -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' https://api.github.com/repos/multiprocessio/dsq/releases/tags/$GIT_TAG | jq '.id'`" >> $GITHUB_ENV 42 | - run: go build -trimpath -buildmode=pie -mod=readonly -modcacherw -ldflags "-s -w -X main.Version=$GIT_TAG" 43 | - run: zip dsq-darwin-x64-$GIT_TAG.zip dsq 44 | - name: Upload release 45 | run: | 46 | curl --fail \ 47 | -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ 48 | -H "Content-Type: application/zip" \ 49 | --data-binary @./dsq-darwin-x64-$GIT_TAG.zip \ 50 | "https://uploads.github.com/repos/multiprocessio/dsq/releases/$RELEASE_ID/assets?name=dsq-darwin-x64-$GIT_TAG.zip" 51 | 52 | build-windows: 53 | runs-on: windows-latest 54 | 55 | steps: 56 | - uses: actions/checkout@master 57 | with: 58 | ref: ${{ github.ref }} 59 | 60 | - run: ./scripts/ci/prepare_windows.ps1 61 | - run: echo "GIT_TAG=$(git tag --points-at HEAD)" >> $Env:GITHUB_ENV 62 | - run: | 63 | echo "RELEASE_ID=$(curl -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' https://api.github.com/repos/multiprocessio/dsq/releases/tags/$Env:GIT_TAG | jq '.id')" >> $Env:GITHUB_ENV 64 | - run: go build -trimpath -buildmode=pie -mod=readonly -modcacherw -ldflags "-s -w -X main.Version=$Env:GIT_TAG" 65 | - run: zip dsq-win32-x64-$Env:GIT_TAG.zip dsq.exe 66 | - name: Upload release 67 | run: | 68 | curl --fail -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" -H "Content-Type: application/zip" --data-binary "@./dsq-win32-x64-$Env:GIT_TAG.zip" "https://uploads.github.com/repos/multiprocessio/dsq/releases/$Env:RELEASE_ID/assets?name=dsq-win32-x64-$Env:GIT_TAG.zip" 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | dsq 3 | *.exe 4 | taxi.* 5 | datafusion_commands.txt 6 | benchmarks.md 7 | .idea 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2022 Multiprocess Labs LLC 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Not under active development 2 | 3 | While development may continue in the future with a different 4 | architecture, for the moment you should probably instead use 5 | [DuckDB](https://github.com/duckdb/duckdb), 6 | [ClickHouse-local](https://clickhouse.com/docs/en/operations/utilities/clickhouse-local), 7 | or [GlareDB (based on 8 | DataFusion)](https://github.com/GlareDB/glaredb). 9 | 10 | These are built on stronger analytics foundations than projects like 11 | dsq based on SQLite. For example, column-oriented storage and 12 | vectorized execution, let alone JIT-compiled expression evaluation, 13 | are possible with these other projects. 14 | 15 | [More here](https://twitter.com/eatonphil/status/1708130091425784146). 16 | 17 | # Commandline tool for running SQL queries against JSON, CSV, Excel, Parquet, and more 18 | 19 | Since Github doesn't provide a great way for you to learn about new 20 | releases and features, don't just star the repo, join the [mailing 21 | list](https://docs.google.com/forms/d/e/1FAIpQLSfYF3AZivacRrQWanC-skd0iI23ermwPd17T_64Xc4etoL_Tw/viewform). 22 | 23 | - [About](#about) 24 | - [Install](#install) 25 | - [macOS Homebrew](#macos-homebrew) 26 | - [Binaries on macOS, Linux, WSL](#binaries-on-macos-linux-wsl) 27 | - [Binaries on Windows (not WSL)](#binaries-on-windows-not-wsl) 28 | - [Build and install from source](#build-and-install-from-source) 29 | - [Usage](#usage) 30 | - [Pretty print](#pretty-print) 31 | - [Piping data to dsq](#piping-data-to-dsq) 32 | - [Multiple files and joins](#multiple-files-and-joins) 33 | - [SQL query from file](#sql-query-from-file) 34 | - [Transforming data to JSON without querying](#transforming-data-to-json-without-querying) 35 | - [Array of objects nested within an object](#array-of-objects-nested-within-an-object) 36 | - [Multiple Excel sheets](#multiple-excel-sheets) 37 | - [Limitation: nested arrays](#limitation-nested-arrays) 38 | - [Nested object values](#nested-object-values) 39 | - [Caveat: PowerShell, CMD.exe](#caveat-powershell-cmdexe) 40 | - [Nested objects explained](#nested-objects-explained) 41 | - [Limitation: whole object retrieval](#limitation-whole-object-retrieval) 42 | - [Nested arrays](#nested-arrays) 43 | - [JSON operators](#json-operators) 44 | - [REGEXP](#regexp) 45 | - [Standard Library](#standard-library) 46 | - [Output column order](#output-column-order) 47 | - [Dumping inferred schema](#dumping-inferred-schema) 48 | - [Caching](#caching) 49 | - [Interactive REPL](#interactive-repl) 50 | - [Converting numbers in CSV and TSV files](#converting-numbers-in-csv-and-tsv-files) 51 | - [Supported Data Types](#supported-data-types) 52 | - [Engine](#engine) 53 | - [Comparisons](#comparisons) 54 | - [Benchmark](#benchmark) 55 | - [Notes](#notes) 56 | - [Third-party integrations](#third-party-integrations) 57 | - [Community](#community) 58 | - [How can I help?](#how-can-i-help) 59 | - [License](#license) 60 | 61 | ## About 62 | 63 | This is a CLI companion to 64 | [DataStation](https://github.com/multiprocessio/datastation) (a GUI) 65 | for running SQL queries against data files. So if you want the GUI 66 | version of this, check out DataStation. 67 | 68 | ## Install 69 | 70 | Binaries for amd64 (x86_64) are provided for each release. 71 | 72 | ### macOS Homebrew 73 | 74 | `dsq` is available on macOS Homebrew: 75 | 76 | ```bash 77 | $ brew install dsq 78 | ``` 79 | 80 | ### Binaries on macOS, Linux, WSL 81 | 82 | On macOS, Linux, and WSL you can run the following: 83 | 84 | ```bash 85 | $ VERSION="v0.23.0" 86 | $ FILE="dsq-$(uname -s | awk '{ print tolower($0) }')-x64-$VERSION.zip" 87 | $ curl -LO "https://github.com/multiprocessio/dsq/releases/download/$VERSION/$FILE" 88 | $ unzip $FILE 89 | $ sudo mv ./dsq /usr/local/bin/dsq 90 | ``` 91 | 92 | Or install manually from the [releases 93 | page](https://github.com/multiprocessio/dsq/releases), unzip and add 94 | `dsq` to your `$PATH`. 95 | 96 | ### Binaries on Windows (not WSL) 97 | 98 | Download the [latest Windows 99 | release](https://github.com/multiprocessio/dsq/releases), unzip it, 100 | and add `dsq` to your `$PATH`. 101 | 102 | ### Build and install from source 103 | 104 | If you are on another platform or architecture or want to grab the 105 | latest release, you can do so with Go 1.18+: 106 | 107 | ```bash 108 | $ go install github.com/multiprocessio/dsq@latest 109 | ``` 110 | 111 | `dsq` will likely work on other platforms that Go is ported to such as 112 | AARCH64 and OpenBSD, but tests and builds are only run against x86_64 113 | Windows/Linux/macOS. 114 | 115 | ## Usage 116 | 117 | You can either pipe data to `dsq` or you can pass a file name to 118 | it. NOTE: piping data doesn't work on Windows. 119 | 120 | If you are passing a file, it must have the usual extension for its 121 | content type. 122 | 123 | For example: 124 | 125 | ```bash 126 | $ dsq testdata.json "SELECT * FROM {} WHERE x > 10" 127 | ``` 128 | 129 | Or: 130 | 131 | ```bash 132 | $ dsq testdata.ndjson "SELECT name, AVG(time) FROM {} GROUP BY name ORDER BY AVG(time) DESC" 133 | ``` 134 | 135 | ### Pretty print 136 | 137 | By default `dsq` prints ugly JSON. This is the most efficient mode. 138 | 139 | ```bash 140 | $ dsq testdata/userdata.parquet 'select count(*) from {}' 141 | [{"count(*)":1000} 142 | ] 143 | ``` 144 | 145 | If you want prettier JSON you can pipe `dsq` to `jq`. 146 | 147 | ```bash 148 | $ dsq testdata/userdata.parquet 'select count(*) from {}' | jq 149 | [ 150 | { 151 | "count(*)": 1000 152 | } 153 | ] 154 | ``` 155 | 156 | Or you can enable pretty printing with `-p` or `--pretty` in `dsq` 157 | which will display your results in an ASCII table. 158 | 159 | ```bash 160 | $ dsq --pretty testdata/userdata.parquet 'select count(*) from {}' 161 | +----------+ 162 | | count(*) | 163 | +----------+ 164 | | 1000 | 165 | +----------+ 166 | ``` 167 | 168 | ### Piping data to dsq 169 | 170 | When piping data to `dsq` you need to set the `-s` flag and specify 171 | the file extension or MIME type. 172 | 173 | For example: 174 | 175 | ```bash 176 | $ cat testdata.csv | dsq -s csv "SELECT * FROM {} LIMIT 1" 177 | ``` 178 | 179 | Or: 180 | 181 | ```bash 182 | $ cat testdata.parquet | dsq -s parquet "SELECT COUNT(1) FROM {}" 183 | ``` 184 | 185 | ### Multiple files and joins 186 | 187 | You can pass multiple files to DSQ. As long as they are supported data 188 | files in a valid format, you can run SQL against all files as 189 | tables. Each table can be accessed by the string `{N}` where `N` is the 190 | 0-based index of the file in the list of files passed on the 191 | commandline. 192 | 193 | For example this joins two datasets of differing origin types (CSV and 194 | JSON). 195 | 196 | ```bash 197 | $ dsq testdata/join/users.csv testdata/join/ages.json \ 198 | "select {0}.name, {1}.age from {0} join {1} on {0}.id = {1}.id" 199 | [{"age":88,"name":"Ted"}, 200 | {"age":56,"name":"Marjory"}, 201 | {"age":33,"name":"Micah"}] 202 | ``` 203 | 204 | You can also give file-table-names aliases since `dsq` uses standard 205 | SQL: 206 | 207 | ```bash 208 | $ dsq testdata/join/users.csv testdata/join/ages.json \ 209 | "select u.name, a.age from {0} u join {1} a on u.id = a.id" 210 | [{"age":88,"name":"Ted"}, 211 | {"age":56,"name":"Marjory"}, 212 | {"age":33,"name":"Micah"}] 213 | ``` 214 | 215 | ### SQL query from file 216 | 217 | As your query becomes more complex, it might be useful to store it in a file 218 | rather than specify it on the command line. To do so replace the query argument 219 | with `--file` or `-f` and the path to the file. 220 | 221 | ```bash 222 | $ dsq data1.csv data2.csv -f query.sql 223 | ``` 224 | 225 | ### Transforming data to JSON without querying 226 | 227 | As a shorthand for `dsq testdata.csv "SELECT * FROM {}"` to convert 228 | supported file types to JSON you can skip the query and the converted 229 | JSON will be dumped to stdout. 230 | 231 | For example: 232 | 233 | ```bash 234 | $ dsq testdata.csv 235 | [{...some csv data...},{...some csv data...},...] 236 | ``` 237 | 238 | ### Array of objects nested within an object 239 | 240 | DataStation and `dsq`'s SQL integration operates on an array of 241 | objects. If your array of objects happens to be at the top-level, you 242 | don't need to do anything. But if your array data is nested within an 243 | object you can add a "path" parameter to the table reference. 244 | 245 | For example if you have this data: 246 | 247 | ```bash 248 | $ cat api-results.json 249 | { 250 | "data": { 251 | "data": [ 252 | {"id": 1, "name": "Corah"}, 253 | {"id": 3, "name": "Minh"} 254 | ] 255 | }, 256 | "total": 2 257 | } 258 | ``` 259 | 260 | You need to tell `dsq` that the path to the array data is `"data.data"`: 261 | 262 | ```bash 263 | $ dsq --pretty api-results.json 'SELECT * FROM {0, "data.data"} ORDER BY id DESC' 264 | +----+-------+ 265 | | id | name | 266 | +----+-------+ 267 | | 3 | Minh | 268 | | 1 | Corah | 269 | +----+-------+ 270 | ``` 271 | 272 | You can also use the shorthand `{"path"}` or `{'path'}` if you only have one table: 273 | 274 | ```bash 275 | $ dsq --pretty api-results.json 'SELECT * FROM {"data.data"} ORDER BY id DESC' 276 | +----+-------+ 277 | | id | name | 278 | +----+-------+ 279 | | 3 | Minh | 280 | | 1 | Corah | 281 | +----+-------+ 282 | ``` 283 | 284 | You can use either single or double quotes for the path. 285 | 286 | #### Multiple Excel sheets 287 | 288 | Excel files with multiple sheets are stored as an object with key 289 | being the sheet name and value being the sheet data as an array of 290 | objects. 291 | 292 | If you have an Excel file with two sheets called `Sheet1` and `Sheet2` 293 | you can run `dsq` on the second sheet by specifying the sheet name as 294 | the path: 295 | 296 | ```bash 297 | $ dsq data.xlsx 'SELECT COUNT(1) FROM {"Sheet2"}' 298 | ``` 299 | 300 | #### Limitation: nested arrays 301 | 302 | You cannot specify a path through an array, only objects. 303 | 304 | ### Nested object values 305 | 306 | It's easiest to show an example. Let's say you have the following JSON file called `user_addresses.json`: 307 | 308 | ```bash 309 | $ cat user_addresses.json 310 | [ 311 | {"name": "Agarrah", "location": {"city": "Toronto", "address": { "number": 1002 }}}, 312 | {"name": "Minoara", "location": {"city": "Mexico City", "address": { "number": 19 }}}, 313 | {"name": "Fontoon", "location": {"city": "New London", "address": { "number": 12 }}} 314 | ] 315 | ``` 316 | 317 | You can query the nested fields like so: 318 | 319 | ```sql 320 | $ dsq user_addresses.json 'SELECT name, "location.city" FROM {}' 321 | ``` 322 | 323 | And if you need to disambiguate the table: 324 | 325 | ```sql 326 | $ dsq user_addresses.json 'SELECT name, {}."location.city" FROM {}' 327 | ``` 328 | 329 | #### Caveat: PowerShell, CMD.exe 330 | 331 | On PowerShell and CMD.exe you must escape inner double quotes with backslashes: 332 | 333 | ```powershell 334 | > dsq user_addresses.json 'select name, \"location.city\" from {}' 335 | [{"location.city":"Toronto","name":"Agarrah"}, 336 | {"location.city":"Mexico City","name":"Minoara"}, 337 | {"location.city":"New London","name":"Fontoon"}] 338 | ``` 339 | 340 | #### Nested objects explained 341 | 342 | Nested objects are collapsed and their new column name becomes the 343 | JSON path to the value connected by `.`. Actual dots in the path must 344 | be escaped with a backslash. Since `.` is a special character in SQL 345 | you must quote the whole new column name. 346 | 347 | #### Limitation: whole object retrieval 348 | 349 | You cannot query whole objects, you must ask for a specific path that 350 | results in a scalar value. 351 | 352 | For example in the `user_addresses.json` example above you CANNOT do this: 353 | 354 | ```sql 355 | $ dsq user_addresses.json 'SELECT name, {}."location" FROM {}' 356 | ``` 357 | 358 | Because `location` is not a scalar value. It is an object. 359 | 360 | ### Nested arrays 361 | 362 | Nested arrays are converted to a JSON string when stored in 363 | SQLite. Since SQLite supports querying JSON strings you can access 364 | that data as structured data even though it is a string. 365 | 366 | So if you have data like this in `fields.json`: 367 | 368 | ```json 369 | [ 370 | {"field1": [1]}, 371 | {"field1": [2]}, 372 | ] 373 | ``` 374 | 375 | You can request the entire field: 376 | 377 | ``` 378 | $ dsq fields.json "SELECT field1 FROM {}" | jq 379 | [ 380 | { 381 | "field1": "[1]" 382 | }, 383 | { 384 | "field1": "[2]", 385 | } 386 | ] 387 | ``` 388 | 389 | #### JSON operators 390 | 391 | You can get the first value in the array using SQL JSON operators. 392 | 393 | ``` 394 | $ dsq fields.json "SELECT field1->0 FROM {}" | jq 395 | [ 396 | { 397 | "field1->0": "1" 398 | }, 399 | { 400 | "field1->0": "2" 401 | } 402 | ] 403 | ``` 404 | 405 | ### REGEXP 406 | 407 | Since DataStation and `dsq` are built on SQLite, you can filter using 408 | `x REGEXP 'y'` where `x` is some column or value and `y` is a REGEXP 409 | string. SQLite doesn't pick a regexp implementation. DataStation and 410 | `dsq` use Go's regexp implementation which is more limited than PCRE2 411 | because Go support for PCRE2 is not yet very mature. 412 | 413 | ```sql 414 | $ dsq user_addresses.json "SELECT * FROM {} WHERE name REGEXP 'A.*'" 415 | [{"location.address.number":1002,"location.city":"Toronto","name":"Agarrah"}] 416 | ``` 417 | 418 | ### Standard Library 419 | 420 | dsq registers 421 | [go-sqlite3-stdlib](https://github.com/multiprocessio/go-sqlite3-stdlib) 422 | so you get access to numerous statistics, url, math, string, and 423 | regexp functions that aren't part of the SQLite base. 424 | 425 | View that project docs for all available extended functions. 426 | 427 | ### Output column order 428 | 429 | When emitting JSON (i.e. without the `--pretty` flag) keys within an 430 | object are unordered. 431 | 432 | If order is important to you you can filter with `jq`: `dsq x.csv 433 | 'SELECT a, b FROM {}' | jq --sort-keys`. 434 | 435 | With the `--pretty` flag, column order is purely alphabetical. It is 436 | not possible at the moment for the order to depend on the SQL query 437 | order. 438 | 439 | ### Dumping inferred schema 440 | 441 | For any supported file you can dump the inferred schema rather than 442 | dumping the data or running a SQL query. Set the `--schema` flag to do 443 | this. 444 | 445 | The inferred schema is very simple, only JSON types are supported. If 446 | the underlying format (like Parquet) supports finer-grained data types 447 | (like int64) this will not show up in the inferred schema. It will 448 | show up just as `number`. 449 | 450 | For example: 451 | 452 | ``` 453 | $ dsq testdata/avro/test_data.avro --schema --pretty 454 | Array of 455 | Object of 456 | birthdate of 457 | string 458 | cc of 459 | Varied of 460 | Object of 461 | long of 462 | number or 463 | Unknown 464 | comments of 465 | string 466 | country of 467 | string 468 | email of 469 | string 470 | first_name of 471 | string 472 | gender of 473 | string 474 | id of 475 | number 476 | ip_address of 477 | string 478 | last_name of 479 | string 480 | registration_dttm of 481 | string 482 | salary of 483 | Varied of 484 | Object of 485 | double of 486 | number or 487 | Unknown 488 | title of 489 | string 490 | ``` 491 | 492 | You can print this as a structured JSON string by omitting the 493 | `--pretty` flag when setting the `--schema` flag. 494 | 495 | ### Caching 496 | 497 | Sometimes you want to do some exploration on a dataset that isn't 498 | changing frequently. By turning on the `--cache` or `-C` flag 499 | DataStation will store the imported data on disk and not delete it 500 | when the run is over. 501 | 502 | With caching on, DataStation calculates a SHA1 sum of all the files you 503 | specified. If the sum ever changes then it will reimport all the 504 | files. Otherwise when you run additional queries with the cache 505 | flag on it will reuse that existing database and not reimport the files. 506 | 507 | Since without caching on DataStation uses an in-memory database, the 508 | initial query with caching on may take slightly longer than with 509 | caching off. Subsequent queries will be substantially faster though 510 | (for large datasets). 511 | 512 | For example, in the first run with caching on this query might take 30s: 513 | 514 | ``` 515 | $ dsq some-large-file.json --cache 'SELECT COUNT(1) FROM {}' 516 | ``` 517 | 518 | But when you run another query it might only take 1s. 519 | 520 | ``` 521 | $ dsq some-large-file.json --cache 'SELECT SUM(age) FROM {}' 522 | ``` 523 | 524 | Not because we cache any result but because we cache importing the 525 | file into SQLite. 526 | 527 | So even if you change the query, as long as the file doesn't change, 528 | the cache is effective. 529 | 530 | To make this permanent you can export `DSQ_CACHE=true` in your environment. 531 | 532 | ### Interactive REPL 533 | 534 | Use the `-i` or `--interactive` flag to enter an interactive REPL 535 | where you can run multiple SQL queries. 536 | 537 | ``` 538 | $ dsq some-large-file.json -i 539 | dsq> SELECT COUNT(1) FROM {}; 540 | +----------+ 541 | | COUNT(1) | 542 | +----------+ 543 | | 1000 | 544 | +----------+ 545 | (1 row) 546 | dsq> SELECT * FROM {} WHERE NAME = 'Kevin'; 547 | (0 rows) 548 | ``` 549 | 550 | ### Converting numbers in CSV and TSV files 551 | 552 | CSV and TSV files do not allow to specify the type of the individual 553 | values contained in them. All values are treated as strings by default. 554 | 555 | This can lead to unexpected results in queries. Consider the following 556 | example: 557 | 558 | ``` 559 | $ cat scores.csv 560 | name,score 561 | Fritz,90 562 | Rainer,95.2 563 | Fountainer,100 564 | 565 | $ dsq scores.csv "SELECT * FROM {} ORDER BY score" 566 | [{"name":"Fountainer","score":"100"}, 567 | {"name":"Fritz","score":"90"}, 568 | {"name":"Rainer","score":"95.2"}] 569 | ``` 570 | 571 | Note how the `score` column contains numerical values only. Still, 572 | sorting by that column yields unexpected results because the values are 573 | treated as strings, and sorted lexically. (You can tell that the 574 | individual scores were imported as strings because they're quoted in the 575 | JSON result.) 576 | 577 | Use the `-n` or `--convert-numbers` flag to auto-detect and convert 578 | numerical values (integers and floats) in imported files: 579 | 580 | ``` 581 | $ dsq ~/scores.csv --convert-numbers "SELECT * FROM {} ORDER BY score" 582 | [{"name":"Fritz","score":90}, 583 | {"name":"Rainer","score":95.2}, 584 | {"name":"Fountainer","score":100}] 585 | ``` 586 | 587 | Note how the scores are imported as numbers now and how the records in 588 | the result set are sorted by their numerical value. Also note that the 589 | individual scores are no longer quoted in the JSON result. 590 | 591 | To make this permanent you can export `DSQ_CONVERT_NUMBERS=true` in 592 | your environment. Turning this on disables some optimizations. 593 | 594 | ## Supported Data Types 595 | 596 | | Name | File Extension(s) | Mime Type | Notes | | 597 | |------------------------|-------------------|--------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|---| 598 | | CSV | `csv` | `text/csv` | | | 599 | | TSV | `tsv`, `tab` | `text/tab-separated-values` | | | 600 | | JSON | `json` | `application/json` | Must be an array of objects or a [path to an array of objects](https://github.com/multiprocessio/dsq#array-of-objects-nested-within-an-object). | | 601 | | Newline-delimited JSON | `ndjson`, `jsonl` | `application/jsonlines` | | | 602 | | Concatenated JSON | `cjson` | `application/jsonconcat` | | | 603 | | ORC | `orc` | `orc` | | | 604 | | Parquet | `parquet` | `parquet` | | | 605 | | Avro | `avro` | `application/avro` | | | 606 | | YAML | `yaml`, `yml` | `application/yaml` | | | 607 | | Excel | `xlsx`, `xls` | `application/vnd.ms-excel` | If you have multiple sheets, you must [specify a sheet path](https://github.com/multiprocessio/dsq#multiple-excel-sheets). | | 608 | | ODS | `ods` | `application/vnd.oasis.opendocument.spreadsheet` | If you have multiple sheets, you must [specify a sheet path](https://github.com/multiprocessio/dsq#multiple-excel-sheets). | | 609 | | Apache Error Logs | NA | `text/apache2error` | Currently only works if being piped in. | | 610 | | Apache Access Logs | NA | `text/apache2access` | Currently only works if being piped in. | | 611 | | Nginx Access Logs | NA | `text/nginxaccess` | Currently only works if being piped in. | | 612 | | LogFmt Logs | `logfmt` | `text/logfmt` | | | 613 | 614 | ## Engine 615 | 616 | Under the hood dsq uses 617 | [DataStation](https://github.com/multiprocessio/datastation) as a 618 | library and under that hood DataStation uses SQLite to power these 619 | kinds of SQL queries on arbitrary (structured) data. 620 | 621 | ## Comparisons 622 | 623 | | Name | Link | Caching | Engine | Supported File Types | Binary Size | 624 | |-|---|-|-|------------------------------------------------------------------------|-| 625 | | dsq | Here | Yes | SQLite | CSV, TSV, a few variations of JSON, Parquet, Excel, ODS (OpenOffice Calc), ORC, Avro, YAML, Logs | 49M | 626 | | q | http://harelba.github.io/q/ | Yes | SQLite | CSV, TSV | 82M | 627 | | textql | https://github.com/dinedal/textql | No | SQLite | CSV, TSV | 7.3M | 628 | | octoql | https://github.com/cube2222/octosql | No | Custom engine | JSON, CSV, Excel, Parquet | 18M | 629 | | csvq | https://github.com/mithrandie/csvq | No | Custom engine | CSV | 15M | 630 | | sqlite-utils | https://github.com/simonw/sqlite-utils | No | SQLite | CSV, TSV | N/A, Not a single binary | 631 | | trdsql | https://github.com/noborus/trdsql | No | SQLite, MySQL or PostgreSQL | Few variations of JSON, TSV, LTSV, TBLN, CSV | 14M | 632 | | spysql | https://github.com/dcmoura/spyql | No | Custom engine | CSV, JSON, TEXT | N/A, Not a single binary | 633 | | duckdb | https://github.com/duckdb/duckdb | ? | Custom engine | CSV, Parquet | 35M | 634 | 635 | Not included: 636 | 637 | * clickhouse-local: fastest of anything listed here but so gigantic (over 2GB) that it can't reasonably be considered a good tool for any environment 638 | * sqlite3: requires multiple commands to ingest CSV, not great for one-liners 639 | * datafusion-cli: very fast (slower only than clickhouse-local) but requires multiple commands to ingest CSV, so not great for one-liners 640 | 641 | ## Benchmark 642 | 643 | This benchmark was run June 19, 2022. It is run on a [dedicated bare 644 | metal instance on 645 | OVH](https://us.ovhcloud.com/bare-metal/rise/rise-1/) with: 646 | 647 | * 64 GB DDR4 ECC 2,133 MHz 648 | * 2x450 GB SSD NVMe in Soft RAID 649 | * Intel Xeon E3-1230v6 - 4c/8t - 3.5 GHz/3.9 GHz 650 | 651 | It runs a `SELECT passenger_count, COUNT(*), AVG(total_amount) FROM 652 | taxi.csv GROUP BY passenger_count` query against the well-known NYC 653 | Yellow Taxi Trip Dataset. Specifically, the CSV file from April 2021 654 | is used. It's a 200MB CSV file with ~2 million rows, 18 columns, and 655 | mostly numerical values. 656 | 657 | The script is [here](./scripts/benchmark.sh). It is an adaptation of 658 | the [benchmark that the octosql devs 659 | run](https://github.com/cube2222/octosql#Benchmarks). 660 | 661 | | Program | Version | Mean [s] | Min [s] | Max [s] | Relative | 662 | |:----------|:--------------------|---------------:|--------:|--------:|-------------:| 663 | | dsq | 0.20.1 (caching on) | 1.151 ± 0.010 | 1.131 | 1.159 | 1.00 | 664 | | duckdb | 0.3.4 | 1.723 ± 0.023 | 1.708 | 1.757 | 1.50 ± 0.02 | 665 | | octosql | 0.7.3 | 2.005 ± 0.008 | 1.991 | 2.015 | 1.74 ± 0.02 | 666 | | q | 3.1.6 (caching on) | 2.028 ± 0.010 | 2.021 | 2.055 | 1.76 ± 0.02 | 667 | | sqlite3 * | 3.36.0 | 4.204 ± 0.018 | 4.177 | 4.229 | 3.64 ± 0.04 | 668 | | trdsql | 0.10.0 | 12.972 ± 0.225 | 12.554 | 13.392 | 11.27 ± 0.22 | 669 | | dsq | 0.20.1 (default) | 15.030 ± 0.086 | 14.895 | 15.149 | 13.06 ± 0.13 | 670 | | textql | fca00ec | 19.148 ± 0.183 | 18.865 | 19.500 | 16.63 ± 0.21 | 671 | | spyql | 0.6.0 | 16.985 ± 0.105 | 16.854 | 17.161 | 14.75 ± 0.16 | 672 | | q | 3.1.6 (default) | 24.061 ± 0.095 | 23.954 | 24.220 | 20.90 ± 0.20 | 673 | 674 | \* While dsq and q are built on top of sqlite3 there is not a builtin way in sqlite3 to cache ingested files without a bit of scripting 675 | 676 | Not included: 677 | * clickhouse-local: faster than any of these but over 2GB so not a reasonable general-purpose CLI 678 | * datafusion-cli: slower only than clickhouse-local but requires multiple commands to ingest CSV, can't do one-liners 679 | * sqlite-utils: takes minutes to finish 680 | 681 | ### Notes 682 | 683 | OctoSQL, duckdb, and SpyQL implement their own SQL engines. 684 | dsq, q, trdsql, and textql copy data into SQLite and depend on the 685 | SQLite engine for query execution. 686 | 687 | Tools that implement their own SQL engines can do better on 1) 688 | ingestion and 2) queries that act on a subset of data (such as limited 689 | columns or limited rows). These tools implement ad-hoc subsets of SQL 690 | that may be missing or differ from your favorite syntax. On the other 691 | hand, tools that depend on SQLite have the benefit of providing a 692 | well-tested and well-documented SQL engine. DuckDB is exceptional 693 | since there is a dedicated company behind it. 694 | 695 | dsq also comes with numerous [useful 696 | functions](https://github.com/multiprocessio/go-sqlite3-stdlib) 697 | (e.g. best-effort date parsing, URL parsing/extraction, statistics 698 | functions, etc.) on top of [SQLite builtins](https://www.sqlite.org/lang_corefunc.html). 699 | 700 | ## Third-party integrations 701 | 702 | * [ob-dsq](https://github.com/fritzgrabo/ob-dsq) 703 | 704 | ## Community 705 | 706 | [Join us at #dsq on the Multiprocess Discord](https://discord.gg/9BRhAMhDa5). 707 | 708 | ## How can I help? 709 | 710 | Download dsq and use it! Report bugs on 711 | [Discord](https://discord.gg/f2wQBc4bXX). 712 | 713 | If you're a developer with some Go experience looking to hack on open 714 | source, check out 715 | [GOOD_FIRST_PROJECTS.md](https://github.com/multiprocessio/datastation/blob/main/GOOD_FIRST_PROJECTS.md) 716 | in the DataStation repo. 717 | 718 | ## License 719 | 720 | This software is licensed under an Apache 2.0 license. 721 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/multiprocessio/dsq 2 | 3 | go 1.18 4 | 5 | // Uncomment for local development (and re-run `go mod tidy`) 6 | // replace github.com/multiprocessio/datastation/runner => ../datastation/runner 7 | 8 | require ( 9 | github.com/chzyer/readline v1.5.0 10 | github.com/google/uuid v1.3.0 11 | github.com/multiprocessio/datastation/runner v0.0.0-20221019004540-4e72a6e0af28 12 | github.com/olekukonko/tablewriter v0.0.5 13 | ) 14 | 15 | require ( 16 | cloud.google.com/go v0.104.0 // indirect 17 | cloud.google.com/go/bigquery v1.42.0 // indirect 18 | cloud.google.com/go/compute v1.10.0 // indirect 19 | cloud.google.com/go/iam v0.5.0 // indirect 20 | github.com/Azure/azure-pipeline-go v0.2.3 // indirect 21 | github.com/Azure/azure-storage-blob-go v0.15.0 // indirect 22 | github.com/ClickHouse/ch-go v0.48.0 // indirect 23 | github.com/ClickHouse/clickhouse-go/v2 v2.3.0 // indirect 24 | github.com/alexbrainman/odbc v0.0.0-20211220213544-9c9a2e61c5e2 // indirect 25 | github.com/andybalholm/brotli v1.0.4 // indirect 26 | github.com/apache/arrow/go/arrow v0.0.0-20211112161151-bc219186db40 // indirect 27 | github.com/apache/thrift v0.17.0 // indirect 28 | github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect 29 | github.com/aws/aws-sdk-go v1.44.118 // indirect 30 | github.com/aws/aws-sdk-go-v2 v1.16.16 // indirect 31 | github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.8 // indirect 32 | github.com/aws/aws-sdk-go-v2/credentials v1.12.21 // indirect 33 | github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.34 // indirect 34 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23 // indirect 35 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17 // indirect 36 | github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14 // indirect 37 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9 // indirect 38 | github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18 // indirect 39 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17 // indirect 40 | github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.17 // indirect 41 | github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11 // indirect 42 | github.com/aws/smithy-go v1.13.3 // indirect 43 | github.com/beorn7/perks v1.0.1 // indirect 44 | github.com/cespare/xxhash/v2 v2.1.2 // indirect 45 | github.com/deepmap/oapi-codegen v1.11.0 // indirect 46 | github.com/denisenkom/go-mssqldb v0.12.3 // indirect 47 | github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 // indirect 48 | github.com/form3tech-oss/jwt-go v3.2.5+incompatible // indirect 49 | github.com/gabriel-vasile/mimetype v1.4.1 // indirect 50 | github.com/go-faster/city v1.0.1 // indirect 51 | github.com/go-faster/errors v0.6.1 // indirect 52 | github.com/go-logfmt/logfmt v0.5.1 // indirect 53 | github.com/go-sql-driver/mysql v1.6.0 // indirect 54 | github.com/goccy/go-json v0.9.11 // indirect 55 | github.com/gocql/gocql v1.2.1 // indirect 56 | github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect 57 | github.com/golang-sql/sqlexp v0.1.0 // indirect 58 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect 59 | github.com/golang/protobuf v1.5.2 // indirect 60 | github.com/golang/snappy v0.0.4 // indirect 61 | github.com/google/flatbuffers v22.9.29+incompatible // indirect 62 | github.com/google/go-cmp v0.5.9 // indirect 63 | github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect 64 | github.com/googleapis/gax-go/v2 v2.6.0 // indirect 65 | github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect 66 | github.com/influxdata/influxdb-client-go/v2 v2.11.0 // indirect 67 | github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf // indirect 68 | github.com/jmespath/go-jmespath v0.4.0 // indirect 69 | github.com/jmoiron/sqlx v1.3.5 // indirect 70 | github.com/jpillora/backoff v1.0.0 // indirect 71 | github.com/json-iterator/go v1.1.12 // indirect 72 | github.com/klauspost/compress v1.15.11 // indirect 73 | github.com/lib/pq v1.10.7 // indirect 74 | github.com/linkedin/goavro/v2 v2.12.0 // indirect 75 | github.com/matoous/go-nanoid/v2 v2.0.0 // indirect 76 | github.com/mattn/go-ieproxy v0.0.9 // indirect 77 | github.com/mattn/go-runewidth v0.0.10 // indirect 78 | github.com/mattn/go-sqlite3 v1.14.15 // indirect 79 | github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect 80 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 81 | github.com/modern-go/reflect2 v1.0.2 // indirect 82 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect 83 | github.com/multiprocessio/go-json v0.0.0-20220308002443-61d497dd7b9e // indirect 84 | github.com/multiprocessio/go-openoffice v0.0.0-20220110232726-064f5dda1956 // indirect 85 | github.com/multiprocessio/go-sqlite3-stdlib v0.0.0-20220822170115-9f6825a1cd25 // indirect 86 | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect 87 | github.com/neo4j/neo4j-go-driver/v4 v4.4.4 // indirect 88 | github.com/paulmach/orb v0.7.1 // indirect 89 | github.com/pierrec/lz4/v4 v4.1.17 // indirect 90 | github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect 91 | github.com/pkg/errors v0.9.1 // indirect 92 | github.com/prometheus/client_golang v1.13.0 // indirect 93 | github.com/prometheus/client_model v0.3.0 // indirect 94 | github.com/prometheus/common v0.37.0 // indirect 95 | github.com/prometheus/procfs v0.8.0 // indirect 96 | github.com/richardlehane/mscfb v1.0.4 // indirect 97 | github.com/richardlehane/msoleps v1.0.3 // indirect 98 | github.com/rivo/uniseg v0.1.0 // indirect 99 | github.com/scritchley/orc v0.0.0-20210513144143-06dddf1ad665 // indirect 100 | github.com/segmentio/asm v1.2.0 // indirect 101 | github.com/shopspring/decimal v1.3.1 // indirect 102 | github.com/sijms/go-ora/v2 v2.5.3 // indirect 103 | github.com/sirupsen/logrus v1.9.0 // indirect 104 | github.com/snowflakedb/gosnowflake v1.6.13 // indirect 105 | github.com/tidwall/gjson v1.14.3 // indirect 106 | github.com/tidwall/match v1.1.1 // indirect 107 | github.com/tidwall/pretty v1.2.1 // indirect 108 | github.com/xitongsys/parquet-go v1.6.2 // indirect 109 | github.com/xitongsys/parquet-go-source v0.0.0-20220723234337-052319f3f36b // indirect 110 | github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect 111 | github.com/xuri/excelize/v2 v2.6.1 // indirect 112 | github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect 113 | go.opencensus.io v0.23.0 // indirect 114 | go.opentelemetry.io/otel v1.11.0 // indirect 115 | go.opentelemetry.io/otel/trace v1.11.0 // indirect 116 | golang.org/x/crypto v0.0.0-20221012134737-56aed061732a // indirect 117 | golang.org/x/net v0.0.0-20221019024206-cb67ada4b0ad // indirect 118 | golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 // indirect 119 | golang.org/x/sys v0.1.0 // indirect 120 | golang.org/x/text v0.4.0 // indirect 121 | golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect 122 | gonum.org/v1/gonum v0.12.0 // indirect 123 | google.golang.org/api v0.100.0 // indirect 124 | google.golang.org/appengine v1.6.7 // indirect 125 | google.golang.org/genproto v0.0.0-20221018160656-63c7b68cfc55 // indirect 126 | google.golang.org/grpc v1.50.1 // indirect 127 | google.golang.org/protobuf v1.28.1 // indirect 128 | gopkg.in/inf.v0 v0.9.1 // indirect 129 | gopkg.in/yaml.v2 v2.4.0 // indirect 130 | gopkg.in/yaml.v3 v3.0.1 // indirect 131 | ) 132 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 8 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= 9 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= 10 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= 11 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= 12 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= 13 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= 14 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= 15 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= 16 | cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8= 17 | cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= 18 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 19 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= 20 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= 21 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= 22 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= 23 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 24 | cloud.google.com/go/bigquery v1.42.0 h1:JuTk8po4bCKRwObdT0zLb1K0BGkGHJdtgs2GK3j2Gws= 25 | cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= 26 | cloud.google.com/go/compute v1.10.0 h1:aoLIYaA1fX3ywihqpBk2APQKOo20nXsp1GEZQbx5Jk4= 27 | cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= 28 | cloud.google.com/go/datacatalog v1.6.0 h1:xzXGAE2fAuMh+ksODKr9nRv9ega1vHjFwRqMA8tRrVE= 29 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 30 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= 31 | cloud.google.com/go/iam v0.5.0 h1:fz9X5zyTWBmamZsqvqZqD7khbifcZF/q+Z1J8pfhIUg= 32 | cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= 33 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 34 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 35 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= 36 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= 37 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 38 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= 39 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 40 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= 41 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= 42 | cloud.google.com/go/storage v1.23.0 h1:wWRIaDURQA8xxHguFCshYepGlrWIrbBnAmc7wfg07qY= 43 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 44 | gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= 45 | github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U= 46 | github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= 47 | github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= 48 | github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= 49 | github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= 50 | github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= 51 | github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0/go.mod h1:+6sju8gk8FRmSajX3Oz4G5Gm7P+mbqE9FVaXXFYTkCM= 52 | github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0/go.mod h1:bhXu1AjYL+wutSL/kpSq6s7733q2Rb0yuot9Zgfqa/0= 53 | github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= 54 | github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= 55 | github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1/go.mod h1:eZ4g6GUvXiGulfIbbhh1Xr4XwUYaYaWMqzGD/284wCA= 56 | github.com/Azure/azure-storage-blob-go v0.15.0 h1:rXtgp8tN1p29GvpGgfJetavIG0V7OgcSXPpwp3tx6qk= 57 | github.com/Azure/azure-storage-blob-go v0.15.0/go.mod h1:vbjsVbX0dlxnRc4FFMPsS9BsJWPcne7GB7onqlPvz58= 58 | github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= 59 | github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= 60 | github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q= 61 | github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= 62 | github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= 63 | github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= 64 | github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= 65 | github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= 66 | github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= 67 | github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= 68 | github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= 69 | github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= 70 | github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= 71 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 72 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 73 | github.com/ClickHouse/ch-go v0.48.0 h1:7BIWp+vynGeIEXNtN3K0WQdSgmYAxM+GENnCtTnwN5M= 74 | github.com/ClickHouse/ch-go v0.48.0/go.mod h1:KBY72ltlOlHelc4Jn4hlReP8Caek8d6RG4ZkoPsWxzc= 75 | github.com/ClickHouse/clickhouse-go/v2 v2.3.0 h1:v0iT0yZspjjNgnLyPUa0WoGMme0Y/sNjCtOAFcyBkkA= 76 | github.com/ClickHouse/clickhouse-go/v2 v2.3.0/go.mod h1:f2kb1LPopJdIyt0Y0vxNk9aiQCyhCmeVcyvOOaPCT4Q= 77 | github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= 78 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 79 | github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 80 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 81 | github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 82 | github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= 83 | github.com/alexbrainman/odbc v0.0.0-20211220213544-9c9a2e61c5e2 h1:090cWAt7zsbdvRegKCBVwcCTghjxhUh1PK2KNSq82vw= 84 | github.com/alexbrainman/odbc v0.0.0-20211220213544-9c9a2e61c5e2/go.mod h1:c5eyz5amZqTKvY3ipqerFO/74a/8CYmXOahSr40c+Ww= 85 | github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= 86 | github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= 87 | github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= 88 | github.com/apache/arrow/go/arrow v0.0.0-20200730104253-651201b0f516/go.mod h1:QNYViu/X0HXDHw7m3KXzWSVXIbfUvJqBFe6Gj8/pYA0= 89 | github.com/apache/arrow/go/arrow v0.0.0-20211112161151-bc219186db40 h1:q4dksr6ICHXqG5hm0ZW5IHyeEJXoIJSOZeBLmWPNeIQ= 90 | github.com/apache/arrow/go/arrow v0.0.0-20211112161151-bc219186db40/go.mod h1:Q7yQnSMnLvcXlZ8RV+jwz/6y1rQTqbX6C82SndT52Zs= 91 | github.com/apache/thrift v0.0.0-20181112125854-24918abba929/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= 92 | github.com/apache/thrift v0.14.2/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= 93 | github.com/apache/thrift v0.17.0 h1:cMd2aj52n+8VoAtvSvLn4kDC3aZ6IAkBuqWQ2IDu7wo= 94 | github.com/apache/thrift v0.17.0/go.mod h1:OLxhMRJxomX+1I/KUw03qoV3mMz16BwaKI+d4fPBx7Q= 95 | github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA= 96 | github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw= 97 | github.com/aws/aws-sdk-go v1.30.19/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= 98 | github.com/aws/aws-sdk-go v1.44.118 h1:FJOqIRTukf7+Ulp047/k7JB6eqMXNnj7eb+coORThHQ= 99 | github.com/aws/aws-sdk-go v1.44.118/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= 100 | github.com/aws/aws-sdk-go-v2 v1.7.1/go.mod h1:L5LuPC1ZgDr2xQS7AmIec/Jlc7O/Y1u2KxJyNVab250= 101 | github.com/aws/aws-sdk-go-v2 v1.16.16 h1:M1fj4FE2lB4NzRb9Y0xdWsn2P0+2UHVxwKyOa4YJNjk= 102 | github.com/aws/aws-sdk-go-v2 v1.16.16/go.mod h1:SwiyXi/1zTUZ6KIAmLK5V5ll8SiURNUYOqTerZPaF9k= 103 | github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.8 h1:tcFliCWne+zOuUfKNRn8JdFBuWPDuISDH08wD2ULkhk= 104 | github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.8/go.mod h1:JTnlBSot91steJeti4ryyu/tLd4Sk84O5W22L7O2EQU= 105 | github.com/aws/aws-sdk-go-v2/config v1.5.0/go.mod h1:RWlPOAW3E3tbtNAqTwvSW54Of/yP3oiZXMI0xfUdjyA= 106 | github.com/aws/aws-sdk-go-v2/config v1.17.8 h1:b9LGqNnOdg9vR4Q43tBTVWk4J6F+W774MSchvKJsqnE= 107 | github.com/aws/aws-sdk-go-v2/config v1.17.8/go.mod h1:UkCI3kb0sCdvtjiXYiU4Zx5h07BOpgBTtkPu/49r+kA= 108 | github.com/aws/aws-sdk-go-v2/credentials v1.3.1/go.mod h1:r0n73xwsIVagq8RsxmZbGSRQFj9As3je72C2WzUIToc= 109 | github.com/aws/aws-sdk-go-v2/credentials v1.12.21 h1:4tjlyCD0hRGNQivh5dN8hbP30qQhMLBE/FgQR1vHHWM= 110 | github.com/aws/aws-sdk-go-v2/credentials v1.12.21/go.mod h1:O+4XyAt4e+oBAoIwNUYkRg3CVMscaIJdmZBOcPgJ8D8= 111 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.3.0/go.mod h1:2LAuqPx1I6jNfaGDucWfA2zqQCYCOMCDHiCOciALyNw= 112 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17 h1:r08j4sbZu/RVi+BNxkBJwPMUYY3P8mgSDuKkZ/ZN1lE= 113 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17/go.mod h1:yIkQcCDYNsZfXpd5UX2Cy+sWA1jPgIhGTw9cOBzfVnQ= 114 | github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.3.2/go.mod h1:qaqQiHSrOUVOfKe6fhgQ6UzhxjwqVW8aHNegd6Ws4w4= 115 | github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.34 h1:1PNtaCM+2ruo1dfYL2RweUdtbuPvinjAejjNcPa/RQY= 116 | github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.34/go.mod h1:+Six+CXNHYllXam32j+YW8ixk82+am345ei89kEz8p4= 117 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23 h1:s4g/wnzMf+qepSNgTvaQQHNxyMLKSawNhKCPNy++2xY= 118 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23/go.mod h1:2DFxAQ9pfIRy0imBCJv+vZ2X6RKxves6fbnEuSry6b4= 119 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17 h1:/K482T5A3623WJgWT8w1yRAFK4RzGzEl7y39yhtn9eA= 120 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17/go.mod h1:pRwaTYCJemADaqCbUAxltMoHKata7hmB5PjEXeu0kfg= 121 | github.com/aws/aws-sdk-go-v2/internal/ini v1.1.1/go.mod h1:Zy8smImhTdOETZqfyn01iNOe0CNggVbPjCajyaz6Gvg= 122 | github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24 h1:wj5Rwc05hvUSvKuOF29IYb9QrCLjU+rHAy/x/o0DK2c= 123 | github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24/go.mod h1:jULHjqqjDlbyTa7pfM7WICATnOv+iOhjletM3N0Xbu8= 124 | github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14 h1:ZSIPAkAsCCjYrhqfw2+lNzWDzxzHXEckFkTePL5RSWQ= 125 | github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.14/go.mod h1:AyGgqiKv9ECM6IZeNQtdT8NnMvUb3/2wokeq2Fgryto= 126 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.2.1/go.mod h1:v33JQ57i2nekYTA70Mb+O18KeH4KqhdqxTJZNK1zdRE= 127 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9 h1:Lh1AShsuIJTwMkoxVCAYPJgNG5H+eN6SmoUn8nOZ5wE= 128 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.9/go.mod h1:a9j48l6yL5XINLHLcOKInjdvknN+vWqPBxqeIDw7ktw= 129 | github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18 h1:BBYoNQt2kUZUUK4bIPsKrCcjVPUMNsgQpNAwhznK/zo= 130 | github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.18/go.mod h1:NS55eQ4YixUJPTC+INxi2/jCqe1y2Uw3rnh9wEOVJxY= 131 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.2.1/go.mod h1:zceowr5Z1Nh2WVP8bf/3ikB41IZW59E4yIYbg+pC6mw= 132 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17 h1:Jrd/oMh0PKQc6+BowB+pLEwLIgaQF29eYbe7E1Av9Ug= 133 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17/go.mod h1:4nYOrY41Lrbk2170/BGkcJKBhws9Pfn8MG3aGqjjeFI= 134 | github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.5.1/go.mod h1:6EQZIwNNvHpq/2/QSJnp4+ECvqIy55w95Ofs0ze+nGQ= 135 | github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.17 h1:HfVVR1vItaG6le+Bpw6P4midjBDMKnjMyZnw9MXYUcE= 136 | github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.17/go.mod h1:YqMdV+gEKCQ59NrB7rzrJdALeBIsYiVi8Inj3+KcqHI= 137 | github.com/aws/aws-sdk-go-v2/service/s3 v1.11.1/go.mod h1:XLAGFrEjbvMCLvAtWLLP32yTv8GpBquCApZEycDLunI= 138 | github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11 h1:3/gm/JTX9bX8CpzTgIlrtYpB3EVBDxyg/GY/QdcIEZw= 139 | github.com/aws/aws-sdk-go-v2/service/s3 v1.27.11/go.mod h1:fmgDANqTUCxciViKl9hb/zD5LFbvPINFRgWhDbR+vZo= 140 | github.com/aws/aws-sdk-go-v2/service/sso v1.3.1/go.mod h1:J3A3RGUvuCZjvSuZEcOpHDnzZP/sKbhDWV2T1EOzFIM= 141 | github.com/aws/aws-sdk-go-v2/service/sso v1.11.23 h1:pwvCchFUEnlceKIgPUouBJwK81aCkQ8UDMORfeFtW10= 142 | github.com/aws/aws-sdk-go-v2/service/sso v1.11.23/go.mod h1:/w0eg9IhFGjGyyncHIQrXtU8wvNsTJOP0R6PPj0wf80= 143 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.6 h1:OwhhKc1P9ElfWbMKPIbMMZBV6hzJlL2JKD76wNNVzgQ= 144 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.6/go.mod h1:csZuQY65DAdFBt1oIjO5hhBR49kQqop4+lcuCjf2arA= 145 | github.com/aws/aws-sdk-go-v2/service/sts v1.6.0/go.mod h1:q7o0j7d7HrJk/vr9uUt3BVRASvcU7gYZB9PUgPiByXg= 146 | github.com/aws/aws-sdk-go-v2/service/sts v1.16.19 h1:9pPi0PsFNAGILFfPCk8Y0iyEBGc6lu6OQ97U7hmdesg= 147 | github.com/aws/aws-sdk-go-v2/service/sts v1.16.19/go.mod h1:h4J3oPZQbxLhzGnk+j9dfYHi5qIOVJ5kczZd658/ydM= 148 | github.com/aws/smithy-go v1.6.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= 149 | github.com/aws/smithy-go v1.13.3 h1:l7LYxGuzK6/K+NzJ2mC+VvLUbae0sL3bXU//04MkmnA= 150 | github.com/aws/smithy-go v1.13.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= 151 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 152 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 153 | github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= 154 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 155 | github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= 156 | github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= 157 | github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= 158 | github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= 159 | github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= 160 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 161 | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 162 | github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= 163 | github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 164 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 165 | github.com/chzyer/logex v1.2.0 h1:+eqR0HfOetur4tgnC8ftU5imRnhi4te+BadWS95c5AM= 166 | github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= 167 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 168 | github.com/chzyer/readline v1.5.0 h1:lSwwFrbNviGePhkewF1az4oLmcwqCZijQ2/Wi3BGHAI= 169 | github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= 170 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 171 | github.com/chzyer/test v0.0.0-20210722231415-061457976a23 h1:dZ0/VyGgQdVGAss6Ju0dt5P0QltE0SFY5Woh6hbIfiQ= 172 | github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 173 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 174 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 175 | github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 176 | github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 177 | github.com/colinmarc/hdfs/v2 v2.1.1/go.mod h1:M3x+k8UKKmxtFu++uAZ0OtDU8jR3jnaZIAc6yK4Ue0c= 178 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 179 | github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= 180 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 181 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 182 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 183 | github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= 184 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE= 185 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= 186 | github.com/deepmap/oapi-codegen v1.11.0 h1:f/X2NdIkaBKsSdpeuwLnY/vDI0AtPUrmB5LMgc7YD+A= 187 | github.com/deepmap/oapi-codegen v1.11.0/go.mod h1:k+ujhoQGxmQYBZBbxhOZNZf4j08qv5mC+OH+fFTnKxM= 188 | github.com/denisenkom/go-mssqldb v0.12.3 h1:pBSGx9Tq67pBOTLmxNuirNTeB8Vjmf886Kx+8Y+8shw= 189 | github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo= 190 | github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= 191 | github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= 192 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 193 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 194 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 195 | github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 196 | github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 197 | github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= 198 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 199 | github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3 h1:fmFk0Wt3bBxxwZnu48jqMdaOR/IZ4vdtJFuaFV8MpIE= 200 | github.com/flosch/pongo2 v0.0.0-20200913210552-0d938eb266f3/go.mod h1:bJWSKrZyQvfTnb2OudyUjurSG4/edverV7n82+K3JiM= 201 | github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 202 | github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= 203 | github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= 204 | github.com/form3tech-oss/jwt-go v3.2.5+incompatible h1:/l4kBbb4/vGSsdtB5nUe8L7B9mImVMaBPw9L/0TBHU8= 205 | github.com/form3tech-oss/jwt-go v3.2.5+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= 206 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= 207 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 208 | github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= 209 | github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= 210 | github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= 211 | github.com/getkin/kin-openapi v0.94.0/go.mod h1:LWZfzOd7PRy8GJ1dJ6mCU6tNdSfOwRac1BUPam4aw6Q= 212 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 213 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 214 | github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= 215 | github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= 216 | github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= 217 | github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= 218 | github.com/go-faster/errors v0.6.1 h1:nNIPOBkprlKzkThvS/0YaX8Zs9KewLCOSFQS5BU06FI= 219 | github.com/go-faster/errors v0.6.1/go.mod h1:5MGV2/2T9yvlrbhe9pD9LO5Z/2zCSq2T8j+Jpi2LAyY= 220 | github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= 221 | github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks= 222 | github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= 223 | github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= 224 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 225 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 226 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 227 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 228 | github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 229 | github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= 230 | github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= 231 | github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U= 232 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 233 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 234 | github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= 235 | github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= 236 | github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= 237 | github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= 238 | github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= 239 | github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= 240 | github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= 241 | github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= 242 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 243 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= 244 | github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= 245 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= 246 | github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= 247 | github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= 248 | github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= 249 | github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 250 | github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= 251 | github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= 252 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 253 | github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= 254 | github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 255 | github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= 256 | github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= 257 | github.com/gocql/gocql v1.2.1 h1:G/STxUzD6pGvRHzG0Fi7S04SXejMKBbRZb7pwre1edU= 258 | github.com/gocql/gocql v1.2.1/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= 259 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 260 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 261 | github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= 262 | github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= 263 | github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= 264 | github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= 265 | github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= 266 | github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= 267 | github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= 268 | github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= 269 | github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= 270 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 271 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 272 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 273 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 274 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= 275 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 276 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 277 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 278 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 279 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 280 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 281 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 282 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 283 | github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 284 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 285 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 286 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 287 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 288 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 289 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 290 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 291 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 292 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 293 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 294 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 295 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 296 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 297 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 298 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 299 | github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 300 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 301 | github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 302 | github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 303 | github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 304 | github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= 305 | github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 306 | github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= 307 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 308 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 309 | github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= 310 | github.com/google/flatbuffers v2.0.0+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= 311 | github.com/google/flatbuffers v22.9.29+incompatible h1:3UBb679lq3V/O9rgzoJmnkP1jJzmC9OdFzITUBkLU/A= 312 | github.com/google/flatbuffers v22.9.29+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= 313 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 314 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 315 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 316 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 317 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 318 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 319 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 320 | github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 321 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 322 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 323 | github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 324 | github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 325 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 326 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 327 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 328 | github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= 329 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 330 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 331 | github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= 332 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 333 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 334 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 335 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 336 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 337 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 338 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 339 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 340 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 341 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 342 | github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 343 | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 344 | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 345 | github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= 346 | github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= 347 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 348 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 349 | github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= 350 | github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= 351 | github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= 352 | github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 353 | github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= 354 | github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= 355 | github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= 356 | github.com/hashicorp/go-uuid v0.0.0-20180228145832-27454136f036/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 357 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 358 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 359 | github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= 360 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 361 | github.com/influxdata/influxdb-client-go/v2 v2.11.0 h1:BrHYv38rWkAnp22gIaHFp5LpOCazOqRMRvVE1yW3ym8= 362 | github.com/influxdata/influxdb-client-go/v2 v2.11.0/go.mod h1:YteV91FiQxRdccyJ2cHvj2f/5sq4y4Njqu1fQzsQCOU= 363 | github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf h1:7JTmneyiNEwVBOHSjoMxiWAqB992atOeepeFYegn5RU= 364 | github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= 365 | github.com/jcmturner/gofork v0.0.0-20180107083740-2aebee971930/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= 366 | github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= 367 | github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= 368 | github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= 369 | github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= 370 | github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= 371 | github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= 372 | github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= 373 | github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= 374 | github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= 375 | github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= 376 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 377 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 378 | github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 379 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 380 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 381 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 382 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 383 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 384 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 385 | github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= 386 | github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= 387 | github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= 388 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 389 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 390 | github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= 391 | github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= 392 | github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= 393 | github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= 394 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 395 | github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 396 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 397 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 398 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 399 | github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= 400 | github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= 401 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 402 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 403 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 404 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 405 | github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= 406 | github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= 407 | github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= 408 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 409 | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= 410 | github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y= 411 | github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ= 412 | github.com/lestrrat-go/blackmagic v1.0.1/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= 413 | github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= 414 | github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc= 415 | github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= 416 | github.com/lestrrat-go/jwx v1.2.24/go.mod h1:zoNuZymNl5lgdcu6P7K6ie2QRll5HVfF4xwxBBK1NxY= 417 | github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= 418 | github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= 419 | github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= 420 | github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= 421 | github.com/linkedin/goavro/v2 v2.12.0 h1:rIQQSj8jdAUlKQh6DttK8wCRv4t4QO09g1C4aBWXslg= 422 | github.com/linkedin/goavro/v2 v2.12.0/go.mod h1:KXx+erlq+RPlGSPmLF7xGo6SAbh8sCQ53x064+ioxhk= 423 | github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 424 | github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 425 | github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 426 | github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= 427 | github.com/matoous/go-nanoid v1.5.0/go.mod h1:zyD2a71IubI24efhpvkJz+ZwfwagzgSO6UNiFsZKN7U= 428 | github.com/matoous/go-nanoid/v2 v2.0.0 h1:d19kur2QuLeHmJBkvYkFdhFBzLoo1XVm2GgTpL+9Tj0= 429 | github.com/matoous/go-nanoid/v2 v2.0.0/go.mod h1:FtS4aGPVfEkxKxhdWPAspZpZSh1cOjtM7Ej/So3hR0g= 430 | github.com/matryer/moq v0.2.7/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk= 431 | github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 432 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 433 | github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= 434 | github.com/mattn/go-ieproxy v0.0.9 h1:RvVbLiMv/Hbjf1gRaC2AQyzwbdVhdId7D2vPnXIml4k= 435 | github.com/mattn/go-ieproxy v0.0.9/go.mod h1:eF30/rfdQUO9EnzNIZQr0r9HiLMlZNCpJkHbmMuOAE0= 436 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 437 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 438 | github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 439 | github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg= 440 | github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= 441 | github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= 442 | github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= 443 | github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= 444 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 445 | github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM= 446 | github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= 447 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 448 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 449 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 450 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 451 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 452 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 453 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 454 | github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= 455 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= 456 | github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= 457 | github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= 458 | github.com/multiprocessio/datastation/runner v0.0.0-20221019004540-4e72a6e0af28 h1:Jfsq/7n2TbloeBVPyprmqKMmyXlY7UXa+Elx7RCJvGU= 459 | github.com/multiprocessio/datastation/runner v0.0.0-20221019004540-4e72a6e0af28/go.mod h1:PNGhFimdy6sGijegoqtM90iD1kziOynbzMdq35Lc4rk= 460 | github.com/multiprocessio/go-json v0.0.0-20220308002443-61d497dd7b9e h1:NlPl7amllnQyVAkZgjBvFEkKxJSba/R8ZpaTodc7SIQ= 461 | github.com/multiprocessio/go-json v0.0.0-20220308002443-61d497dd7b9e/go.mod h1:huI4M/MrI5px/SgmXYi0a2byKikSLgDrnMQuXOqKtw4= 462 | github.com/multiprocessio/go-openoffice v0.0.0-20220110232726-064f5dda1956 h1:WVofL03Eq+z3LbDOfH5eKzu2U85LFZZngOMBlNaO/H0= 463 | github.com/multiprocessio/go-openoffice v0.0.0-20220110232726-064f5dda1956/go.mod h1:JMhCobMOTCgIL4EwBPVrRB60Iq9hknRP9mX/MYiWHAc= 464 | github.com/multiprocessio/go-sqlite3-stdlib v0.0.0-20220822170115-9f6825a1cd25 h1:bnhGk2UFFPqylhxTEffs1ehDRn4bEZsEoDH53Z4HqA8= 465 | github.com/multiprocessio/go-sqlite3-stdlib v0.0.0-20220822170115-9f6825a1cd25/go.mod h1:RrGEZqqiyEcLyTVLDSgtNZVLqJykj0F4vwuuqvMdT60= 466 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 467 | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= 468 | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 469 | github.com/ncw/swift v1.0.52/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= 470 | github.com/neo4j/neo4j-go-driver/v4 v4.4.4 h1:SWVwM+F76eGeJaXSOw61zn5MHpHHsaM75ceRZytst9U= 471 | github.com/neo4j/neo4j-go-driver/v4 v4.4.4/go.mod h1:NexOfrm4c317FVjekrhVV8pHBXgtMG5P6GeweJWCyo4= 472 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 473 | github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= 474 | github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= 475 | github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= 476 | github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= 477 | github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= 478 | github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= 479 | github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= 480 | github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= 481 | github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= 482 | github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= 483 | github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= 484 | github.com/paulmach/orb v0.7.1 h1:Zha++Z5OX/l168sqHK3k4z18LDvr+YAO/VjK0ReQ9rU= 485 | github.com/paulmach/orb v0.7.1/go.mod h1:FWRlTgl88VI1RBx/MkrwWDRhQ96ctqMCh8boXhmqB/A= 486 | github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= 487 | github.com/pborman/getopt v0.0.0-20180729010549-6fdd0a2c7117/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= 488 | github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= 489 | github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= 490 | github.com/pierrec/lz4/v4 v4.1.8/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= 491 | github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc= 492 | github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= 493 | github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= 494 | github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= 495 | github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= 496 | github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= 497 | github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 498 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 499 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 500 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 501 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 502 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 503 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 504 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 505 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= 506 | github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= 507 | github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= 508 | github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= 509 | github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= 510 | github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= 511 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 512 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 513 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 514 | github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 515 | github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= 516 | github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= 517 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 518 | github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= 519 | github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= 520 | github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= 521 | github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= 522 | github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= 523 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 524 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 525 | github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= 526 | github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= 527 | github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= 528 | github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= 529 | github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= 530 | github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM= 531 | github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= 532 | github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= 533 | github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM= 534 | github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= 535 | github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY= 536 | github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 537 | github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= 538 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 539 | github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= 540 | github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= 541 | github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= 542 | github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= 543 | github.com/scritchley/orc v0.0.0-20210513144143-06dddf1ad665 h1:W7Y6ejGhTaW9WlWhTtxE8f+SOa3c1NoFWsU9XT2cUOY= 544 | github.com/scritchley/orc v0.0.0-20210513144143-06dddf1ad665/go.mod h1:U4h1RViHcbDQl9stSaImdd7N3/ZnUkZ2yombj5cSgEY= 545 | github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= 546 | github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= 547 | github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= 548 | github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= 549 | github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= 550 | github.com/sijms/go-ora/v2 v2.5.3 h1:klGKmhqRONVTtIzTdfYTvrW94kdJkdmZl93u2A3vchI= 551 | github.com/sijms/go-ora/v2 v2.5.3/go.mod h1:EHxlY6x7y9HAsdfumurRfTd+v8NrEOTR3Xl4FWlH6xk= 552 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 553 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 554 | github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= 555 | github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= 556 | github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= 557 | github.com/snowflakedb/gosnowflake v1.6.13 h1:r8iozak/p3P2jYfjF3EbeteqMMzPWjwmVrdENJDW6EI= 558 | github.com/snowflakedb/gosnowflake v1.6.13/go.mod h1:BoZ0gnLERaUEiziH4Dumim10LN8cvoaCKovsAfhxzrE= 559 | github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= 560 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 561 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 562 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 563 | github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 564 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 565 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 566 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 567 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 568 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 569 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 570 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 571 | github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 572 | github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= 573 | github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw= 574 | github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= 575 | github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= 576 | github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= 577 | github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= 578 | github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= 579 | github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= 580 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 581 | github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= 582 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 583 | github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= 584 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 585 | github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= 586 | github.com/xitongsys/parquet-go v1.5.1/go.mod h1:xUxwM8ELydxh4edHGegYq1pA8NnMKDx0K/GyB0o2bww= 587 | github.com/xitongsys/parquet-go v1.6.2 h1:MhCaXii4eqceKPu9BwrjLqyK10oX9WF+xGhwvwbw7xM= 588 | github.com/xitongsys/parquet-go v1.6.2/go.mod h1:IulAQyalCm0rPiZVNnCgm/PCL64X2tdSVGMQ/UeKqWA= 589 | github.com/xitongsys/parquet-go-source v0.0.0-20190524061010-2b72cbee77d5/go.mod h1:xxCx7Wpym/3QCo6JhujJX51dzSXrwmb0oH6FQb39SEA= 590 | github.com/xitongsys/parquet-go-source v0.0.0-20200817004010-026bad9b25d0/go.mod h1:HYhIKsdns7xz80OgkbgJYrtQY7FjHWHKH6cvN7+czGE= 591 | github.com/xitongsys/parquet-go-source v0.0.0-20220723234337-052319f3f36b h1:tA9vmqC+hxBElCuZLUQAw4TGMs9kXjF5UJNZHLQUJ/4= 592 | github.com/xitongsys/parquet-go-source v0.0.0-20220723234337-052319f3f36b/go.mod h1:YFoRvz/hJ2HUiZGjjk3HfzHYS/Yt/R/K27cGKokTE28= 593 | github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj09jdMlkY0aiA6+Skbtl3/c= 594 | github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= 595 | github.com/xuri/excelize/v2 v2.6.1 h1:ICBdtw803rmhLN3zfvyEGH3cwSmZv+kde7LhTDT659k= 596 | github.com/xuri/excelize/v2 v2.6.1/go.mod h1:tL+0m6DNwSXj/sILHbQTYsLi9IF4TW59H2EF3Yrx1AU= 597 | github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M= 598 | github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= 599 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 600 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 601 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 602 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 603 | github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 604 | github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 605 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 606 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 607 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 608 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 609 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 610 | go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= 611 | go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= 612 | go.opentelemetry.io/otel v1.11.0 h1:kfToEGMDq6TrVrJ9Vht84Y8y9enykSZzDDZglV0kIEk= 613 | go.opentelemetry.io/otel v1.11.0/go.mod h1:H2KtuEphyMvlhZ+F7tg9GRhAOe60moNx61Ex+WmiKkk= 614 | go.opentelemetry.io/otel/trace v1.11.0 h1:20U/Vj42SX+mASlXLmSGBg6jpI1jQtv682lZtTAOVFI= 615 | go.opentelemetry.io/otel/trace v1.11.0/go.mod h1:nyYjis9jy0gytE9LXGU+/m1sHTKbRY0fX0hulNNDP1U= 616 | go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= 617 | golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 618 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 619 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 620 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 621 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 622 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 623 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 624 | golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 625 | golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 626 | golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 627 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 628 | golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 629 | golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 630 | golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 631 | golang.org/x/crypto v0.0.0-20220513210258-46612604a0f9/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 632 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 633 | golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 634 | golang.org/x/crypto v0.0.0-20221012134737-56aed061732a h1:NmSIgad6KjE6VvHciPZuNRTKxGhlPfD6OA87W/PLkqg= 635 | golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 636 | golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 637 | golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 638 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 639 | golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 640 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 641 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 642 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 643 | golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= 644 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 645 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 646 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 647 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 648 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= 649 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y= 650 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 651 | golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= 652 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 653 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 654 | golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 655 | golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 656 | golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 657 | golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 658 | golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 659 | golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 660 | golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE= 661 | golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= 662 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 663 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 664 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 665 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 666 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 667 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 668 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 669 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 670 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 671 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 672 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 673 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 674 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 675 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 676 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 677 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 678 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 679 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 680 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 681 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 682 | golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= 683 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 684 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 685 | golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 686 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 687 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 688 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 689 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 690 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 691 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 692 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 693 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 694 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 695 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 696 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 697 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 698 | golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 699 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 700 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 701 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 702 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 703 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 704 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 705 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 706 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 707 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 708 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 709 | golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 710 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 711 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 712 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 713 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 714 | golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 715 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 716 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 717 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 718 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 719 | golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= 720 | golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 721 | golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 722 | golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 723 | golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 724 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 725 | golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 726 | golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 727 | golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 728 | golang.org/x/net v0.0.0-20220513224357-95641704303c/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= 729 | golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 730 | golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 731 | golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= 732 | golang.org/x/net v0.0.0-20221019024206-cb67ada4b0ad h1:Zx6wVVDwwNJFWXNIvDi7o952w3/1ckSwYk/7eykRmjM= 733 | golang.org/x/net v0.0.0-20221019024206-cb67ada4b0ad/go.mod h1:RpDiru2p0u2F0lLpEoqnP2+7xs0ifAuOcJ442g6GU2s= 734 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 735 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 736 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 737 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 738 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 739 | golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 740 | golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= 741 | golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 h1:nt+Q6cXKz4MosCSpnbMtqiQ8Oz0pxTef2B4Vca2lvfk= 742 | golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= 743 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 744 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 745 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 746 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 747 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 748 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 749 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 750 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 751 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 752 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 753 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 754 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 755 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 756 | golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 757 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 758 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 759 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 760 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 761 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 762 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 763 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 764 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 765 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 766 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 767 | golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 768 | golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 769 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 770 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 771 | golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 772 | golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 773 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 774 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 775 | golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 776 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 777 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 778 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 779 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 780 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 781 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 782 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 783 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 784 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 785 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 786 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 787 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 788 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 789 | golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 790 | golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 791 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 792 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 793 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 794 | golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 795 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 796 | golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 797 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 798 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 799 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 800 | golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 801 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 802 | golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 803 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 804 | golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 805 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 806 | golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 807 | golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 808 | golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 809 | golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 810 | golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 811 | golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 812 | golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 813 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 814 | golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 815 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 816 | golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 817 | golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= 818 | golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 819 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 820 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= 821 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 822 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 823 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 824 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 825 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 826 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 827 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 828 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 829 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 830 | golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= 831 | golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 832 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 833 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 834 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 835 | golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 836 | golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 837 | golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 838 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 839 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 840 | golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 841 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 842 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 843 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 844 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 845 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 846 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 847 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 848 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 849 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 850 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 851 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 852 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 853 | golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 854 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 855 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 856 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 857 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 858 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 859 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 860 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 861 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 862 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 863 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 864 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 865 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 866 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 867 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 868 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 869 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 870 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 871 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 872 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= 873 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 874 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 875 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 876 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 877 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 878 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 879 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 880 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 881 | golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 882 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 883 | golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 884 | golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= 885 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 886 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 887 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 888 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 889 | golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 890 | golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= 891 | golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= 892 | gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= 893 | gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= 894 | gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= 895 | gonum.org/v1/gonum v0.12.0 h1:xKuo6hzt+gMav00meVPUlXwSdoEJP46BR+wdxQEFK2o= 896 | gonum.org/v1/gonum v0.12.0/go.mod h1:73TDxJfAAHeA8Mk9mf8NlIppyhQNo5GLTcYeqgo2lvY= 897 | gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= 898 | gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= 899 | gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= 900 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 901 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 902 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 903 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 904 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 905 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 906 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 907 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 908 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 909 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 910 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 911 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 912 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 913 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 914 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= 915 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= 916 | google.golang.org/api v0.100.0 h1:LGUYIrbW9pzYQQ8NWXlaIVkgnfubVBZbMFb9P8TK374= 917 | google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= 918 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 919 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 920 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 921 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 922 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 923 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 924 | google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= 925 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 926 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 927 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 928 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 929 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 930 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 931 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 932 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 933 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 934 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 935 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 936 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 937 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 938 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 939 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 940 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= 941 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 942 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 943 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 944 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 945 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 946 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 947 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 948 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 949 | google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 950 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= 951 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 952 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= 953 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 954 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 955 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 956 | google.golang.org/genproto v0.0.0-20210630183607-d20f26d13c79/go.mod h1:yiaVoXHpRzHGyxV3o4DktVWY4mSUErTKaeEOq6C3t3U= 957 | google.golang.org/genproto v0.0.0-20221018160656-63c7b68cfc55 h1:U1u4KB2kx6KR/aJDjQ97hZ15wQs8ZPvDcGcRynBhkvg= 958 | google.golang.org/genproto v0.0.0-20221018160656-63c7b68cfc55/go.mod h1:45EK0dUbEZ2NHjCeAd2LXmyjAgGUGrpGROgjhC3ADck= 959 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 960 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 961 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 962 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 963 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 964 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 965 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 966 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 967 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= 968 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 969 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 970 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 971 | google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= 972 | google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= 973 | google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 974 | google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 975 | google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= 976 | google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= 977 | google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= 978 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 979 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 980 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 981 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 982 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 983 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 984 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 985 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 986 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 987 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 988 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 989 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 990 | google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 991 | google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 992 | google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= 993 | google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 994 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 995 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 996 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 997 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 998 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 999 | gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 1000 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 1001 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 1002 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 1003 | gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= 1004 | gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= 1005 | gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= 1006 | gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= 1007 | gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= 1008 | gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= 1009 | gopkg.in/jcmturner/gokrb5.v7 v7.3.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= 1010 | gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= 1011 | gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 1012 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 1013 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 1014 | gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 1015 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 1016 | gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 1017 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 1018 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 1019 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 1020 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 1021 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 1022 | gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 1023 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 1024 | gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 1025 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 1026 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 1027 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 1028 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 1029 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 1030 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 1031 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 1032 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 1033 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 1034 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 1035 | rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 1036 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= 1037 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 1038 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/sha1" 5 | "encoding/hex" 6 | "encoding/json" 7 | "errors" 8 | "fmt" 9 | "hash" 10 | "io" 11 | "log" 12 | "math/rand" 13 | "os" 14 | "path" 15 | "path/filepath" 16 | "regexp" 17 | "sort" 18 | "strconv" 19 | "strings" 20 | "time" 21 | 22 | "github.com/chzyer/readline" 23 | "github.com/multiprocessio/datastation/runner" 24 | 25 | "github.com/google/uuid" 26 | "github.com/olekukonko/tablewriter" 27 | ) 28 | 29 | func resolveContentType(fileExtensionOrContentType string) runner.MimeType { 30 | if strings.Contains(fileExtensionOrContentType, string(filepath.Separator)) { 31 | return runner.MimeType(fileExtensionOrContentType) 32 | } 33 | 34 | return runner.GetMimeType("x."+fileExtensionOrContentType, runner.ContentTypeInfo{}) 35 | } 36 | 37 | func evalFileInto(file, mimetype string, convertNumbers bool, w *runner.ResultWriter) error { 38 | if mimetype == "" { 39 | mimetype = string(runner.GetMimeType(file, runner.ContentTypeInfo{})) 40 | } else { 41 | mimetype = string(resolveContentType(mimetype)) 42 | } 43 | 44 | if mimetype == "" { 45 | return fmt.Errorf("Unknown mimetype for file: %s.\n", file) 46 | } 47 | 48 | return runner.TransformFile(file, runner.ContentTypeInfo{ 49 | Type: mimetype, 50 | ConvertNumbers: convertNumbers, 51 | }, w) 52 | } 53 | 54 | var tableFileRe = regexp.MustCompile(`({(?P[0-9]+)(((,\s*(?P"(?:[^"\\]|\\.)*\"))?)|(,\s*(?P'(?:[^'\\]|\\.)*\'))?)})|({((((?P"(?:[^"\\]|\\.)*\"))?)|((?P'(?:[^'\\]|\\.)*\'))?)})`) 55 | 56 | func rewriteQuery(query string, resolveDM_getPanelToId *map[string]string) string { 57 | query = strings.ReplaceAll(query, "{}", "{0}") 58 | 59 | query = tableFileRe.ReplaceAllStringFunc(query, func(m string) string { 60 | matchForSubexps := tableFileRe.FindStringSubmatch(m) 61 | index := "0" 62 | path := "" 63 | for i, name := range tableFileRe.SubexpNames() { 64 | if matchForSubexps[i] == "" { 65 | continue 66 | } 67 | 68 | switch name { 69 | case "number": 70 | index = matchForSubexps[i] 71 | case "numberdoublepath", "numbersinglepath", "doublepath", "singlepath": 72 | path = matchForSubexps[i] 73 | } 74 | } 75 | 76 | if path != "" { 77 | return fmt.Sprintf("DM_getPanel(%s, %s)", index, path) 78 | } 79 | 80 | if resolveDM_getPanelToId != nil { 81 | return "\"" + (*resolveDM_getPanelToId)[index] + "\"" 82 | } 83 | 84 | return fmt.Sprintf("DM_getPanel(%s)", index) 85 | }) 86 | 87 | return query 88 | } 89 | 90 | func dumpJSONFile(file string, pretty bool, schema bool) error { 91 | fd, err := os.Open(file) 92 | if err != nil { 93 | return err 94 | } 95 | defer fd.Close() 96 | 97 | size := int64(-1) 98 | fi, err := fd.Stat() 99 | if err == nil { 100 | size = fi.Size() 101 | } 102 | 103 | if schema { 104 | s, err := runner.ShapeFromFile(file, "doesn't-matter", runner.DefaultShapeMaxBytesToRead, 100) 105 | if err != nil { 106 | return err 107 | } 108 | 109 | if pretty { 110 | _, err = fmt.Fprintf(os.Stdout, "%s\n", s.Pretty("")) 111 | return err 112 | } 113 | 114 | enc := json.NewEncoder(os.Stdout) 115 | enc.SetIndent("", " ") 116 | return enc.Encode(s) 117 | } 118 | 119 | if !pretty { 120 | // Dump the result to stdout 121 | _, err := io.Copy(os.Stdout, fd) 122 | if err != nil { 123 | return err 124 | } 125 | // This is intentional to add a newline 126 | fmt.Println() 127 | return nil 128 | } 129 | 130 | var rows []map[string]interface{} 131 | if size != 0 { 132 | s, err := runner.ShapeFromFile(file, "doesn't-matter", runner.DefaultShapeMaxBytesToRead, 100) 133 | if err != nil { 134 | return err 135 | } 136 | var columns []string 137 | for name := range s.ArrayShape.Children.ObjectShape.Children { 138 | columns = append(columns, name) 139 | } 140 | sort.Strings(columns) 141 | 142 | table := tablewriter.NewWriter(os.Stdout) 143 | table.SetHeader(columns) 144 | table.SetAutoFormatHeaders(false) 145 | 146 | dec := json.NewDecoder(fd) 147 | err = dec.Decode(&rows) 148 | if err != nil { 149 | return err 150 | } 151 | 152 | for _, objRow := range rows { 153 | var row []string 154 | for _, column := range columns { 155 | var cell string 156 | switch t := objRow[column].(type) { 157 | case bool, byte, complex64, complex128, error, float32, float64, 158 | int, int8, int16, int32, int64, 159 | uint, uint16, uint32, uint64, uintptr: 160 | cell = fmt.Sprintf("%#v", t) 161 | case string: 162 | cell = t 163 | default: 164 | cellBytes, _ := json.Marshal(t) 165 | cell = string(cellBytes) 166 | } 167 | row = append(row, cell) 168 | } 169 | table.Append(row) 170 | } 171 | 172 | table.Render() 173 | } 174 | 175 | if len(rows) == 1 { 176 | fmt.Println("(1 row)") 177 | } else { 178 | fmt.Printf("(%d rows)\n", len(rows)) 179 | } 180 | 181 | return nil 182 | } 183 | 184 | func getFileContentHash(sha1 hash.Hash, fileName string) error { 185 | file, err := os.Open(fileName) 186 | if err != nil { 187 | return err 188 | } 189 | defer file.Close() 190 | 191 | _, err = io.Copy(sha1, file) 192 | return err 193 | } 194 | 195 | func getFilesContentHash(files []string) (string, error) { 196 | sha1 := sha1.New() 197 | 198 | for _, file := range files { 199 | err := getFileContentHash(sha1, file) 200 | if err != nil { 201 | return "", err 202 | } 203 | } 204 | 205 | return hex.EncodeToString(sha1.Sum(nil)), nil 206 | } 207 | 208 | func importFile(projectId, panelId, file, mimetype string, convertNumbers bool, w *runner.ResultWriter, withShape bool) (*runner.PanelInfo, error) { 209 | err := evalFileInto(file, mimetype, convertNumbers, w) 210 | if err != nil { 211 | return nil, err 212 | } 213 | 214 | err = w.Close() 215 | if err != nil { 216 | return nil, err 217 | } 218 | 219 | s := &runner.Shape{} 220 | if withShape { 221 | s, err = w.Shape(panelId, runner.DefaultShapeMaxBytesToRead, 100) 222 | if err != nil { 223 | return nil, err 224 | } 225 | } 226 | 227 | return &runner.PanelInfo{ 228 | ResultMeta: runner.PanelResult{ 229 | Shape: *s, 230 | }, 231 | Id: panelId, 232 | Name: uuid.New().String(), 233 | }, nil 234 | } 235 | 236 | func runQuery(queryRaw string, project *runner.ProjectState, ec *runner.EvalContext, args *args, files []string, resolveDM_getPanelToId *map[string]string) error { 237 | query := rewriteQuery(queryRaw, resolveDM_getPanelToId) 238 | panel := &runner.PanelInfo{ 239 | Type: runner.DatabasePanel, 240 | Content: query, 241 | Id: uuid.New().String(), 242 | Name: uuid.New().String(), 243 | DatabasePanelInfo: &runner.DatabasePanelInfo{ 244 | Database: runner.DatabasePanelInfoDatabase{ 245 | ConnectorId: project.Connectors[0].Id, 246 | }, 247 | }, 248 | } 249 | 250 | err := ec.EvalDatabasePanel(project, 0, panel, nil, args.cacheSettings) 251 | if err != nil { 252 | if e, ok := err.(*runner.DSError); ok && e.Name == "NotAnArrayOfObjectsError" { 253 | rest := "." 254 | nth, err := strconv.Atoi(e.TargetPanelId) 255 | if err == nil { 256 | rest = ": " + files[nth] + "." 257 | } 258 | return fmt.Errorf("Input is not an array of objects%s\n", rest) 259 | } 260 | 261 | return err 262 | } 263 | 264 | resultFile := ec.GetPanelResultsFile(project.Id, panel.Id) 265 | return dumpJSONFile(resultFile, args.pretty, args.schema) 266 | } 267 | 268 | func repl(project *runner.ProjectState, ec *runner.EvalContext, args *args, files []string, resolveDM_getPanelToId *map[string]string) error { 269 | completer := readline.NewPrefixCompleter( 270 | readline.PcItem("SELECT"), 271 | readline.PcItem("FROM"), 272 | readline.PcItem("WHERE"), 273 | readline.PcItem("AND"), 274 | readline.PcItem("OR"), 275 | readline.PcItem("IN"), 276 | readline.PcItem("JOIN"), 277 | ) 278 | 279 | filterInput := func(r rune) (rune, bool) { 280 | switch r { 281 | // block CtrlZ feature 282 | case readline.CharCtrlZ: 283 | return r, false 284 | } 285 | return r, true 286 | } 287 | 288 | historyFile := path.Join(runner.HOME, "dsq_history") 289 | l, err := readline.NewEx(&readline.Config{ 290 | Prompt: "dsq> ", 291 | HistoryFile: historyFile, 292 | InterruptPrompt: "^D", 293 | EOFPrompt: "exit", 294 | HistorySearchFold: true, 295 | FuncFilterInputRune: filterInput, 296 | AutoComplete: completer, 297 | }) 298 | if err != nil { 299 | return err 300 | } 301 | 302 | defer l.Close() 303 | 304 | for { 305 | queryRaw, err := l.Readline() 306 | if err != nil { 307 | return err 308 | } 309 | 310 | queryRaw = strings.TrimSpace(queryRaw) 311 | if queryRaw == "" { 312 | continue 313 | } 314 | 315 | if queryRaw == "exit" { 316 | // prints bye like mysql 317 | fmt.Println("bye") 318 | return nil 319 | } 320 | 321 | err = runQuery(queryRaw, project, ec, args, files, resolveDM_getPanelToId) 322 | if err != nil { 323 | return err 324 | } 325 | } 326 | } 327 | 328 | type args struct { 329 | pipedMimetype string 330 | pretty bool 331 | schema bool 332 | sqlFile string 333 | cacheSettings runner.CacheSettings 334 | nonFlagArgs []string 335 | dumpCacheFile bool 336 | isInteractive bool 337 | convertNumbers bool 338 | noSQLiteWriter bool 339 | } 340 | 341 | func getArgs() (*args, error) { 342 | args := &args{} 343 | 344 | args.noSQLiteWriter = strings.ToLower(os.Getenv("DSQ_NO_SQLITE_WRITER")) == "true" 345 | args.convertNumbers = strings.ToLower(os.Getenv("DSQ_CONVERT_NUMBERS")) == "true" 346 | args.cacheSettings.Enabled = strings.ToLower(os.Getenv("DSQ_CACHE")) == "true" 347 | 348 | osArgs := os.Args[1:] 349 | for i := 0; i < len(osArgs); i++ { 350 | arg := osArgs[i] 351 | isLast := i == len(osArgs)-1 352 | 353 | if arg == "--verbose" { 354 | runner.Verbose = true 355 | continue 356 | } 357 | 358 | if arg == "-s" || arg == "--stdin" { 359 | if isLast { 360 | return nil, errors.New("Must specify stdin mimetype.") 361 | } 362 | 363 | args.pipedMimetype = osArgs[i+1] 364 | i++ 365 | 366 | continue 367 | } 368 | 369 | if arg == "-h" || arg == "--help" { 370 | log.Println(HELP) 371 | return nil, nil 372 | } 373 | 374 | if arg == "-p" || arg == "--pretty" { 375 | args.pretty = true 376 | continue 377 | } 378 | 379 | if arg == "-v" || arg == "--version" { 380 | log.Println("dsq " + Version) 381 | return nil, nil 382 | } 383 | 384 | if arg == "-c" || arg == "--schema" { 385 | args.schema = true 386 | continue 387 | } 388 | 389 | if arg == "-f" || arg == "--file" { 390 | if isLast { 391 | return nil, errors.New("Must specify a SQL file.") 392 | } 393 | 394 | args.sqlFile = osArgs[i+1] 395 | i++ 396 | 397 | continue 398 | } 399 | 400 | if arg == "--cache" || arg == "-C" { 401 | args.cacheSettings.Enabled = true 402 | continue 403 | } 404 | 405 | if arg == "--cache-file" || arg == "-D" { 406 | args.dumpCacheFile = true 407 | args.cacheSettings.Enabled = true 408 | continue 409 | } 410 | 411 | if arg == "--interactive" || arg == "-i" { 412 | args.isInteractive = true 413 | args.pretty = true 414 | args.cacheSettings.Enabled = true 415 | continue 416 | } 417 | 418 | if arg == "-n" || arg == "--convert-numbers" { 419 | args.convertNumbers = true 420 | continue 421 | } 422 | 423 | if arg == "--no-sqlite-writer" { 424 | args.noSQLiteWriter = true 425 | continue 426 | } 427 | 428 | args.nonFlagArgs = append(args.nonFlagArgs, arg) 429 | } 430 | 431 | return args, nil 432 | } 433 | 434 | var Version = "latest" 435 | 436 | var HELP = `dsq (Version ` + Version + `) - commandline SQL engine for data files 437 | 438 | Usage: dsq [file...] $query 439 | dsq $file [query] 440 | cat $file | dsq -s $filetype [query] 441 | dsq $file -f $queryfile 442 | 443 | dsq is a tool for running SQL on one or more data files. It uses 444 | SQLite's SQL dialect. Files as tables are accessible via "{N}" where N 445 | is the 0-based index of the file in the commandline. 446 | 447 | The shorthand "{}" is replaced with "{0}". 448 | 449 | Examples: 450 | 451 | # This simply dumps the CSV as JSON 452 | $ dsq test.csv 453 | 454 | # This dumps the first 10 rows of the parquet file as JSON. 455 | $ dsq data.parquet "SELECT * FROM {} LIMIT 10" 456 | 457 | # This joins two datasets of differing origin types (CSV and JSON). 458 | $ dsq testdata/join/users.csv testdata/join/ages.json \ 459 | "select {0}.name, {1}.age from {0} join {1} on {0}.id = {1}.id" 460 | 461 | See the repo for more details: https://github.com/multiprocessio/dsq` 462 | 463 | func _main() error { 464 | rand.Seed(time.Now().UnixNano()) 465 | 466 | log.SetFlags(0) 467 | runner.Verbose = false 468 | 469 | args, err := getArgs() 470 | if err != nil { 471 | return err 472 | } 473 | 474 | // Some commands exit naturally here. Like -h and -v 475 | if args == nil { 476 | return nil 477 | } 478 | 479 | lastNonFlagArg := "" 480 | files := args.nonFlagArgs 481 | 482 | // Grab from stdin into local file 483 | mimetypeOverride := map[string]string{} 484 | if args.pipedMimetype != "" { 485 | pipedTmp, err := os.CreateTemp("", "dsq-stdin") 486 | if err != nil { 487 | return err 488 | } 489 | defer os.Remove(pipedTmp.Name()) 490 | 491 | mimetypeOverride[pipedTmp.Name()] = args.pipedMimetype 492 | 493 | _, err = io.Copy(pipedTmp, os.Stdin) 494 | if err != nil { 495 | return err 496 | } 497 | pipedTmp.Close() 498 | files = append([]string{pipedTmp.Name()}, files...) 499 | } 500 | 501 | // If -f|--file not present, query is the last argument 502 | if args.sqlFile == "" { 503 | if len(files) > 1 { 504 | lastNonFlagArg = files[len(files)-1] 505 | if strings.Contains(lastNonFlagArg, " ") { 506 | files = files[:len(files)-1] 507 | } 508 | } 509 | } else { 510 | // Otherwise read -f|--file as query 511 | content, err := os.ReadFile(args.sqlFile) 512 | if err != nil { 513 | return errors.New("Error opening sql file: " + err.Error()) 514 | } 515 | 516 | lastNonFlagArg = string(content) 517 | if lastNonFlagArg == "" { 518 | return errors.New("SQL file is empty.") 519 | } 520 | } 521 | 522 | if len(files) == 0 { 523 | return errors.New("No input files.") 524 | } 525 | 526 | var projectIdHashOrTmp string 527 | if args.cacheSettings.Enabled { 528 | var err error 529 | projectIdHashOrTmp, err = getFilesContentHash(files) 530 | if err != nil { 531 | log.Printf("Error creating hash for cache mode: %v, defaulting to normal mode", err) 532 | args.cacheSettings.Enabled = false 533 | } 534 | } else { 535 | projectTmp, err := os.CreateTemp("", "dsq-project") 536 | if err != nil { 537 | return err 538 | } 539 | defer os.Remove(projectTmp.Name()) 540 | 541 | projectIdHashOrTmp = projectTmp.Name() 542 | } 543 | 544 | project := &runner.ProjectState{ 545 | Id: projectIdHashOrTmp, 546 | Pages: []runner.ProjectPage{ 547 | { 548 | Panels: nil, 549 | }, 550 | }, 551 | } 552 | 553 | tmpDir, err := os.MkdirTemp("", "dsq") 554 | if err != nil { 555 | return err 556 | } 557 | defer os.RemoveAll(tmpDir) 558 | 559 | // Does no harm in calculating this even if caching is not on. A few places use this path. 560 | cachedPath := filepath.Join(os.TempDir(), "dsq-cache-"+projectIdHashOrTmp+".db") 561 | if args.cacheSettings.Enabled { 562 | info, err := os.Stat(cachedPath) 563 | args.cacheSettings.CachePresent = err == nil && info.Size() != 0 564 | if !args.cacheSettings.CachePresent { 565 | log.Println("Cache invalid, re-import required.") 566 | os.Remove(cachedPath) 567 | } 568 | } 569 | 570 | ec := runner.NewEvalContext(*runner.DefaultSettings, tmpDir) 571 | connector, err := runner.MakeTmpSQLiteConnector() 572 | if err != nil { 573 | return err 574 | } 575 | if args.cacheSettings.Enabled { 576 | connector.DatabaseConnectorInfo.Database.Database = cachedPath 577 | } 578 | 579 | justDumpResults := lastNonFlagArg == "" && !args.isInteractive 580 | 581 | // Check if we can use direct SQLite writer 582 | useSQLiteWriter := !args.noSQLiteWriter && !args.schema && !justDumpResults 583 | if useSQLiteWriter && !args.cacheSettings.Enabled { 584 | tmp, err := os.CreateTemp("", "dsq-sqlite-shared") 585 | if err != nil { 586 | return err 587 | } 588 | defer os.Remove(tmp.Name()) 589 | connector.DatabaseConnectorInfo.Database.Database = tmp.Name() 590 | } 591 | 592 | for _, file := range files { 593 | mt := mimetypeOverride[file] 594 | if mt == "" { 595 | mt = string(runner.GetMimeType(file, runner.ContentTypeInfo{})) 596 | } else { 597 | mt = string(resolveContentType(mt)) 598 | } 599 | mtm := runner.MimeType(mt) 600 | useSQLiteWriter = useSQLiteWriter && (mtm == runner.CSVMimeType || 601 | mtm == runner.TSVMimeType || 602 | mtm == runner.RegexpLinesMimeType) 603 | if !useSQLiteWriter { 604 | break 605 | } 606 | } 607 | // Done checking if we can use SQLiteWriter 608 | 609 | // This is going to break sometime. Reset back to original possible values. 610 | if !useSQLiteWriter { 611 | if args.cacheSettings.Enabled { 612 | connector.DatabaseConnectorInfo.Database.Database = cachedPath 613 | } else { 614 | connector.DatabaseConnectorInfo.Database.Database = ":memory:" 615 | } 616 | } 617 | 618 | // When dumping schema, need to injest even if cache is on. 619 | if !args.cacheSettings.CachePresent || !args.cacheSettings.Enabled || lastNonFlagArg == "" { 620 | for i, file := range files { 621 | panelId := uuid.New().String() 622 | 623 | convertNumbers := args.convertNumbers 624 | 625 | var w *runner.ResultWriter 626 | if useSQLiteWriter { 627 | tableName := fmt.Sprintf("t_%d", i) 628 | sw, err := openSQLiteResultItemWriter(connector.DatabaseConnectorInfo.Database.Database, tableName, convertNumbers) 629 | if err != nil { 630 | return err 631 | } 632 | 633 | // Prevent DataStation/runner from 634 | // doing conversion in Go. SQLite will 635 | // handle this as part of the NUMERIC 636 | // field types. 637 | convertNumbers = false 638 | 639 | w = runner.NewResultWriter(sw) 640 | } else { 641 | // Use JSONWriter 642 | w, err = ec.GetResultWriter(project.Id, panelId) 643 | if err != nil { 644 | return err 645 | } 646 | } 647 | 648 | panel, err := importFile(project.Id, panelId, file, mimetypeOverride[file], convertNumbers, w, !useSQLiteWriter) 649 | if err != nil { 650 | return err 651 | } 652 | project.Pages[0].Panels = append(project.Pages[0].Panels, *panel) 653 | } 654 | } 655 | 656 | if args.dumpCacheFile { 657 | fmt.Println(cachedPath) 658 | return nil 659 | } 660 | 661 | // No query, just dump transformed file directly out 662 | if justDumpResults { 663 | resultFile := ec.GetPanelResultsFile(project.Id, project.Pages[0].Panels[0].Id) 664 | return dumpJSONFile(resultFile, args.pretty, args.schema) 665 | } 666 | 667 | project.Connectors = append(project.Connectors, *connector) 668 | 669 | var resolveDM_getPanelToId *map[string]string 670 | if useSQLiteWriter { 671 | m := map[string]string{} 672 | for i := range files { 673 | m[fmt.Sprintf("%d", i)] = fmt.Sprintf("t_%d", i) 674 | } 675 | resolveDM_getPanelToId = &m 676 | } 677 | 678 | if args.isInteractive { 679 | return repl(project, &ec, args, files, resolveDM_getPanelToId) 680 | } 681 | 682 | return runQuery(lastNonFlagArg, project, &ec, args, files, resolveDM_getPanelToId) 683 | } 684 | 685 | func main() { 686 | err := _main() 687 | if err != nil { 688 | log.Fatal(err) 689 | } 690 | } 691 | -------------------------------------------------------------------------------- /scripts/benchmark.sh: -------------------------------------------------------------------------------- 1 | # Extract if doesn't exist 2 | 7z e -aos testdata/taxi.csv.7z 3 | 4 | hyperfine --min-runs 10 -w 2 --export-markdown benchmarks.md \ 5 | "sqlite3 :memory: -cmd '.mode csv' -cmd '.import taxi.csv taxi' 'SELECT passenger_count, COUNT(*), AVG(total_amount) FROM taxi GROUP BY passenger_count'" \ 6 | "duckdb -c \"SELECT passenger_count, COUNT(*), AVG(total_amount) FROM 'taxi.csv' GROUP BY passenger_count\"" \ 7 | 'trdsql -ih "SELECT passenger_count, COUNT(*), AVG(total_amount) FROM taxi.csv GROUP BY passenger_count"' \ 8 | 'OCTOSQL_NO_TELEMETRY=1 octosql "SELECT passenger_count, COUNT(*), AVG(total_amount) FROM taxi.csv GROUP BY passenger_count"' \ 9 | "q -d ',' -H \"SELECT passenger_count, COUNT(*), AVG(total_amount) FROM taxi.csv GROUP BY passenger_count\"" \ 10 | "q -d ',' -H -C readwrite \"SELECT passenger_count, COUNT(*), AVG(total_amount) FROM taxi.csv GROUP BY passenger_count\"" \ 11 | 'dsq taxi.csv "SELECT passenger_count, COUNT(*), AVG(total_amount) FROM {} GROUP BY passenger_count"' \ 12 | 'dsq -C taxi.csv "SELECT passenger_count, COUNT(*), AVG(total_amount) FROM {} GROUP BY passenger_count"' \ 13 | 'textql -header -sql "SELECT passenger_count, COUNT(*), AVG(total_amount) FROM taxi GROUP BY passenger_count" taxi.csv' \ 14 | 'spyql "SELECT passenger_count, count_agg(*), avg_agg(total_amount) FROM csv GROUP BY passenger_count" < taxi.csv' 15 | -------------------------------------------------------------------------------- /scripts/ci/prepare_linux.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -ex 4 | 5 | sudo curl -LO https://go.dev/dl/go1.18.linux-amd64.tar.gz 6 | sudo rm -rf /usr/local/go 7 | sudo tar -C /usr/local -xzf go1.18.linux-amd64.tar.gz 8 | sudo ln -s /usr/local/go/bin/go /usr/local/bin/go 9 | sudo ln -s /usr/local/go/bin/gofmt /usr/local/bin/gofmt 10 | 11 | sudo apt install -y p7zip 12 | 7z e testdata/taxi.csv.7z 13 | -------------------------------------------------------------------------------- /scripts/ci/prepare_macos.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eux 4 | 5 | sudo curl -LO https://go.dev/dl/go1.18.darwin-amd64.tar.gz 6 | sudo rm -rf /usr/local/go 7 | sudo tar -C /usr/local -xzf go1.18.darwin-amd64.tar.gz 8 | sudo mv /usr/local/go/bin/go /usr/local/bin/go 9 | sudo mv /usr/local/go/bin/gofmt /usr/local/bin/gofmt 10 | 11 | # Install 7z 12 | curl -LO https://github.com/jinfeihan57/p7zip/releases/download/v17.04/macos-10.15-p7zip.zip 13 | unzip macos-10.15-p7zip.zip 14 | ./7z e testdata/taxi.csv.7z 15 | -------------------------------------------------------------------------------- /scripts/ci/prepare_windows.ps1: -------------------------------------------------------------------------------- 1 | Set-StrictMode -Version Latest 2 | $ErrorActionPreference = "Stop" 3 | $PSDefaultParameterValues['*:ErrorAction']='Stop' 4 | function ThrowOnNativeFailure { 5 | if (-not $?) 6 | { 7 | throw 'Native Failure' 8 | } 9 | } 10 | 11 | iwr -useb 'https://raw.githubusercontent.com/scoopinstaller/install/master/install.ps1' -outfile 'install.ps1' 12 | .\install.ps1 -RunAsAdmin 13 | Join-Path (Resolve-Path ~).Path "scoop\shims" >> $Env:GITHUB_PATH 14 | scoop install jq 15 | scoop install zip 16 | scoop install curl 17 | scoop install 7zip 18 | scoop install go@1.18.3 19 | 20 | # curl -L -O "https://go.dev/dl/go1.18.windows-amd64.zip" 21 | # unzip go1.18.windows-amd64.zip 22 | # Join-Path $pwd "go\bin" >> $Env:GITHUB_PATH 23 | 24 | 7z e testdata/taxi.csv.7z -------------------------------------------------------------------------------- /scripts/fail_on_diff.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | if [[ "$(git diff)" != "" ]]; then 6 | printf "\033[0;31mFAILURE: Unexpected diff (did you run 'yarn format'?)\n\n\033[0m" 7 | git diff --color=never 8 | exit 1 9 | fi 10 | -------------------------------------------------------------------------------- /scripts/generate_test_data.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const faker = require('faker'); 3 | const XLSX = require('xlsx'); 4 | const CSV = require('papaparse'); 5 | const parquet = require('@dsnp/parquetjs'); 6 | 7 | const data = []; 8 | for (let i = 0; i < 1000; i++) { 9 | data.push({ 10 | ' Name ': faker.name.findName(), 11 | 'Phone Number ': faker.phone.phoneNumber(), 12 | Email: faker.internet.email(), 13 | Street: faker.address.streetAddress(), 14 | ' City ': faker.address.city(), 15 | State: faker.address.state(), 16 | 'Zip Code ': faker.address.zipCode(), 17 | 'Routing Number ': faker.finance.routingNumber(), 18 | Department: faker.commerce.department(), 19 | 'Company\t': faker.company.companyName(), 20 | 'Created At ': faker.date.past(), 21 | 'Profile Photo': faker.image.imageUrl(), 22 | ' Description': faker.lorem.paragraph(), 23 | Activated: faker.datatype.boolean(), 24 | }); 25 | } 26 | console.log(`Generated ${data.length} test data rows`); 27 | 28 | const directory = 'testdata/'; 29 | 30 | async function write() { 31 | // Write as CSV 32 | const csvname = directory + 'userdata.csv'; 33 | fs.writeFileSync(csvname, CSV.unparse(data)); 34 | console.log(`Wrote ${csvname}`); 35 | 36 | // Write as TSV 37 | const tsvname = directory + 'userdata.tsv'; 38 | fs.writeFileSync( 39 | tsvname, 40 | CSV.unparse(data, { 41 | delimiter: '\t', 42 | }) 43 | ); 44 | console.log(`Wrote ${tsvname}`); 45 | 46 | // Write as JSON 47 | const jsonname = directory + 'userdata.json'; 48 | fs.writeFileSync(jsonname, JSON.stringify(data)); 49 | console.log(`Wrote ${jsonname}`); 50 | 51 | // Write as JSON lines 52 | const jsonlinesnames = directory + 'userdata.jsonl'; 53 | fs.writeFileSync( 54 | jsonlinesnames, 55 | data.map((row) => JSON.stringify(row).replace(/\n/g, '')).join('\n') 56 | ); 57 | console.log(`Wrote ${jsonlinesnames}`); 58 | 59 | // Write as .ods file 60 | const ws = XLSX.utils.json_to_sheet(data); 61 | const wb = XLSX.utils.book_new(); 62 | XLSX.utils.book_append_sheet(wb, ws, 'Sheet 1'); 63 | const odsname = directory + 'userdata.ods'; 64 | XLSX.writeFile(wb, odsname); 65 | console.log(`Wrote ${odsname}`); 66 | 67 | // Write as Excel file 68 | const excelname = directory + 'userdata.xlsx'; 69 | XLSX.writeFile(wb, excelname); 70 | console.log(`Wrote ${excelname}`); 71 | 72 | // Write as parquet file 73 | const schema = new parquet.ParquetSchema({ 74 | ' Name ': { type: 'UTF8' }, 75 | 'Phone Number ': { type: 'UTF8' }, 76 | Email: { type: 'UTF8' }, 77 | Street: { type: 'UTF8' }, 78 | ' City ': { type: 'UTF8' }, 79 | State: { type: 'UTF8' }, 80 | 'Zip Code ': { type: 'UTF8' }, 81 | 'Routing Number ': { type: 'INT64' }, 82 | Department: { type: 'UTF8' }, 83 | 'Company\t': { type: 'UTF8' }, 84 | 'Created At ': { type: 'TIMESTAMP_MILLIS' }, 85 | 'Profile Photo': { type: 'UTF8' }, 86 | ' Description': { type: 'UTF8' }, 87 | Activated: { type: 'BOOLEAN' }, 88 | }); 89 | const parquetname = directory + 'userdata.parquet'; 90 | const writer = await parquet.ParquetWriter.openFile(schema, parquetname); 91 | for (const row of data) { 92 | await writer.appendRow(row); 93 | } 94 | await writer.close(); 95 | console.log(`Wrote ${parquetname}`); 96 | } 97 | 98 | write(); 99 | -------------------------------------------------------------------------------- /scripts/test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import glob 4 | import json 5 | import os 6 | import shlex 7 | import subprocess 8 | import sys 9 | import tempfile 10 | from datetime import datetime 11 | 12 | DEBUG = '-d' in sys.argv or '--debug' in sys.argv 13 | WIN = os.name == 'nt' 14 | 15 | def cmd(to_run, bash=False, doNotReplaceWin=False): 16 | pieces = shlex.split(to_run) 17 | if WIN and not doNotReplaceWin: 18 | for i, piece in enumerate(pieces): 19 | pieces[i] = piece.replace('./dsq', './dsq.exe').replace('/', '\\') 20 | elif bash or '|' in pieces: 21 | pieces = ['bash', '-c', to_run] 22 | 23 | return subprocess.run(pieces, cwd=os.getcwd(), capture_output=True, check=True) 24 | 25 | tests = 0 26 | failures = 0 27 | 28 | def test(name, to_run, want, fail=False, sort=False, winSkip=False, within_seconds=None, want_stderr=None): 29 | global tests 30 | global failures 31 | 32 | skip = False 33 | for i, arg in enumerate(sys.argv): 34 | if arg == '-f' or arg == '--filter': 35 | if sys.argv[i+1].lower() not in name.lower(): 36 | return 37 | if arg == '-fo' or arg == '--filter-out': 38 | if sys.argv[i+1].lower() in name.lower(): 39 | return 40 | 41 | tests += 1 42 | skipped = True 43 | 44 | t1 = datetime.now() 45 | 46 | print('STARTING: ' + name) 47 | if DEBUG: 48 | print(to_run) 49 | 50 | if WIN and winSkip or skip: 51 | print(' SKIPPED\n') 52 | print() 53 | return 54 | 55 | try: 56 | res = cmd(to_run) 57 | got = res.stdout.decode() 58 | 59 | got_err = res.stderr.decode() 60 | if want_stderr and got_err != want_stderr: 61 | failures += 1 62 | print(f' FAILURE: stderr mismatch. Got "{got_err}", wanted "{want_stderr}".') 63 | print() 64 | return 65 | 66 | if sort: 67 | got = json.dumps(json.loads(got), sort_keys=True) 68 | want = json.dumps(json.loads(want), sort_keys=True) 69 | except json.JSONDecodeError as e: 70 | failures += 1 71 | print(' FAILURE: bad JSON: ' + got) 72 | print() 73 | return 74 | except Exception as e: 75 | if not fail: 76 | print(f' FAILURE: unexpected failure: {0} {1}', str(e), e.output.decode()) 77 | failures += 1 78 | print() 79 | return 80 | else: 81 | got = e.output.decode() 82 | skipped = False 83 | if fail and skipped: 84 | print(f' FAILURE: unexpected success') 85 | failures += 1 86 | print() 87 | return 88 | if WIN and '/' in want: 89 | want = want.replace('/', '\\') 90 | if want.strip() != got.strip(): 91 | print(f' FAILURE') 92 | try: 93 | with tempfile.NamedTemporaryFile() as want_fp: 94 | want_fp.write(want.strip().encode()) 95 | want_fp.flush() 96 | with tempfile.NamedTemporaryFile() as got_fp: 97 | got_fp.write(got.strip().encode()) 98 | got_fp.flush() 99 | diff_res = cmd(f'diff {want_fp.name} {got_fp.name} || true', bash=True) 100 | print(diff_res.stdout.decode()) 101 | except Exception as e: 102 | print(e.cmd, e.output.decode()) 103 | failures += 1 104 | print() 105 | return 106 | 107 | t2 = datetime.now() 108 | s = (t2-t1).seconds 109 | if within_seconds and s > within_seconds: 110 | print(f' FAILURE: completed in {s} seconds. Wanted <{within_seconds}s') 111 | failures += 1 112 | return 113 | 114 | print(f' SUCCESS\n') 115 | 116 | 117 | types = ['csv', 'tsv', 'parquet', 'json', 'jsonl', 'xlsx', 'ods'] 118 | for t in types: 119 | if WIN: 120 | continue 121 | to_run = f"cat ./testdata/userdata.{t} | ./dsq -s {t} 'SELECT COUNT(1) AS c FROM {{}}' | jq '.[0].c'" 122 | test('SQL count for ' + t + ' pipe', to_run, '1000') 123 | 124 | to_run = f"./dsq ./testdata/userdata.{t} 'SELECT COUNT(1) AS c FROM {{}}' | jq '.[0].c'" 125 | test('SQL count for ' + t + ' file', to_run, '1000') 126 | 127 | 128 | # No input test 129 | to_run = "./dsq" 130 | want_stderr = "No input files.\n" 131 | test("Handles no arguments correctly", to_run, want="", want_stderr=want_stderr, fail=True) 132 | 133 | # Join test 134 | to_run = "./dsq testdata/join/users.csv testdata/join/ages.json 'select {0}.name, {1}.age from {0} join {1} on {0}.id = {1}.id'" 135 | want = """[{"age":88,"name":"Ted"}, 136 | {"age":56,"name":"Marjory"}, 137 | {"age":33,"name":"Micah"}]""" 138 | test("Join two file-tables", to_run, want, sort=True) 139 | 140 | # Nested values test 141 | to_run = """./dsq ./testdata/nested/nested.json 'select name, "location.city" city, "location.address.number" address_number from {}'""" 142 | want = """[{"address_number":1002,"city":"Toronto","name":"Agarrah"}, 143 | {"address_number":19,"city":"Mexico City","name":"Minoara"}, 144 | {"address_number":12,"city":"New London","name":"Fontoon"}]""" 145 | test("Extract nested values", to_run, want, sort=True) 146 | 147 | # Not an array of data test 148 | to_run = "./dsq ./testdata/bad/not_an_array.json 'SELECT * FROM {}'" 149 | want_stderr = "Input is not an array of objects: ./testdata/bad/not_an_array.json.\n" 150 | test("Does not allow querying on non-array data", to_run, want="", want_stderr=want_stderr, fail=True) 151 | 152 | # REGEXP support 153 | to_run = """./dsq ./testdata/nested/nested.json "SELECT * FROM {} WHERE name REGEXP 'A.*'" """ 154 | want = '[{"location.address.number":1002,"location.city":"Toronto","name":"Agarrah"}]' 155 | test("Supports filtering with REGEXP", to_run, want, sort=True) 156 | 157 | # Table aliases 158 | to_run = """./dsq ./testdata/nested/nested.json "SELECT * FROM {} u WHERE u.name REGEXP 'A.*'" """ 159 | want = '[{"location.address.number":1002,"location.city":"Toronto","name":"Agarrah"}]' 160 | test("Supports table aliases", to_run, want, sort=True) 161 | 162 | # With path 163 | to_run = """./dsq ./testdata/path/path.json "SELECT * FROM {0, 'data.data2'} ORDER BY id DESC" """ 164 | want = '[{"id":4,"name":"Minh2"},{"id":2,"name":"Corah2"}]' 165 | test("Supports path specification", to_run, want, sort=True) 166 | 167 | # With path shorthand 168 | to_run = """./dsq ./testdata/path/path.json "SELECT * FROM {'data.data'} ORDER BY id DESC" """ 169 | want = '[{"id":3,"name":"Minh"},{"id":1,"name":"Corah"}]' 170 | test("Supports path specification shorthand", to_run, want, sort=True) 171 | 172 | # Excel multiple sheets 173 | to_run = """./dsq testdata/excel/multiple-sheets.xlsx 'SELECT COUNT(1) AS n FROM {0, "Sheet2"}'""" 174 | want = '[{"n": 682}]' 175 | test("Supports Excel with multiple sheets", to_run, want, sort=True) 176 | 177 | # ORC support 178 | to_run = """./dsq ./testdata/orc/test_data.orc 'SELECT COUNT(*) FROM {} WHERE _col8="China"'""" 179 | want = '[{"COUNT(*)":189}]' 180 | test("Supports ORC files", to_run, want, sort=True) 181 | 182 | # Avro support 183 | to_run = """./dsq ./testdata/avro/test_data.avro 'SELECT COUNT(*) FROM {} WHERE country="Sweden"'""" 184 | want = '[{"COUNT(*)":25}]' 185 | test("Supports Avro files", to_run, want, sort=True) 186 | 187 | # YAML support 188 | to_run = """./dsq ./testdata/yaml/userdata.yaml 'SELECT COUNT(*) FROM {} WHERE activated=false'""" 189 | want = '[{"COUNT(*)":3}]' 190 | test("Supports YAML files", to_run, want, sort=True) 191 | 192 | # LogFmt support 193 | to_run = """./dsq ./testdata/logfmt/log.logfmt 'SELECT level FROM {}'""" 194 | want = """[{"level":"debug"}, 195 | {"level":"info"}, 196 | {"level":"warning"}, 197 | {"level":"debug"}, 198 | {"level":"panic"}]""" 199 | test("Supports LogFmt log files", to_run, want, sort=True) 200 | 201 | # Version test 202 | to_run = """./dsq -v""" 203 | want_stderr = "dsq latest\n" 204 | test("Shows version and quits", to_run, want="", want_stderr=want_stderr) 205 | 206 | # Pretty column order 207 | to_run = """./dsq --pretty testdata/path/path.json 'SELECT name, id FROM {"data.data"}'""" 208 | want = """+----+-------+ 209 | | id | name | 210 | +----+-------+ 211 | | 1 | Corah | 212 | | 3 | Minh | 213 | +----+-------+ 214 | (2 rows)""" 215 | test("Pretty column order alphabetical", to_run, want) 216 | 217 | # Pretty without query 218 | to_run = """./dsq --pretty testdata/regr/36.json""" 219 | want = """+---+---+-------+ 220 | | a | b | c | 221 | +---+---+-------+ 222 | | 1 | 2 | [1,2] | 223 | +---+---+-------+ 224 | (1 row)""" 225 | test("Pretty works even without query", to_run, want) 226 | 227 | # Prints schema pretty 228 | to_run = """./dsq --pretty --schema testdata/regr/36.json""" 229 | want = """Array of 230 | Object of 231 | a of 232 | number 233 | b of 234 | number 235 | c of 236 | Array of 237 | number 238 | """ 239 | test("Pretty prints schema", to_run, want) 240 | 241 | # Prints schema as JSON 242 | to_run = """./dsq --schema testdata/regr/36.json""" 243 | want = """{ 244 | "kind": "array", 245 | "array": { 246 | "kind": "object", 247 | "object": { 248 | "b": { 249 | "kind": "scalar", 250 | "scalar": "number" 251 | }, 252 | "c": { 253 | "kind": "array", 254 | "array": { 255 | "kind": "scalar", 256 | "scalar": "number" 257 | } 258 | }, 259 | "a": { 260 | "kind": "scalar", 261 | "scalar": "number" 262 | } 263 | } 264 | } 265 | }""" 266 | test("Prints schema as JSON", to_run, want, sort=True) 267 | 268 | # SQL file tests 269 | # Simple sql query from file 270 | to_run = """./dsq testdata/userdata.json --file ./testdata/sql/simple.sql""" 271 | want = """ 272 | [{" Name ":"Michelle Yost"}, 273 | {" Name ":"Guadalupe Schimmel II"}, 274 | {" Name ":"Corey Beier"}] 275 | """ 276 | test("Run simple query from sql file", to_run, want, sort=True) 277 | 278 | # Error when query file is empty 279 | to_run = """./dsq testdata/userdata.json --file ./testdata/sql/empty.sql""" 280 | want_stderr = "SQL file is empty.\n" 281 | test("Run query from empty sql file", to_run, want="", want_stderr=want_stderr, fail=True) 282 | 283 | # Error when query file is empty 284 | to_run = """./dsq testdata/userdata.json -f""" 285 | want_stderr = "Must specify a SQL file.\n" 286 | test("Not specifying sql file", to_run, want="", want_stderr=want_stderr, fail=True) 287 | 288 | # Cache test 289 | # Drop the db file on disk to make sure this test's cache is clean. 290 | for f in glob.glob(os.path.join(tempfile.gettempdir(), "dsq-cache-*.db*")): 291 | print("Deleting existing dsq database file: " + f) 292 | os.remove(f) 293 | 294 | to_run = """ 295 | ./dsq --cache taxi.csv "SELECT passenger_count, COUNT(*), AVG(total_amount) FROM {} GROUP BY passenger_count ORDER BY COUNT(*) DESC" 296 | """ 297 | want = """ 298 | [{"AVG(total_amount)":17.641883306799908,"passenger_count":"1","COUNT(*)":1533197}, 299 | {"AVG(total_amount)":18.097587071145647,"passenger_count":"2","COUNT(*)":286461}, 300 | {"AVG(total_amount)":32.23715114825533,"passenger_count":"","COUNT(*)":128020}, 301 | {"AVG(total_amount)":17.915395871092315,"passenger_count":"3","COUNT(*)":72852}, 302 | {"AVG(total_amount)":17.270924817567234,"passenger_count":"5","COUNT(*)":50291}, 303 | {"passenger_count":"0","COUNT(*)":42228,"AVG(total_amount)":17.021401676615067}, 304 | {"passenger_count":"6","COUNT(*)":32623,"AVG(total_amount)":17.600296416636713}, 305 | {"passenger_count":"4","COUNT(*)":25510,"AVG(total_amount)":18.452774990196012}, 306 | {"COUNT(*)":2,"AVG(total_amount)":95.705,"passenger_count":"8"}, 307 | {"passenger_count":"7","COUNT(*)":2,"AVG(total_amount)":87.17}, 308 | {"passenger_count":"9","COUNT(*)":1,"AVG(total_amount)":113.6}]""" 309 | want_stderr = "Cache invalid, re-import required.\n" 310 | 311 | test("Caching from file (first time so import is required)", to_run, want, want_stderr=want_stderr, sort=True) 312 | 313 | to_run = """ 314 | cat taxi.csv | ./dsq --cache -s csv 'SELECT passenger_count, COUNT(*), AVG(total_amount) FROM {} GROUP BY passenger_count ORDER BY COUNT(*) DESC' 315 | """ 316 | 317 | test("Caching from pipe (second time so import not required)", to_run, want, sort=True, winSkip=True, within_seconds=5) 318 | 319 | to_run = """ 320 | cat testdata/taxi_trunc.csv | ./dsq --cache -s csv 'SELECT passenger_count, COUNT(*), AVG(total_amount) FROM {} GROUP BY passenger_count ORDER BY COUNT(*) DESC'""" 321 | want = """[{"COUNT(*)":9,"AVG(total_amount)":20.571111111111115,"passenger_count":"1"}, 322 | {"passenger_count":"0","COUNT(*)":1,"AVG(total_amount)":43.67}]""" 323 | want_stderr = "Cache invalid, re-import required.\n" 324 | 325 | test("Re-imports when file changes with cache on", to_run, want, want_stderr=want_stderr, sort=True, winSkip=True) 326 | 327 | # Mode support 328 | to_run = """./dsq testdata/userdata.json 'SELECT mode(Activated) mostly_activated FROM {}' """ 329 | want = '[{"mostly_activated":1}]' 330 | test("Mode support", to_run, want=want) 331 | 332 | # URL functions 333 | to_run = """./dsq testdata/basic_logs.csv 'SELECT url_host(request) host, count(1) count FROM {} group by host' """ 334 | want = '[{"host":"age.com","count":2}]' 335 | test("URL functions", to_run, want=want, sort=True) 336 | 337 | # URL functions, split_part 338 | to_run = """./dsq testdata/basic_logs.csv 'SELECT split_part(url_host(request), ".", -1) host, count(1) count FROM {} group by host' """ 339 | want = '[{"host":"com","count":2}]' 340 | test("URL functions", to_run, want=want, sort=True) 341 | 342 | # Number conversion 343 | to_run = """./dsq testdata/convert.csv 'SELECT * FROM {}'""" 344 | want = """[{"test":"1"}, 345 | {"test":"1.1"}, 346 | {"test":"+1"}, 347 | {"test":"01"}, 348 | {"test":"001"}, 349 | {"test":"0001.1"}]""" 350 | test("No number conversion, with query", to_run, want=want, sort=True) 351 | 352 | to_run = """./dsq --convert-numbers testdata/convert.csv 'SELECT * FROM {}'""" 353 | want = """[{"test":1}, 354 | {"test":1.1}, 355 | {"test":1}, 356 | {"test":1}, 357 | {"test":1}, 358 | {"test":1.1}]""" 359 | test("Number conversion, with query", to_run, want=want, sort=True) 360 | 361 | to_run = """./dsq testdata/convert.csv""" 362 | want = """[{"test":"1"}, 363 | {"test":"1.1"}, 364 | {"test":"+1"}, 365 | {"test":"01"}, 366 | {"test":"001"}, 367 | {"test":"0001.1"}]""" 368 | test("No number conversion, no query", to_run, want=want, sort=True) 369 | 370 | to_run = """./dsq --convert-numbers testdata/convert.csv""" 371 | want = """[{"test":1}, 372 | {"test":1.1}, 373 | {"test":1}, 374 | {"test":1}, 375 | {"test":1}, 376 | {"test":1.1}]""" 377 | test("Number conversion, no query", to_run, want=want, sort=True) 378 | 379 | to_run = """./dsq testdata/csv/numberconvert.csv 'select * from {} where score > "90"'""" 380 | want = """[{"Score": "95", "Name": "Rainer"}]""" 381 | test("No number conversion, does alphabet ordering", to_run, want=want, sort=True) 382 | 383 | to_run = """./dsq --convert-numbers testdata/csv/numberconvert.csv 'select * from {} where score > "90"'""" 384 | want = """[{"Name":"Rainer","Score":95}, 385 | {"Name":"Fountainer","Score":100}]""" 386 | test("Number conversion, number ordering", to_run, want=want, sort=True) 387 | 388 | # END OF TESTS 389 | 390 | # START OF REGRESSION TESTS 391 | # Nested array support 392 | to_run = """./dsq ./testdata/regr/36.json 'SELECT c->1 AS secondc FROM {}'""" 393 | want = '[{"secondc": "2"}]' 394 | test("https://github.com/multiprocessio/dsq/issues/36", to_run, want, sort=True) 395 | 396 | to_run = """./dsq ./testdata/regr/36.json 'SELECT * FROM {}'""" 397 | want = '[{"a": 1, "b": 2, "c": "[1,2]"}]' 398 | test("https://github.com/multiprocessio/dsq/issues/36", to_run, want, sort=True) 399 | 400 | to_run = """./dsq ./testdata/regr/67.jsonl 'SELECT COUNT(1) AS count FROM {}'""" 401 | want = '[{"count": 1}]' 402 | test("https://github.com/multiprocessio/dsq/issues/67", to_run, want, sort=True) 403 | 404 | to_run = """./dsq ./testdata/regr/74.csv 'SELECT * FROM {}'""" 405 | want = '[{"a": "1", "a b": "2"}]' 406 | test("https://github.com/multiprocessio/dsq/issues/74", to_run, want, sort=True) 407 | 408 | 409 | # END OF REGRESSION TESTS 410 | 411 | print(f"{tests - failures} of {tests} succeeded.") 412 | if failures > 0: 413 | sys.exit(1) 414 | -------------------------------------------------------------------------------- /sqlite.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "database/sql" 5 | "encoding/json" 6 | "fmt" 7 | "strings" 8 | 9 | "github.com/multiprocessio/datastation/runner" 10 | ) 11 | 12 | type SQLiteResultItemWriter struct { 13 | db *sql.DB 14 | fields []string 15 | panelId string 16 | rowBuffer runner.Vector[any] 17 | convertNumbers bool 18 | } 19 | 20 | func openSQLiteResultItemWriter(f string, panelId string, convertNumbers bool) (runner.ResultItemWriter, error) { 21 | var sw SQLiteResultItemWriter 22 | sw.panelId = panelId 23 | sw.convertNumbers = convertNumbers 24 | 25 | sw.rowBuffer = runner.Vector[any]{} 26 | 27 | var err error 28 | sw.db, err = sql.Open("sqlite3_extended", f) 29 | if err != nil { 30 | return nil, err 31 | } 32 | 33 | return &sw, nil 34 | } 35 | 36 | func (sw *SQLiteResultItemWriter) createTable() error { 37 | fieldType := "TEXT" 38 | if sw.convertNumbers { 39 | fieldType = "NUMERIC" 40 | } 41 | 42 | var columns []string 43 | for _, field := range sw.fields { 44 | columns = append(columns, `"`+field+`" `+fieldType) 45 | } 46 | create := "CREATE TABLE \"" + sw.panelId + "\"(" + strings.Join(columns, ", ") + ");" 47 | _, err := sw.db.Exec(create) 48 | return err 49 | } 50 | 51 | func (sw *SQLiteResultItemWriter) makeQuery(rows int) string { 52 | var query strings.Builder 53 | query.WriteString("INSERT INTO \"" + sw.panelId + "\" VALUES ") 54 | for i := 0; i < rows; i++ { 55 | if i > 0 { 56 | query.WriteString(", ") 57 | } 58 | 59 | query.WriteByte('(') 60 | for i := range sw.fields { 61 | if i > 0 { 62 | query.WriteString(", ") 63 | } 64 | query.WriteByte('?') 65 | } 66 | query.WriteByte(')') 67 | } 68 | 69 | return query.String() 70 | } 71 | 72 | func (sw *SQLiteResultItemWriter) flush() error { 73 | rowsInBatch := 100 74 | query := sw.makeQuery(rowsInBatch) 75 | 76 | stmt, err := sw.db.Prepare(query) 77 | if err != nil { 78 | return err 79 | } 80 | 81 | rows := sw.rowBuffer.Index() / len(sw.fields) 82 | args := sw.rowBuffer.List() 83 | var leftover []any 84 | batchArgs := make([]any, rowsInBatch*len(sw.fields)) 85 | for i := 0; i < rows; i += rowsInBatch { 86 | if i+rowsInBatch > rows { 87 | leftover = make([]any, (rows-i)*len(sw.fields)) 88 | copy(leftover, args[i*len(sw.fields):]) 89 | break 90 | } 91 | 92 | copy(batchArgs, args[i*len(sw.fields):(i+rowsInBatch)*len(sw.fields)]) 93 | _, err = stmt.Exec(batchArgs...) 94 | if err != nil { 95 | return err 96 | } 97 | } 98 | 99 | err = stmt.Close() 100 | if err != nil { 101 | return err 102 | } 103 | 104 | if len(leftover) > 0 { 105 | remainingRows := len(leftover) / len(sw.fields) 106 | _, err := sw.db.Exec(sw.makeQuery(remainingRows), leftover...) 107 | if err != nil { 108 | return err 109 | } 110 | } 111 | 112 | sw.rowBuffer.Reset() 113 | return nil 114 | } 115 | 116 | func (sw *SQLiteResultItemWriter) WriteRow(r any, written int) error { 117 | m, ok := r.(map[string]any) 118 | if !ok { 119 | return fmt.Errorf("Row must be a map, got: %#v", r) 120 | } 121 | 122 | if len(sw.fields) == 0 { 123 | for key := range m { 124 | sw.fields = append(sw.fields, key) 125 | } 126 | 127 | err := sw.createTable() 128 | if err != nil { 129 | return err 130 | } 131 | } 132 | 133 | for _, field := range sw.fields { 134 | v := m[field] 135 | switch t := v.(type) { 136 | case []any: 137 | bs, err := json.Marshal(t) 138 | if err != nil { 139 | return err 140 | } 141 | v = string(bs) 142 | } 143 | sw.rowBuffer.Append(v) 144 | } 145 | 146 | // Flush data 147 | if written > 0 && written%10000 == 0 { 148 | return sw.flush() 149 | } 150 | 151 | return nil 152 | } 153 | 154 | func (sw *SQLiteResultItemWriter) SetNamespace(key string) error { 155 | return fmt.Errorf("SetNamespace unimplemented") 156 | } 157 | 158 | func (sw *SQLiteResultItemWriter) Shape(id string, maxBytesToRead, sampleSize int) (*runner.Shape, error) { 159 | return nil, fmt.Errorf("Shape unimplemented") 160 | } 161 | 162 | func (sw *SQLiteResultItemWriter) Close() error { 163 | if sw.rowBuffer.Index() > 0 { 164 | err := sw.flush() 165 | if err != nil { 166 | return err 167 | } 168 | } 169 | 170 | return sw.db.Close() 171 | } 172 | -------------------------------------------------------------------------------- /testdata/avro/test_data.avro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/multiprocessio/dsq/c3ae0bafb0c3283e3c98cb250ada5a19e79ad58e/testdata/avro/test_data.avro -------------------------------------------------------------------------------- /testdata/bad/not_an_array.json: -------------------------------------------------------------------------------- 1 | {"a": 1} 2 | -------------------------------------------------------------------------------- /testdata/basic_logs.csv: -------------------------------------------------------------------------------- 1 | name,age,request 2 | phil,12,https://age.com/flubber.html?k=123 3 | buddy,19,https://age.com/path.html?k=199 -------------------------------------------------------------------------------- /testdata/convert.csv: -------------------------------------------------------------------------------- 1 | test 2 | 1 3 | 1.1 4 | +1 5 | 01 6 | 001 7 | 0001.1 -------------------------------------------------------------------------------- /testdata/csv/numberconvert.csv: -------------------------------------------------------------------------------- 1 | Name,Score 2 | Fritz,90 3 | Rainer,95 4 | Fountainer,100 -------------------------------------------------------------------------------- /testdata/excel/multiple-sheets.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/multiprocessio/dsq/c3ae0bafb0c3283e3c98cb250ada5a19e79ad58e/testdata/excel/multiple-sheets.xlsx -------------------------------------------------------------------------------- /testdata/join/ages.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"id": 1, "age": 88}, 3 | {"id": 2, "age": 56}, 4 | {"id": 3, "age": 33} 5 | ] 6 | -------------------------------------------------------------------------------- /testdata/join/users.csv: -------------------------------------------------------------------------------- 1 | id,name 2 | 1,Ted 3 | 2,Marjory 4 | 3,Micah -------------------------------------------------------------------------------- /testdata/logfmt/log.logfmt: -------------------------------------------------------------------------------- 1 | time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8 2 | time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10 3 | time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true 4 | time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4 5 | time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009 -------------------------------------------------------------------------------- /testdata/nested/nested.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"name": "Agarrah", "location": {"city": "Toronto", "address": { "number": 1002 }}}, 3 | {"name": "Minoara", "location": {"city": "Mexico City", "address": { "number": 19 }}}, 4 | {"name": "Fontoon", "location": {"city": "New London", "address": { "number": 12 }}} 5 | ] 6 | -------------------------------------------------------------------------------- /testdata/orc/test_data.orc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/multiprocessio/dsq/c3ae0bafb0c3283e3c98cb250ada5a19e79ad58e/testdata/orc/test_data.orc -------------------------------------------------------------------------------- /testdata/path/path.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "data": [ 4 | {"id": 1, "name": "Corah"}, 5 | {"id": 3, "name": "Minh"} 6 | ], 7 | "data2": [ 8 | {"id": 2, "name": "Corah2"}, 9 | {"id": 4, "name": "Minh2"} 10 | ] 11 | }, 12 | "total": 2 13 | } 14 | -------------------------------------------------------------------------------- /testdata/regr/36.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"a": 1, "b": 2, "c": [1,2]} 3 | ] 4 | -------------------------------------------------------------------------------- /testdata/regr/67.jsonl: -------------------------------------------------------------------------------- 1 | {"foo":[]} 2 | -------------------------------------------------------------------------------- /testdata/regr/74.csv: -------------------------------------------------------------------------------- 1 | "a","a b" 2 | 1,2 -------------------------------------------------------------------------------- /testdata/sql/empty.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/multiprocessio/dsq/c3ae0bafb0c3283e3c98cb250ada5a19e79ad58e/testdata/sql/empty.sql -------------------------------------------------------------------------------- /testdata/sql/simple.sql: -------------------------------------------------------------------------------- 1 | SELECT " Name " FROM {} LIMIT 3; -------------------------------------------------------------------------------- /testdata/taxi.csv.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/multiprocessio/dsq/c3ae0bafb0c3283e3c98cb250ada5a19e79ad58e/testdata/taxi.csv.7z -------------------------------------------------------------------------------- /testdata/taxi_trunc.csv: -------------------------------------------------------------------------------- 1 | VendorID,tpep_pickup_datetime,tpep_dropoff_datetime,passenger_count,trip_distance,RatecodeID,store_and_fwd_flag,PULocationID,DOLocationID,payment_type,fare_amount,extra,mta_tax,tip_amount,tolls_amount,improvement_surcharge,total_amount,congestion_surcharge 2 | 1,2021-04-01 00:00:18,2021-04-01 00:21:54,1,8.40,1,N,79,116,1,25.5,3,0.5,5.85,0,0.3,35.15,2.5 3 | 1,2021-04-01 00:42:37,2021-04-01 00:46:23,1,.90,1,N,75,236,2,5,3,0.5,0,0,0.3,8.8,2.5 4 | 1,2021-04-01 00:57:56,2021-04-01 01:08:22,1,3.40,1,N,236,168,2,11.5,3,0.5,0,0,0.3,15.3,2.5 5 | 1,2021-04-01 00:01:58,2021-04-01 00:54:27,1,.00,1,N,47,61,1,44.2,0,0.5,0,0,0.3,45,0 6 | 2,2021-04-01 00:24:55,2021-04-01 00:34:33,1,1.96,1,N,238,152,1,9,0.5,0.5,3.09,0,0.3,13.39,0 7 | 2,2021-04-01 00:19:16,2021-04-01 00:21:46,1,.77,1,N,142,238,1,4.5,0.5,0.5,1.24,0,0.3,9.54,2.5 8 | 2,2021-04-01 00:25:11,2021-04-01 00:31:53,1,3.65,1,N,238,244,1,11.5,0.5,0.5,2.56,0,0.3,15.36,0 9 | 1,2021-04-01 00:27:53,2021-04-01 00:47:03,0,8.90,1,N,138,239,1,26.5,3,0.5,7.25,6.12,0.3,43.67,2.5 10 | 2,2021-04-01 00:24:24,2021-04-01 00:37:50,1,2.98,1,N,151,244,2,12,0.5,0.5,0,0,0.3,13.3,0 11 | 1,2021-04-01 00:19:18,2021-04-01 00:41:25,1,8.90,1,N,132,196,2,28,0.5,0.5,0,0,0.3,29.3,0 12 | -------------------------------------------------------------------------------- /testdata/unknown: -------------------------------------------------------------------------------- 1 | hey this is unknown -------------------------------------------------------------------------------- /testdata/userdata.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/multiprocessio/dsq/c3ae0bafb0c3283e3c98cb250ada5a19e79ad58e/testdata/userdata.ods -------------------------------------------------------------------------------- /testdata/userdata.parquet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/multiprocessio/dsq/c3ae0bafb0c3283e3c98cb250ada5a19e79ad58e/testdata/userdata.parquet -------------------------------------------------------------------------------- /testdata/userdata.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/multiprocessio/dsq/c3ae0bafb0c3283e3c98cb250ada5a19e79ad58e/testdata/userdata.xlsx -------------------------------------------------------------------------------- /testdata/yaml/userdata.yaml: -------------------------------------------------------------------------------- 1 | - " Name ": Michelle Yost 2 | 'Phone Number ': "(804) 896-6245 x269" 3 | Email: Cicero_Frami41@hotmail.com 4 | Street: '081 Senger Streets' 5 | " City ": North Jerel 6 | State: Nebraska 7 | 'Zip Code ': 67681-6032 8 | 'Routing Number ': '058655724' 9 | Department: Garden 10 | "Company\t": Stiedemann Inc 11 | 'Created At ': '2021-10-18T04:23:27.810Z' 12 | Profile Photo: http://placeimg.com/640/480 13 | " Description": Adipisci animi nulla consectetur quia qui amet at. Hic earum nisi 14 | quam deleniti cupiditate impedit iusto. Autem et quasi amet et ut molestiae. Porro 15 | ipsam ducimus perspiciatis cumque et voluptatem sit corrupti voluptas. Ad facere 16 | unde animi numquam dolorum delectus neque consequatur. Sit cupiditate aperiam 17 | vel commodi quo aut libero. 18 | Activated: true 19 | - " Name ": Guadalupe Schimmel II 20 | 'Phone Number ': 203.466.9566 x3281 21 | Email: Craig.Feeney33@gmail.com 22 | Street: 514 Evangeline Divide 23 | " City ": East Brenden 24 | State: Ohio 25 | 'Zip Code ': 77642-5209 26 | 'Routing Number ': '452226335' 27 | Department: Garden 28 | "Company\t": Hammes, Medhurst and Hilpert 29 | 'Created At ': '2021-10-21T07:36:16.072Z' 30 | Profile Photo: http://placeimg.com/640/480 31 | " Description": Natus illo non ratione possimus est quidem ea eius. Et accusamus 32 | recusandae cum quas eum perferendis quo modi dolorem. Doloremque quos fuga omnis 33 | placeat assumenda. Omnis quis consequatur. 34 | Activated: false 35 | - " Name ": Corey Beier 36 | 'Phone Number ': 1-604-307-7955 x87013 37 | Email: Deborah_Marvin@yahoo.com 38 | Street: 77080 Kale Plaza 39 | " City ": Pico Rivera 40 | State: West Virginia 41 | 'Zip Code ': '93612' 42 | 'Routing Number ': '506297760' 43 | Department: Industrial 44 | "Company\t": Leffler - Prosacco 45 | 'Created At ': '2021-05-15T23:53:08.950Z' 46 | Profile Photo: http://placeimg.com/640/480 47 | " Description": Et laborum voluptas officia recusandae et. Quibusdam voluptatem 48 | aspernatur accusamus in sed vero. Est est tempore sit amet cupiditate quasi. Modi 49 | id quae deleniti. Praesentium rerum corrupti architecto harum ut et ipsa velit. 50 | Delectus quis nobis officia et at veniam assumenda. 51 | Activated: false 52 | - " Name ": Margie Greenholt 53 | 'Phone Number ': 962.314.6602 54 | Email: Calista.Swift52@hotmail.com 55 | Street: 7666 Larue Manor 56 | " City ": Martinaton 57 | State: Iowa 58 | 'Zip Code ': '29526' 59 | 'Routing Number ': '671746379' 60 | Department: Electronics 61 | "Company\t": Jones Inc 62 | 'Created At ': '2021-11-13T16:43:12.607Z' 63 | Profile Photo: http://placeimg.com/640/480 64 | " Description": Sit quia in et harum architecto aut qui consectetur. Tempora dolor 65 | earum omnis mollitia magnam quis. Dolor qui dignissimos pariatur minima veniam 66 | illo eligendi. Et expedita consectetur facilis iure. Nostrum sit natus autem tempore. 67 | Activated: true 68 | - " Name ": Delores Bahringer 69 | 'Phone Number ': 567.433.0968 70 | Email: Briana_Hettinger@hotmail.com 71 | Street: 293 Deja Hills 72 | " City ": Lake Justus 73 | State: Connecticut 74 | 'Zip Code ': 50214-4237 75 | 'Routing Number ': '009476813' 76 | Department: Grocery 77 | "Company\t": Gaylord, Hegmann and Stehr 78 | 'Created At ': '2021-04-18T04:34:02.883Z' 79 | Profile Photo: http://placeimg.com/640/480 80 | " Description": Aperiam repellat ut deleniti minus sint rerum. Quaerat eveniet 81 | tempora eius et quis libero. Quis omnis et aut suscipit ducimus corrupti. Dolorum 82 | dolore eos unde reprehenderit dicta magni blanditiis voluptate. Velit neque iste 83 | ipsam nobis dolore vel corrupti. Non suscipit et nisi rem pariatur id aut illo 84 | facilis. 85 | Activated: false 86 | 87 | --------------------------------------------------------------------------------