This is page 41 of 53. Use http://codebase.md/googleapis/genai-toolbox?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .ci
│ ├── continuous.release.cloudbuild.yaml
│ ├── generate_release_table.sh
│ ├── integration.cloudbuild.yaml
│ ├── quickstart_test
│ │ ├── go.integration.cloudbuild.yaml
│ │ ├── js.integration.cloudbuild.yaml
│ │ ├── py.integration.cloudbuild.yaml
│ │ ├── run_go_tests.sh
│ │ ├── run_js_tests.sh
│ │ ├── run_py_tests.sh
│ │ └── setup_hotels_sample.sql
│ ├── test_with_coverage.sh
│ └── versioned.release.cloudbuild.yaml
├── .github
│ ├── auto-label.yaml
│ ├── blunderbuss.yml
│ ├── CODEOWNERS
│ ├── header-checker-lint.yml
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.yml
│ │ ├── config.yml
│ │ ├── feature_request.yml
│ │ └── question.yml
│ ├── label-sync.yml
│ ├── labels.yaml
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── release-please.yml
│ ├── renovate.json5
│ ├── sync-repo-settings.yaml
│ └── workflows
│ ├── cloud_build_failure_reporter.yml
│ ├── deploy_dev_docs.yaml
│ ├── deploy_previous_version_docs.yaml
│ ├── deploy_versioned_docs.yaml
│ ├── docs_deploy.yaml
│ ├── docs_preview_clean.yaml
│ ├── docs_preview_deploy.yaml
│ ├── lint.yaml
│ ├── schedule_reporter.yml
│ ├── sync-labels.yaml
│ └── tests.yaml
├── .gitignore
├── .gitmodules
├── .golangci.yaml
├── .hugo
│ ├── archetypes
│ │ └── default.md
│ ├── assets
│ │ ├── icons
│ │ │ └── logo.svg
│ │ └── scss
│ │ ├── _styles_project.scss
│ │ └── _variables_project.scss
│ ├── go.mod
│ ├── go.sum
│ ├── hugo.toml
│ ├── layouts
│ │ ├── _default
│ │ │ └── home.releases.releases
│ │ ├── index.llms-full.txt
│ │ ├── index.llms.txt
│ │ ├── partials
│ │ │ ├── hooks
│ │ │ │ └── head-end.html
│ │ │ ├── navbar-version-selector.html
│ │ │ ├── page-meta-links.html
│ │ │ └── td
│ │ │ └── render-heading.html
│ │ ├── robot.txt
│ │ └── shortcodes
│ │ ├── include.html
│ │ ├── ipynb.html
│ │ └── regionInclude.html
│ ├── package-lock.json
│ ├── package.json
│ └── static
│ ├── favicons
│ │ ├── android-chrome-192x192.png
│ │ ├── android-chrome-512x512.png
│ │ ├── apple-touch-icon.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ └── favicon.ico
│ └── js
│ └── w3.js
├── CHANGELOG.md
├── cmd
│ ├── options_test.go
│ ├── options.go
│ ├── root_test.go
│ ├── root.go
│ └── version.txt
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── DEVELOPER.md
├── Dockerfile
├── docs
│ └── en
│ ├── _index.md
│ ├── about
│ │ ├── _index.md
│ │ └── faq.md
│ ├── concepts
│ │ ├── _index.md
│ │ └── telemetry
│ │ ├── index.md
│ │ ├── telemetry_flow.png
│ │ └── telemetry_traces.png
│ ├── getting-started
│ │ ├── _index.md
│ │ ├── colab_quickstart.ipynb
│ │ ├── configure.md
│ │ ├── introduction
│ │ │ ├── _index.md
│ │ │ └── architecture.png
│ │ ├── local_quickstart_go.md
│ │ ├── local_quickstart_js.md
│ │ ├── local_quickstart.md
│ │ ├── mcp_quickstart
│ │ │ ├── _index.md
│ │ │ ├── inspector_tools.png
│ │ │ └── inspector.png
│ │ └── quickstart
│ │ ├── go
│ │ │ ├── adkgo
│ │ │ │ ├── go.mod
│ │ │ │ ├── go.sum
│ │ │ │ └── quickstart.go
│ │ │ ├── genAI
│ │ │ │ ├── go.mod
│ │ │ │ ├── go.sum
│ │ │ │ └── quickstart.go
│ │ │ ├── genkit
│ │ │ │ ├── go.mod
│ │ │ │ ├── go.sum
│ │ │ │ └── quickstart.go
│ │ │ ├── langchain
│ │ │ │ ├── go.mod
│ │ │ │ ├── go.sum
│ │ │ │ └── quickstart.go
│ │ │ ├── openAI
│ │ │ │ ├── go.mod
│ │ │ │ ├── go.sum
│ │ │ │ └── quickstart.go
│ │ │ └── quickstart_test.go
│ │ ├── golden.txt
│ │ ├── js
│ │ │ ├── genAI
│ │ │ │ ├── package-lock.json
│ │ │ │ ├── package.json
│ │ │ │ └── quickstart.js
│ │ │ ├── genkit
│ │ │ │ ├── package-lock.json
│ │ │ │ ├── package.json
│ │ │ │ └── quickstart.js
│ │ │ ├── langchain
│ │ │ │ ├── package-lock.json
│ │ │ │ ├── package.json
│ │ │ │ └── quickstart.js
│ │ │ ├── llamaindex
│ │ │ │ ├── package-lock.json
│ │ │ │ ├── package.json
│ │ │ │ └── quickstart.js
│ │ │ └── quickstart.test.js
│ │ ├── python
│ │ │ ├── __init__.py
│ │ │ ├── adk
│ │ │ │ ├── quickstart.py
│ │ │ │ └── requirements.txt
│ │ │ ├── core
│ │ │ │ ├── quickstart.py
│ │ │ │ └── requirements.txt
│ │ │ ├── langchain
│ │ │ │ ├── quickstart.py
│ │ │ │ └── requirements.txt
│ │ │ ├── llamaindex
│ │ │ │ ├── quickstart.py
│ │ │ │ └── requirements.txt
│ │ │ └── quickstart_test.py
│ │ └── shared
│ │ ├── cloud_setup.md
│ │ ├── configure_toolbox.md
│ │ └── database_setup.md
│ ├── how-to
│ │ ├── _index.md
│ │ ├── connect_via_geminicli.md
│ │ ├── connect_via_mcp.md
│ │ ├── connect-ide
│ │ │ ├── _index.md
│ │ │ ├── alloydb_pg_admin_mcp.md
│ │ │ ├── alloydb_pg_mcp.md
│ │ │ ├── bigquery_mcp.md
│ │ │ ├── cloud_sql_mssql_admin_mcp.md
│ │ │ ├── cloud_sql_mssql_mcp.md
│ │ │ ├── cloud_sql_mysql_admin_mcp.md
│ │ │ ├── cloud_sql_mysql_mcp.md
│ │ │ ├── cloud_sql_pg_admin_mcp.md
│ │ │ ├── cloud_sql_pg_mcp.md
│ │ │ ├── firestore_mcp.md
│ │ │ ├── looker_mcp.md
│ │ │ ├── mssql_mcp.md
│ │ │ ├── mysql_mcp.md
│ │ │ ├── neo4j_mcp.md
│ │ │ ├── postgres_mcp.md
│ │ │ ├── spanner_mcp.md
│ │ │ └── sqlite_mcp.md
│ │ ├── deploy_docker.md
│ │ ├── deploy_gke.md
│ │ ├── deploy_toolbox.md
│ │ ├── export_telemetry.md
│ │ └── toolbox-ui
│ │ ├── edit-headers.gif
│ │ ├── edit-headers.png
│ │ ├── index.md
│ │ ├── optional-param-checked.png
│ │ ├── optional-param-unchecked.png
│ │ ├── run-tool.gif
│ │ ├── tools.png
│ │ └── toolsets.png
│ ├── reference
│ │ ├── _index.md
│ │ ├── cli.md
│ │ └── prebuilt-tools.md
│ ├── resources
│ │ ├── _index.md
│ │ ├── authServices
│ │ │ ├── _index.md
│ │ │ └── google.md
│ │ ├── sources
│ │ │ ├── _index.md
│ │ │ ├── alloydb-admin.md
│ │ │ ├── alloydb-pg.md
│ │ │ ├── bigquery.md
│ │ │ ├── bigtable.md
│ │ │ ├── cassandra.md
│ │ │ ├── clickhouse.md
│ │ │ ├── cloud-monitoring.md
│ │ │ ├── cloud-sql-admin.md
│ │ │ ├── cloud-sql-mssql.md
│ │ │ ├── cloud-sql-mysql.md
│ │ │ ├── cloud-sql-pg.md
│ │ │ ├── couchbase.md
│ │ │ ├── dataplex.md
│ │ │ ├── dgraph.md
│ │ │ ├── elasticsearch.md
│ │ │ ├── firebird.md
│ │ │ ├── firestore.md
│ │ │ ├── http.md
│ │ │ ├── looker.md
│ │ │ ├── mindsdb.md
│ │ │ ├── mongodb.md
│ │ │ ├── mssql.md
│ │ │ ├── mysql.md
│ │ │ ├── neo4j.md
│ │ │ ├── oceanbase.md
│ │ │ ├── oracle.md
│ │ │ ├── postgres.md
│ │ │ ├── redis.md
│ │ │ ├── serverless-spark.md
│ │ │ ├── spanner.md
│ │ │ ├── sqlite.md
│ │ │ ├── tidb.md
│ │ │ ├── trino.md
│ │ │ ├── valkey.md
│ │ │ └── yugabytedb.md
│ │ └── tools
│ │ ├── _index.md
│ │ ├── alloydb
│ │ │ ├── _index.md
│ │ │ ├── alloydb-create-cluster.md
│ │ │ ├── alloydb-create-instance.md
│ │ │ ├── alloydb-create-user.md
│ │ │ ├── alloydb-get-cluster.md
│ │ │ ├── alloydb-get-instance.md
│ │ │ ├── alloydb-get-user.md
│ │ │ ├── alloydb-list-clusters.md
│ │ │ ├── alloydb-list-instances.md
│ │ │ ├── alloydb-list-users.md
│ │ │ └── alloydb-wait-for-operation.md
│ │ ├── alloydbainl
│ │ │ ├── _index.md
│ │ │ └── alloydb-ai-nl.md
│ │ ├── bigquery
│ │ │ ├── _index.md
│ │ │ ├── bigquery-analyze-contribution.md
│ │ │ ├── bigquery-conversational-analytics.md
│ │ │ ├── bigquery-execute-sql.md
│ │ │ ├── bigquery-forecast.md
│ │ │ ├── bigquery-get-dataset-info.md
│ │ │ ├── bigquery-get-table-info.md
│ │ │ ├── bigquery-list-dataset-ids.md
│ │ │ ├── bigquery-list-table-ids.md
│ │ │ ├── bigquery-search-catalog.md
│ │ │ └── bigquery-sql.md
│ │ ├── bigtable
│ │ │ ├── _index.md
│ │ │ └── bigtable-sql.md
│ │ ├── cassandra
│ │ │ ├── _index.md
│ │ │ └── cassandra-cql.md
│ │ ├── clickhouse
│ │ │ ├── _index.md
│ │ │ ├── clickhouse-execute-sql.md
│ │ │ ├── clickhouse-list-databases.md
│ │ │ ├── clickhouse-list-tables.md
│ │ │ └── clickhouse-sql.md
│ │ ├── cloudmonitoring
│ │ │ ├── _index.md
│ │ │ └── cloud-monitoring-query-prometheus.md
│ │ ├── cloudsql
│ │ │ ├── _index.md
│ │ │ ├── cloudsqlcreatedatabase.md
│ │ │ ├── cloudsqlcreateusers.md
│ │ │ ├── cloudsqlgetinstances.md
│ │ │ ├── cloudsqllistdatabases.md
│ │ │ ├── cloudsqllistinstances.md
│ │ │ ├── cloudsqlmssqlcreateinstance.md
│ │ │ ├── cloudsqlmysqlcreateinstance.md
│ │ │ ├── cloudsqlpgcreateinstances.md
│ │ │ └── cloudsqlwaitforoperation.md
│ │ ├── couchbase
│ │ │ ├── _index.md
│ │ │ └── couchbase-sql.md
│ │ ├── dataform
│ │ │ ├── _index.md
│ │ │ └── dataform-compile-local.md
│ │ ├── dataplex
│ │ │ ├── _index.md
│ │ │ ├── dataplex-lookup-entry.md
│ │ │ ├── dataplex-search-aspect-types.md
│ │ │ └── dataplex-search-entries.md
│ │ ├── dgraph
│ │ │ ├── _index.md
│ │ │ └── dgraph-dql.md
│ │ ├── elasticsearch
│ │ │ ├── _index.md
│ │ │ └── elasticsearch-esql.md
│ │ ├── firebird
│ │ │ ├── _index.md
│ │ │ ├── firebird-execute-sql.md
│ │ │ └── firebird-sql.md
│ │ ├── firestore
│ │ │ ├── _index.md
│ │ │ ├── firestore-add-documents.md
│ │ │ ├── firestore-delete-documents.md
│ │ │ ├── firestore-get-documents.md
│ │ │ ├── firestore-get-rules.md
│ │ │ ├── firestore-list-collections.md
│ │ │ ├── firestore-query-collection.md
│ │ │ ├── firestore-query.md
│ │ │ ├── firestore-update-document.md
│ │ │ └── firestore-validate-rules.md
│ │ ├── http
│ │ │ ├── _index.md
│ │ │ └── http.md
│ │ ├── looker
│ │ │ ├── _index.md
│ │ │ ├── looker-add-dashboard-element.md
│ │ │ ├── looker-conversational-analytics.md
│ │ │ ├── looker-create-project-file.md
│ │ │ ├── looker-delete-project-file.md
│ │ │ ├── looker-dev-mode.md
│ │ │ ├── looker-get-connection-databases.md
│ │ │ ├── looker-get-connection-schemas.md
│ │ │ ├── looker-get-connection-table-columns.md
│ │ │ ├── looker-get-connection-tables.md
│ │ │ ├── looker-get-connections.md
│ │ │ ├── looker-get-dashboards.md
│ │ │ ├── looker-get-dimensions.md
│ │ │ ├── looker-get-explores.md
│ │ │ ├── looker-get-filters.md
│ │ │ ├── looker-get-looks.md
│ │ │ ├── looker-get-measures.md
│ │ │ ├── looker-get-models.md
│ │ │ ├── looker-get-parameters.md
│ │ │ ├── looker-get-project-file.md
│ │ │ ├── looker-get-project-files.md
│ │ │ ├── looker-get-projects.md
│ │ │ ├── looker-health-analyze.md
│ │ │ ├── looker-health-pulse.md
│ │ │ ├── looker-health-vacuum.md
│ │ │ ├── looker-make-dashboard.md
│ │ │ ├── looker-make-look.md
│ │ │ ├── looker-query-sql.md
│ │ │ ├── looker-query-url.md
│ │ │ ├── looker-query.md
│ │ │ ├── looker-run-look.md
│ │ │ └── looker-update-project-file.md
│ │ ├── mindsdb
│ │ │ ├── _index.md
│ │ │ ├── mindsdb-execute-sql.md
│ │ │ └── mindsdb-sql.md
│ │ ├── mongodb
│ │ │ ├── _index.md
│ │ │ ├── mongodb-aggregate.md
│ │ │ ├── mongodb-delete-many.md
│ │ │ ├── mongodb-delete-one.md
│ │ │ ├── mongodb-find-one.md
│ │ │ ├── mongodb-find.md
│ │ │ ├── mongodb-insert-many.md
│ │ │ ├── mongodb-insert-one.md
│ │ │ ├── mongodb-update-many.md
│ │ │ └── mongodb-update-one.md
│ │ ├── mssql
│ │ │ ├── _index.md
│ │ │ ├── mssql-execute-sql.md
│ │ │ ├── mssql-list-tables.md
│ │ │ └── mssql-sql.md
│ │ ├── mysql
│ │ │ ├── _index.md
│ │ │ ├── mysql-execute-sql.md
│ │ │ ├── mysql-list-active-queries.md
│ │ │ ├── mysql-list-table-fragmentation.md
│ │ │ ├── mysql-list-tables-missing-unique-indexes.md
│ │ │ ├── mysql-list-tables.md
│ │ │ └── mysql-sql.md
│ │ ├── neo4j
│ │ │ ├── _index.md
│ │ │ ├── neo4j-cypher.md
│ │ │ ├── neo4j-execute-cypher.md
│ │ │ └── neo4j-schema.md
│ │ ├── oceanbase
│ │ │ ├── _index.md
│ │ │ ├── oceanbase-execute-sql.md
│ │ │ └── oceanbase-sql.md
│ │ ├── oracle
│ │ │ ├── _index.md
│ │ │ ├── oracle-execute-sql.md
│ │ │ └── oracle-sql.md
│ │ ├── postgres
│ │ │ ├── _index.md
│ │ │ ├── postgres-execute-sql.md
│ │ │ ├── postgres-list-active-queries.md
│ │ │ ├── postgres-list-available-extensions.md
│ │ │ ├── postgres-list-installed-extensions.md
│ │ │ ├── postgres-list-schemas.md
│ │ │ ├── postgres-list-tables.md
│ │ │ ├── postgres-list-views.md
│ │ │ └── postgres-sql.md
│ │ ├── redis
│ │ │ ├── _index.md
│ │ │ └── redis.md
│ │ ├── serverless-spark
│ │ │ ├── _index.md
│ │ │ ├── serverless-spark-cancel-batch.md
│ │ │ ├── serverless-spark-get-batch.md
│ │ │ └── serverless-spark-list-batches.md
│ │ ├── spanner
│ │ │ ├── _index.md
│ │ │ ├── spanner-execute-sql.md
│ │ │ ├── spanner-list-tables.md
│ │ │ └── spanner-sql.md
│ │ ├── sqlite
│ │ │ ├── _index.md
│ │ │ ├── sqlite-execute-sql.md
│ │ │ └── sqlite-sql.md
│ │ ├── tidb
│ │ │ ├── _index.md
│ │ │ ├── tidb-execute-sql.md
│ │ │ └── tidb-sql.md
│ │ ├── trino
│ │ │ ├── _index.md
│ │ │ ├── trino-execute-sql.md
│ │ │ └── trino-sql.md
│ │ ├── utility
│ │ │ ├── _index.md
│ │ │ └── wait.md
│ │ ├── valkey
│ │ │ ├── _index.md
│ │ │ └── valkey.md
│ │ └── yuagbytedb
│ │ ├── _index.md
│ │ └── yugabytedb-sql.md
│ ├── samples
│ │ ├── _index.md
│ │ ├── alloydb
│ │ │ ├── _index.md
│ │ │ ├── ai-nl
│ │ │ │ ├── alloydb_ai_nl.ipynb
│ │ │ │ └── index.md
│ │ │ └── mcp_quickstart.md
│ │ ├── bigquery
│ │ │ ├── _index.md
│ │ │ ├── colab_quickstart_bigquery.ipynb
│ │ │ ├── local_quickstart.md
│ │ │ └── mcp_quickstart
│ │ │ ├── _index.md
│ │ │ ├── inspector_tools.png
│ │ │ └── inspector.png
│ │ └── looker
│ │ ├── _index.md
│ │ ├── looker_gemini_oauth
│ │ │ ├── _index.md
│ │ │ ├── authenticated.png
│ │ │ ├── authorize.png
│ │ │ └── registration.png
│ │ ├── looker_gemini.md
│ │ └── looker_mcp_inspector
│ │ ├── _index.md
│ │ ├── inspector_tools.png
│ │ └── inspector.png
│ └── sdks
│ ├── _index.md
│ ├── go-sdk.md
│ ├── js-sdk.md
│ └── python-sdk.md
├── gemini-extension.json
├── go.mod
├── go.sum
├── internal
│ ├── auth
│ │ ├── auth.go
│ │ └── google
│ │ └── google.go
│ ├── log
│ │ ├── handler.go
│ │ ├── log_test.go
│ │ ├── log.go
│ │ └── logger.go
│ ├── prebuiltconfigs
│ │ ├── prebuiltconfigs_test.go
│ │ ├── prebuiltconfigs.go
│ │ └── tools
│ │ ├── alloydb-postgres-admin.yaml
│ │ ├── alloydb-postgres-observability.yaml
│ │ ├── alloydb-postgres.yaml
│ │ ├── bigquery.yaml
│ │ ├── clickhouse.yaml
│ │ ├── cloud-sql-mssql-admin.yaml
│ │ ├── cloud-sql-mssql-observability.yaml
│ │ ├── cloud-sql-mssql.yaml
│ │ ├── cloud-sql-mysql-admin.yaml
│ │ ├── cloud-sql-mysql-observability.yaml
│ │ ├── cloud-sql-mysql.yaml
│ │ ├── cloud-sql-postgres-admin.yaml
│ │ ├── cloud-sql-postgres-observability.yaml
│ │ ├── cloud-sql-postgres.yaml
│ │ ├── dataplex.yaml
│ │ ├── elasticsearch.yaml
│ │ ├── firestore.yaml
│ │ ├── looker-conversational-analytics.yaml
│ │ ├── looker.yaml
│ │ ├── mindsdb.yaml
│ │ ├── mssql.yaml
│ │ ├── mysql.yaml
│ │ ├── neo4j.yaml
│ │ ├── oceanbase.yaml
│ │ ├── postgres.yaml
│ │ ├── serverless-spark.yaml
│ │ ├── spanner-postgres.yaml
│ │ ├── spanner.yaml
│ │ └── sqlite.yaml
│ ├── server
│ │ ├── api_test.go
│ │ ├── api.go
│ │ ├── common_test.go
│ │ ├── config.go
│ │ ├── mcp
│ │ │ ├── jsonrpc
│ │ │ │ ├── jsonrpc_test.go
│ │ │ │ └── jsonrpc.go
│ │ │ ├── mcp.go
│ │ │ ├── util
│ │ │ │ └── lifecycle.go
│ │ │ ├── v20241105
│ │ │ │ ├── method.go
│ │ │ │ └── types.go
│ │ │ ├── v20250326
│ │ │ │ ├── method.go
│ │ │ │ └── types.go
│ │ │ └── v20250618
│ │ │ ├── method.go
│ │ │ └── types.go
│ │ ├── mcp_test.go
│ │ ├── mcp.go
│ │ ├── server_test.go
│ │ ├── server.go
│ │ ├── static
│ │ │ ├── assets
│ │ │ │ └── mcptoolboxlogo.png
│ │ │ ├── css
│ │ │ │ └── style.css
│ │ │ ├── index.html
│ │ │ ├── js
│ │ │ │ ├── auth.js
│ │ │ │ ├── loadTools.js
│ │ │ │ ├── mainContent.js
│ │ │ │ ├── navbar.js
│ │ │ │ ├── runTool.js
│ │ │ │ ├── toolDisplay.js
│ │ │ │ ├── tools.js
│ │ │ │ └── toolsets.js
│ │ │ ├── tools.html
│ │ │ └── toolsets.html
│ │ ├── web_test.go
│ │ └── web.go
│ ├── sources
│ │ ├── alloydbadmin
│ │ │ ├── alloydbadmin_test.go
│ │ │ └── alloydbadmin.go
│ │ ├── alloydbpg
│ │ │ ├── alloydb_pg_test.go
│ │ │ └── alloydb_pg.go
│ │ ├── bigquery
│ │ │ ├── bigquery_test.go
│ │ │ ├── bigquery.go
│ │ │ └── cache.go
│ │ ├── bigtable
│ │ │ ├── bigtable_test.go
│ │ │ └── bigtable.go
│ │ ├── cassandra
│ │ │ ├── cassandra_test.go
│ │ │ └── cassandra.go
│ │ ├── clickhouse
│ │ │ ├── clickhouse_test.go
│ │ │ └── clickhouse.go
│ │ ├── cloudmonitoring
│ │ │ ├── cloud_monitoring_test.go
│ │ │ └── cloud_monitoring.go
│ │ ├── cloudsqladmin
│ │ │ ├── cloud_sql_admin_test.go
│ │ │ └── cloud_sql_admin.go
│ │ ├── cloudsqlmssql
│ │ │ ├── cloud_sql_mssql_test.go
│ │ │ └── cloud_sql_mssql.go
│ │ ├── cloudsqlmysql
│ │ │ ├── cloud_sql_mysql_test.go
│ │ │ └── cloud_sql_mysql.go
│ │ ├── cloudsqlpg
│ │ │ ├── cloud_sql_pg_test.go
│ │ │ └── cloud_sql_pg.go
│ │ ├── couchbase
│ │ │ ├── couchbase_test.go
│ │ │ └── couchbase.go
│ │ ├── dataplex
│ │ │ ├── dataplex_test.go
│ │ │ └── dataplex.go
│ │ ├── dgraph
│ │ │ ├── dgraph_test.go
│ │ │ └── dgraph.go
│ │ ├── dialect.go
│ │ ├── elasticsearch
│ │ │ ├── elasticsearch_test.go
│ │ │ └── elasticsearch.go
│ │ ├── firebird
│ │ │ ├── firebird_test.go
│ │ │ └── firebird.go
│ │ ├── firestore
│ │ │ ├── firestore_test.go
│ │ │ └── firestore.go
│ │ ├── http
│ │ │ ├── http_test.go
│ │ │ └── http.go
│ │ ├── ip_type.go
│ │ ├── looker
│ │ │ ├── looker_test.go
│ │ │ └── looker.go
│ │ ├── mindsdb
│ │ │ ├── mindsdb_test.go
│ │ │ └── mindsdb.go
│ │ ├── mongodb
│ │ │ ├── mongodb_test.go
│ │ │ └── mongodb.go
│ │ ├── mssql
│ │ │ ├── mssql_test.go
│ │ │ └── mssql.go
│ │ ├── mysql
│ │ │ ├── mysql_test.go
│ │ │ └── mysql.go
│ │ ├── neo4j
│ │ │ ├── neo4j_test.go
│ │ │ └── neo4j.go
│ │ ├── oceanbase
│ │ │ ├── oceanbase_test.go
│ │ │ └── oceanbase.go
│ │ ├── oracle
│ │ │ └── oracle.go
│ │ ├── postgres
│ │ │ ├── postgres_test.go
│ │ │ └── postgres.go
│ │ ├── redis
│ │ │ ├── redis_test.go
│ │ │ └── redis.go
│ │ ├── serverlessspark
│ │ │ ├── serverlessspark_test.go
│ │ │ └── serverlessspark.go
│ │ ├── sources.go
│ │ ├── spanner
│ │ │ ├── spanner_test.go
│ │ │ └── spanner.go
│ │ ├── sqlite
│ │ │ ├── sqlite_test.go
│ │ │ └── sqlite.go
│ │ ├── tidb
│ │ │ ├── tidb_test.go
│ │ │ └── tidb.go
│ │ ├── trino
│ │ │ ├── trino_test.go
│ │ │ └── trino.go
│ │ ├── util.go
│ │ ├── valkey
│ │ │ ├── valkey_test.go
│ │ │ └── valkey.go
│ │ └── yugabytedb
│ │ ├── yugabytedb_test.go
│ │ └── yugabytedb.go
│ ├── telemetry
│ │ ├── instrumentation.go
│ │ └── telemetry.go
│ ├── testutils
│ │ └── testutils.go
│ ├── tools
│ │ ├── alloydb
│ │ │ ├── alloydbcreatecluster
│ │ │ │ ├── alloydbcreatecluster_test.go
│ │ │ │ └── alloydbcreatecluster.go
│ │ │ ├── alloydbcreateinstance
│ │ │ │ ├── alloydbcreateinstance_test.go
│ │ │ │ └── alloydbcreateinstance.go
│ │ │ ├── alloydbcreateuser
│ │ │ │ ├── alloydbcreateuser_test.go
│ │ │ │ └── alloydbcreateuser.go
│ │ │ ├── alloydbgetcluster
│ │ │ │ ├── alloydbgetcluster_test.go
│ │ │ │ └── alloydbgetcluster.go
│ │ │ ├── alloydbgetinstance
│ │ │ │ ├── alloydbgetinstance_test.go
│ │ │ │ └── alloydbgetinstance.go
│ │ │ ├── alloydbgetuser
│ │ │ │ ├── alloydbgetuser_test.go
│ │ │ │ └── alloydbgetuser.go
│ │ │ ├── alloydblistclusters
│ │ │ │ ├── alloydblistclusters_test.go
│ │ │ │ └── alloydblistclusters.go
│ │ │ ├── alloydblistinstances
│ │ │ │ ├── alloydblistinstances_test.go
│ │ │ │ └── alloydblistinstances.go
│ │ │ ├── alloydblistusers
│ │ │ │ ├── alloydblistusers_test.go
│ │ │ │ └── alloydblistusers.go
│ │ │ └── alloydbwaitforoperation
│ │ │ ├── alloydbwaitforoperation_test.go
│ │ │ └── alloydbwaitforoperation.go
│ │ ├── alloydbainl
│ │ │ ├── alloydbainl_test.go
│ │ │ └── alloydbainl.go
│ │ ├── bigquery
│ │ │ ├── bigqueryanalyzecontribution
│ │ │ │ ├── bigqueryanalyzecontribution_test.go
│ │ │ │ └── bigqueryanalyzecontribution.go
│ │ │ ├── bigquerycommon
│ │ │ │ ├── table_name_parser_test.go
│ │ │ │ ├── table_name_parser.go
│ │ │ │ └── util.go
│ │ │ ├── bigqueryconversationalanalytics
│ │ │ │ ├── bigqueryconversationalanalytics_test.go
│ │ │ │ └── bigqueryconversationalanalytics.go
│ │ │ ├── bigqueryexecutesql
│ │ │ │ ├── bigqueryexecutesql_test.go
│ │ │ │ └── bigqueryexecutesql.go
│ │ │ ├── bigqueryforecast
│ │ │ │ ├── bigqueryforecast_test.go
│ │ │ │ └── bigqueryforecast.go
│ │ │ ├── bigquerygetdatasetinfo
│ │ │ │ ├── bigquerygetdatasetinfo_test.go
│ │ │ │ └── bigquerygetdatasetinfo.go
│ │ │ ├── bigquerygettableinfo
│ │ │ │ ├── bigquerygettableinfo_test.go
│ │ │ │ └── bigquerygettableinfo.go
│ │ │ ├── bigquerylistdatasetids
│ │ │ │ ├── bigquerylistdatasetids_test.go
│ │ │ │ └── bigquerylistdatasetids.go
│ │ │ ├── bigquerylisttableids
│ │ │ │ ├── bigquerylisttableids_test.go
│ │ │ │ └── bigquerylisttableids.go
│ │ │ ├── bigquerysearchcatalog
│ │ │ │ ├── bigquerysearchcatalog_test.go
│ │ │ │ └── bigquerysearchcatalog.go
│ │ │ └── bigquerysql
│ │ │ ├── bigquerysql_test.go
│ │ │ └── bigquerysql.go
│ │ ├── bigtable
│ │ │ ├── bigtable_test.go
│ │ │ └── bigtable.go
│ │ ├── cassandra
│ │ │ └── cassandracql
│ │ │ ├── cassandracql_test.go
│ │ │ └── cassandracql.go
│ │ ├── clickhouse
│ │ │ ├── clickhouseexecutesql
│ │ │ │ ├── clickhouseexecutesql_test.go
│ │ │ │ └── clickhouseexecutesql.go
│ │ │ ├── clickhouselistdatabases
│ │ │ │ ├── clickhouselistdatabases_test.go
│ │ │ │ └── clickhouselistdatabases.go
│ │ │ ├── clickhouselisttables
│ │ │ │ ├── clickhouselisttables_test.go
│ │ │ │ └── clickhouselisttables.go
│ │ │ └── clickhousesql
│ │ │ ├── clickhousesql_test.go
│ │ │ └── clickhousesql.go
│ │ ├── cloudmonitoring
│ │ │ ├── cloudmonitoring_test.go
│ │ │ └── cloudmonitoring.go
│ │ ├── cloudsql
│ │ │ ├── cloudsqlcreatedatabase
│ │ │ │ ├── cloudsqlcreatedatabase_test.go
│ │ │ │ └── cloudsqlcreatedatabase.go
│ │ │ ├── cloudsqlcreateusers
│ │ │ │ ├── cloudsqlcreateusers_test.go
│ │ │ │ └── cloudsqlcreateusers.go
│ │ │ ├── cloudsqlgetinstances
│ │ │ │ ├── cloudsqlgetinstances_test.go
│ │ │ │ └── cloudsqlgetinstances.go
│ │ │ ├── cloudsqllistdatabases
│ │ │ │ ├── cloudsqllistdatabases_test.go
│ │ │ │ └── cloudsqllistdatabases.go
│ │ │ ├── cloudsqllistinstances
│ │ │ │ ├── cloudsqllistinstances_test.go
│ │ │ │ └── cloudsqllistinstances.go
│ │ │ └── cloudsqlwaitforoperation
│ │ │ ├── cloudsqlwaitforoperation_test.go
│ │ │ └── cloudsqlwaitforoperation.go
│ │ ├── cloudsqlmssql
│ │ │ └── cloudsqlmssqlcreateinstance
│ │ │ ├── cloudsqlmssqlcreateinstance_test.go
│ │ │ └── cloudsqlmssqlcreateinstance.go
│ │ ├── cloudsqlmysql
│ │ │ └── cloudsqlmysqlcreateinstance
│ │ │ ├── cloudsqlmysqlcreateinstance_test.go
│ │ │ └── cloudsqlmysqlcreateinstance.go
│ │ ├── cloudsqlpg
│ │ │ └── cloudsqlpgcreateinstances
│ │ │ ├── cloudsqlpgcreateinstances_test.go
│ │ │ └── cloudsqlpgcreateinstances.go
│ │ ├── common_test.go
│ │ ├── common.go
│ │ ├── couchbase
│ │ │ ├── couchbase_test.go
│ │ │ └── couchbase.go
│ │ ├── dataform
│ │ │ └── dataformcompilelocal
│ │ │ ├── dataformcompilelocal_test.go
│ │ │ └── dataformcompilelocal.go
│ │ ├── dataplex
│ │ │ ├── dataplexlookupentry
│ │ │ │ ├── dataplexlookupentry_test.go
│ │ │ │ └── dataplexlookupentry.go
│ │ │ ├── dataplexsearchaspecttypes
│ │ │ │ ├── dataplexsearchaspecttypes_test.go
│ │ │ │ └── dataplexsearchaspecttypes.go
│ │ │ └── dataplexsearchentries
│ │ │ ├── dataplexsearchentries_test.go
│ │ │ └── dataplexsearchentries.go
│ │ ├── dgraph
│ │ │ ├── dgraph_test.go
│ │ │ └── dgraph.go
│ │ ├── elasticsearch
│ │ │ └── elasticsearchesql
│ │ │ ├── elasticsearchesql_test.go
│ │ │ └── elasticsearchesql.go
│ │ ├── firebird
│ │ │ ├── firebirdexecutesql
│ │ │ │ ├── firebirdexecutesql_test.go
│ │ │ │ └── firebirdexecutesql.go
│ │ │ └── firebirdsql
│ │ │ ├── firebirdsql_test.go
│ │ │ └── firebirdsql.go
│ │ ├── firestore
│ │ │ ├── firestoreadddocuments
│ │ │ │ ├── firestoreadddocuments_test.go
│ │ │ │ └── firestoreadddocuments.go
│ │ │ ├── firestoredeletedocuments
│ │ │ │ ├── firestoredeletedocuments_test.go
│ │ │ │ └── firestoredeletedocuments.go
│ │ │ ├── firestoregetdocuments
│ │ │ │ ├── firestoregetdocuments_test.go
│ │ │ │ └── firestoregetdocuments.go
│ │ │ ├── firestoregetrules
│ │ │ │ ├── firestoregetrules_test.go
│ │ │ │ └── firestoregetrules.go
│ │ │ ├── firestorelistcollections
│ │ │ │ ├── firestorelistcollections_test.go
│ │ │ │ └── firestorelistcollections.go
│ │ │ ├── firestorequery
│ │ │ │ ├── firestorequery_test.go
│ │ │ │ └── firestorequery.go
│ │ │ ├── firestorequerycollection
│ │ │ │ ├── firestorequerycollection_test.go
│ │ │ │ └── firestorequerycollection.go
│ │ │ ├── firestoreupdatedocument
│ │ │ │ ├── firestoreupdatedocument_test.go
│ │ │ │ └── firestoreupdatedocument.go
│ │ │ ├── firestorevalidaterules
│ │ │ │ ├── firestorevalidaterules_test.go
│ │ │ │ └── firestorevalidaterules.go
│ │ │ └── util
│ │ │ ├── converter_test.go
│ │ │ ├── converter.go
│ │ │ ├── validator_test.go
│ │ │ └── validator.go
│ │ ├── http
│ │ │ ├── http_test.go
│ │ │ └── http.go
│ │ ├── http_method.go
│ │ ├── looker
│ │ │ ├── lookeradddashboardelement
│ │ │ │ ├── lookeradddashboardelement_test.go
│ │ │ │ └── lookeradddashboardelement.go
│ │ │ ├── lookercommon
│ │ │ │ ├── lookercommon_test.go
│ │ │ │ └── lookercommon.go
│ │ │ ├── lookerconversationalanalytics
│ │ │ │ ├── lookerconversationalanalytics_test.go
│ │ │ │ └── lookerconversationalanalytics.go
│ │ │ ├── lookercreateprojectfile
│ │ │ │ ├── lookercreateprojectfile_test.go
│ │ │ │ └── lookercreateprojectfile.go
│ │ │ ├── lookerdeleteprojectfile
│ │ │ │ ├── lookerdeleteprojectfile_test.go
│ │ │ │ └── lookerdeleteprojectfile.go
│ │ │ ├── lookerdevmode
│ │ │ │ ├── lookerdevmode_test.go
│ │ │ │ └── lookerdevmode.go
│ │ │ ├── lookergetconnectiondatabases
│ │ │ │ ├── lookergetconnectiondatabases_test.go
│ │ │ │ └── lookergetconnectiondatabases.go
│ │ │ ├── lookergetconnections
│ │ │ │ ├── lookergetconnections_test.go
│ │ │ │ └── lookergetconnections.go
│ │ │ ├── lookergetconnectionschemas
│ │ │ │ ├── lookergetconnectionschemas_test.go
│ │ │ │ └── lookergetconnectionschemas.go
│ │ │ ├── lookergetconnectiontablecolumns
│ │ │ │ ├── lookergetconnectiontablecolumns_test.go
│ │ │ │ └── lookergetconnectiontablecolumns.go
│ │ │ ├── lookergetconnectiontables
│ │ │ │ ├── lookergetconnectiontables_test.go
│ │ │ │ └── lookergetconnectiontables.go
│ │ │ ├── lookergetdashboards
│ │ │ │ ├── lookergetdashboards_test.go
│ │ │ │ └── lookergetdashboards.go
│ │ │ ├── lookergetdimensions
│ │ │ │ ├── lookergetdimensions_test.go
│ │ │ │ └── lookergetdimensions.go
│ │ │ ├── lookergetexplores
│ │ │ │ ├── lookergetexplores_test.go
│ │ │ │ └── lookergetexplores.go
│ │ │ ├── lookergetfilters
│ │ │ │ ├── lookergetfilters_test.go
│ │ │ │ └── lookergetfilters.go
│ │ │ ├── lookergetlooks
│ │ │ │ ├── lookergetlooks_test.go
│ │ │ │ └── lookergetlooks.go
│ │ │ ├── lookergetmeasures
│ │ │ │ ├── lookergetmeasures_test.go
│ │ │ │ └── lookergetmeasures.go
│ │ │ ├── lookergetmodels
│ │ │ │ ├── lookergetmodels_test.go
│ │ │ │ └── lookergetmodels.go
│ │ │ ├── lookergetparameters
│ │ │ │ ├── lookergetparameters_test.go
│ │ │ │ └── lookergetparameters.go
│ │ │ ├── lookergetprojectfile
│ │ │ │ ├── lookergetprojectfile_test.go
│ │ │ │ └── lookergetprojectfile.go
│ │ │ ├── lookergetprojectfiles
│ │ │ │ ├── lookergetprojectfiles_test.go
│ │ │ │ └── lookergetprojectfiles.go
│ │ │ ├── lookergetprojects
│ │ │ │ ├── lookergetprojects_test.go
│ │ │ │ └── lookergetprojects.go
│ │ │ ├── lookerhealthanalyze
│ │ │ │ ├── lookerhealthanalyze_test.go
│ │ │ │ └── lookerhealthanalyze.go
│ │ │ ├── lookerhealthpulse
│ │ │ │ ├── lookerhealthpulse_test.go
│ │ │ │ └── lookerhealthpulse.go
│ │ │ ├── lookerhealthvacuum
│ │ │ │ ├── lookerhealthvacuum_test.go
│ │ │ │ └── lookerhealthvacuum.go
│ │ │ ├── lookermakedashboard
│ │ │ │ ├── lookermakedashboard_test.go
│ │ │ │ └── lookermakedashboard.go
│ │ │ ├── lookermakelook
│ │ │ │ ├── lookermakelook_test.go
│ │ │ │ └── lookermakelook.go
│ │ │ ├── lookerquery
│ │ │ │ ├── lookerquery_test.go
│ │ │ │ └── lookerquery.go
│ │ │ ├── lookerquerysql
│ │ │ │ ├── lookerquerysql_test.go
│ │ │ │ └── lookerquerysql.go
│ │ │ ├── lookerqueryurl
│ │ │ │ ├── lookerqueryurl_test.go
│ │ │ │ └── lookerqueryurl.go
│ │ │ ├── lookerrunlook
│ │ │ │ ├── lookerrunlook_test.go
│ │ │ │ └── lookerrunlook.go
│ │ │ └── lookerupdateprojectfile
│ │ │ ├── lookerupdateprojectfile_test.go
│ │ │ └── lookerupdateprojectfile.go
│ │ ├── mindsdb
│ │ │ ├── mindsdbexecutesql
│ │ │ │ ├── mindsdbexecutesql_test.go
│ │ │ │ └── mindsdbexecutesql.go
│ │ │ └── mindsdbsql
│ │ │ ├── mindsdbsql_test.go
│ │ │ └── mindsdbsql.go
│ │ ├── mongodb
│ │ │ ├── mongodbaggregate
│ │ │ │ ├── mongodbaggregate_test.go
│ │ │ │ └── mongodbaggregate.go
│ │ │ ├── mongodbdeletemany
│ │ │ │ ├── mongodbdeletemany_test.go
│ │ │ │ └── mongodbdeletemany.go
│ │ │ ├── mongodbdeleteone
│ │ │ │ ├── mongodbdeleteone_test.go
│ │ │ │ └── mongodbdeleteone.go
│ │ │ ├── mongodbfind
│ │ │ │ ├── mongodbfind_test.go
│ │ │ │ └── mongodbfind.go
│ │ │ ├── mongodbfindone
│ │ │ │ ├── mongodbfindone_test.go
│ │ │ │ └── mongodbfindone.go
│ │ │ ├── mongodbinsertmany
│ │ │ │ ├── mongodbinsertmany_test.go
│ │ │ │ └── mongodbinsertmany.go
│ │ │ ├── mongodbinsertone
│ │ │ │ ├── mongodbinsertone_test.go
│ │ │ │ └── mongodbinsertone.go
│ │ │ ├── mongodbupdatemany
│ │ │ │ ├── mongodbupdatemany_test.go
│ │ │ │ └── mongodbupdatemany.go
│ │ │ └── mongodbupdateone
│ │ │ ├── mongodbupdateone_test.go
│ │ │ └── mongodbupdateone.go
│ │ ├── mssql
│ │ │ ├── mssqlexecutesql
│ │ │ │ ├── mssqlexecutesql_test.go
│ │ │ │ └── mssqlexecutesql.go
│ │ │ ├── mssqllisttables
│ │ │ │ ├── mssqllisttables_test.go
│ │ │ │ └── mssqllisttables.go
│ │ │ └── mssqlsql
│ │ │ ├── mssqlsql_test.go
│ │ │ └── mssqlsql.go
│ │ ├── mysql
│ │ │ ├── mysqlcommon
│ │ │ │ └── mysqlcommon.go
│ │ │ ├── mysqlexecutesql
│ │ │ │ ├── mysqlexecutesql_test.go
│ │ │ │ └── mysqlexecutesql.go
│ │ │ ├── mysqllistactivequeries
│ │ │ │ ├── mysqllistactivequeries_test.go
│ │ │ │ └── mysqllistactivequeries.go
│ │ │ ├── mysqllisttablefragmentation
│ │ │ │ ├── mysqllisttablefragmentation_test.go
│ │ │ │ └── mysqllisttablefragmentation.go
│ │ │ ├── mysqllisttables
│ │ │ │ ├── mysqllisttables_test.go
│ │ │ │ └── mysqllisttables.go
│ │ │ ├── mysqllisttablesmissinguniqueindexes
│ │ │ │ ├── mysqllisttablesmissinguniqueindexes_test.go
│ │ │ │ └── mysqllisttablesmissinguniqueindexes.go
│ │ │ └── mysqlsql
│ │ │ ├── mysqlsql_test.go
│ │ │ └── mysqlsql.go
│ │ ├── neo4j
│ │ │ ├── neo4jcypher
│ │ │ │ ├── neo4jcypher_test.go
│ │ │ │ └── neo4jcypher.go
│ │ │ ├── neo4jexecutecypher
│ │ │ │ ├── classifier
│ │ │ │ │ ├── classifier_test.go
│ │ │ │ │ └── classifier.go
│ │ │ │ ├── neo4jexecutecypher_test.go
│ │ │ │ └── neo4jexecutecypher.go
│ │ │ └── neo4jschema
│ │ │ ├── cache
│ │ │ │ ├── cache_test.go
│ │ │ │ └── cache.go
│ │ │ ├── helpers
│ │ │ │ ├── helpers_test.go
│ │ │ │ └── helpers.go
│ │ │ ├── neo4jschema_test.go
│ │ │ ├── neo4jschema.go
│ │ │ └── types
│ │ │ └── types.go
│ │ ├── oceanbase
│ │ │ ├── oceanbaseexecutesql
│ │ │ │ ├── oceanbaseexecutesql_test.go
│ │ │ │ └── oceanbaseexecutesql.go
│ │ │ └── oceanbasesql
│ │ │ ├── oceanbasesql_test.go
│ │ │ └── oceanbasesql.go
│ │ ├── oracle
│ │ │ ├── oracleexecutesql
│ │ │ │ └── oracleexecutesql.go
│ │ │ └── oraclesql
│ │ │ └── oraclesql.go
│ │ ├── parameters_test.go
│ │ ├── parameters.go
│ │ ├── postgres
│ │ │ ├── postgresexecutesql
│ │ │ │ ├── postgresexecutesql_test.go
│ │ │ │ └── postgresexecutesql.go
│ │ │ ├── postgreslistactivequeries
│ │ │ │ ├── postgreslistactivequeries_test.go
│ │ │ │ └── postgreslistactivequeries.go
│ │ │ ├── postgreslistavailableextensions
│ │ │ │ ├── postgreslistavailableextensions_test.go
│ │ │ │ └── postgreslistavailableextensions.go
│ │ │ ├── postgreslistinstalledextensions
│ │ │ │ ├── postgreslistinstalledextensions_test.go
│ │ │ │ └── postgreslistinstalledextensions.go
│ │ │ ├── postgreslistschemas
│ │ │ │ ├── postgreslistschemas_test.go
│ │ │ │ └── postgreslistschemas.go
│ │ │ ├── postgreslisttables
│ │ │ │ ├── postgreslisttables_test.go
│ │ │ │ └── postgreslisttables.go
│ │ │ ├── postgreslistviews
│ │ │ │ ├── postgreslistviews_test.go
│ │ │ │ └── postgreslistviews.go
│ │ │ └── postgressql
│ │ │ ├── postgressql_test.go
│ │ │ └── postgressql.go
│ │ ├── redis
│ │ │ ├── redis_test.go
│ │ │ └── redis.go
│ │ ├── serverlessspark
│ │ │ ├── serverlesssparkcancelbatch
│ │ │ │ ├── serverlesssparkcancelbatch_test.go
│ │ │ │ └── serverlesssparkcancelbatch.go
│ │ │ ├── serverlesssparkgetbatch
│ │ │ │ ├── serverlesssparkgetbatch_test.go
│ │ │ │ └── serverlesssparkgetbatch.go
│ │ │ └── serverlesssparklistbatches
│ │ │ ├── serverlesssparklistbatches_test.go
│ │ │ └── serverlesssparklistbatches.go
│ │ ├── spanner
│ │ │ ├── spannerexecutesql
│ │ │ │ ├── spannerexecutesql_test.go
│ │ │ │ └── spannerexecutesql.go
│ │ │ ├── spannerlisttables
│ │ │ │ ├── spannerlisttables_test.go
│ │ │ │ └── spannerlisttables.go
│ │ │ └── spannersql
│ │ │ ├── spanner_test.go
│ │ │ └── spannersql.go
│ │ ├── sqlite
│ │ │ ├── sqliteexecutesql
│ │ │ │ ├── sqliteexecutesql_test.go
│ │ │ │ └── sqliteexecutesql.go
│ │ │ └── sqlitesql
│ │ │ ├── sqlitesql_test.go
│ │ │ └── sqlitesql.go
│ │ ├── tidb
│ │ │ ├── tidbexecutesql
│ │ │ │ ├── tidbexecutesql_test.go
│ │ │ │ └── tidbexecutesql.go
│ │ │ └── tidbsql
│ │ │ ├── tidbsql_test.go
│ │ │ └── tidbsql.go
│ │ ├── tools_test.go
│ │ ├── tools.go
│ │ ├── toolsets.go
│ │ ├── trino
│ │ │ ├── trinoexecutesql
│ │ │ │ ├── trinoexecutesql_test.go
│ │ │ │ └── trinoexecutesql.go
│ │ │ └── trinosql
│ │ │ ├── trinosql_test.go
│ │ │ └── trinosql.go
│ │ ├── utility
│ │ │ └── wait
│ │ │ ├── wait_test.go
│ │ │ └── wait.go
│ │ ├── valkey
│ │ │ ├── valkey_test.go
│ │ │ └── valkey.go
│ │ └── yugabytedbsql
│ │ ├── yugabytedbsql_test.go
│ │ └── yugabytedbsql.go
│ └── util
│ ├── orderedmap
│ │ ├── orderedmap_test.go
│ │ └── orderedmap.go
│ └── util.go
├── LICENSE
├── logo.png
├── main.go
├── MCP-TOOLBOX-EXTENSION.md
├── README.md
└── tests
├── alloydb
│ ├── alloydb_integration_test.go
│ └── alloydb_wait_for_operation_test.go
├── alloydbainl
│ └── alloydb_ai_nl_integration_test.go
├── alloydbpg
│ └── alloydb_pg_integration_test.go
├── auth.go
├── bigquery
│ └── bigquery_integration_test.go
├── bigtable
│ └── bigtable_integration_test.go
├── cassandra
│ └── cassandra_integration_test.go
├── clickhouse
│ └── clickhouse_integration_test.go
├── cloudmonitoring
│ └── cloud_monitoring_integration_test.go
├── cloudsql
│ ├── cloud_sql_create_database_test.go
│ ├── cloud_sql_create_users_test.go
│ ├── cloud_sql_get_instances_test.go
│ ├── cloud_sql_list_databases_test.go
│ ├── cloudsql_list_instances_test.go
│ └── cloudsql_wait_for_operation_test.go
├── cloudsqlmssql
│ ├── cloud_sql_mssql_create_instance_integration_test.go
│ └── cloud_sql_mssql_integration_test.go
├── cloudsqlmysql
│ ├── cloud_sql_mysql_create_instance_integration_test.go
│ └── cloud_sql_mysql_integration_test.go
├── cloudsqlpg
│ ├── cloud_sql_pg_create_instances_test.go
│ └── cloud_sql_pg_integration_test.go
├── common.go
├── couchbase
│ └── couchbase_integration_test.go
├── dataform
│ └── dataform_integration_test.go
├── dataplex
│ └── dataplex_integration_test.go
├── dgraph
│ └── dgraph_integration_test.go
├── elasticsearch
│ └── elasticsearch_integration_test.go
├── firebird
│ └── firebird_integration_test.go
├── firestore
│ └── firestore_integration_test.go
├── http
│ └── http_integration_test.go
├── looker
│ └── looker_integration_test.go
├── mindsdb
│ └── mindsdb_integration_test.go
├── mongodb
│ └── mongodb_integration_test.go
├── mssql
│ └── mssql_integration_test.go
├── mysql
│ └── mysql_integration_test.go
├── neo4j
│ └── neo4j_integration_test.go
├── oceanbase
│ └── oceanbase_integration_test.go
├── option.go
├── oracle
│ └── oracle_integration_test.go
├── postgres
│ └── postgres_integration_test.go
├── redis
│ └── redis_test.go
├── server.go
├── serverlessspark
│ └── serverless_spark_integration_test.go
├── source.go
├── spanner
│ └── spanner_integration_test.go
├── sqlite
│ └── sqlite_integration_test.go
├── tidb
│ └── tidb_integration_test.go
├── tool.go
├── trino
│ └── trino_integration_test.go
├── utility
│ └── wait_integration_test.go
├── valkey
│ └── valkey_test.go
└── yugabytedb
└── yugabytedb_integration_test.go
```
# Files
--------------------------------------------------------------------------------
/docs/en/reference/prebuilt-tools.md:
--------------------------------------------------------------------------------
```markdown
1 | ---
2 | title: "Prebuilt Tools"
3 | type: docs
4 | weight: 1
5 | description: >
6 | This page lists all the prebuilt tools available.
7 | ---
8 |
9 | Prebuilt tools are reusable, pre-packaged toolsets that are designed to extend
10 | the capabilities of agents. These tools are built to be generic and adaptable,
11 | allowing developers to interact with and take action on databases.
12 |
13 | See guides, [Connect from your IDE](../how-to/connect-ide/_index.md), for
14 | details on how to connect your AI tools (IDEs) to databases via Toolbox and MCP.
15 |
16 | ## AlloyDB Postgres
17 |
18 | * `--prebuilt` value: `alloydb-postgres`
19 | * **Environment Variables:**
20 | * `ALLOYDB_POSTGRES_PROJECT`: The GCP project ID.
21 | * `ALLOYDB_POSTGRES_REGION`: The region of your AlloyDB instance.
22 | * `ALLOYDB_POSTGRES_CLUSTER`: The ID of your AlloyDB cluster.
23 | * `ALLOYDB_POSTGRES_INSTANCE`: The ID of your AlloyDB instance.
24 | * `ALLOYDB_POSTGRES_DATABASE`: The name of the database to connect to.
25 | * `ALLOYDB_POSTGRES_USER`: (Optional) The database username. Defaults to
26 | IAM authentication if unspecified.
27 | * `ALLOYDB_POSTGRES_PASSWORD`: (Optional) The password for the database
28 | user. Defaults to IAM authentication if unspecified.
29 | * `ALLOYDB_POSTGRES_IP_TYPE`: (Optional) The IP type i.e. "Public" or
30 | "Private" (Default: Public).
31 | * **Permissions:**
32 | * **AlloyDB Client** (`roles/alloydb.client`) to connect to the instance.
33 | * Database-level permissions (e.g., `SELECT`, `INSERT`) are required to
34 | execute queries.
35 | * **Tools:**
36 | * `execute_sql`: Executes a SQL query.
37 | * `list_tables`: Lists tables in the database.
38 | * `list_autovacuum_configurations`: Lists autovacuum configurations in the
39 | database.
40 | * `list_memory_configurations`: Lists memory-related configurations in the
41 | database.
42 | * `list_top_bloated_tables`: List top bloated tables in the database.
43 | * `list_replication_slots`: Lists replication slots in the database.
44 | * `list_invalid_indexes`: Lists invalid indexes in the database.
45 | * `get_query_plan`: Generate the execution plan of a statement.
46 | * `list_views`: Lists views in the database from pg_views with a default
47 | limit of 50 rows. Returns schemaname, viewname and the ownername.
48 | * `list_schemas`: Lists schemas in the database.
49 |
50 | ## AlloyDB Postgres Admin
51 |
52 | * `--prebuilt` value: `alloydb-postgres-admin`
53 | * **Permissions:**
54 | * **AlloyDB Viewer** (`roles/alloydb.viewer`) is required for `list` and
55 | `get` tools.
56 | * **AlloyDB Admin** (`roles/alloydb.admin`) is required for `create` tools.
57 | * **Tools:**
58 | * `create_cluster`: Creates a new AlloyDB cluster.
59 | * `list_clusters`: Lists all AlloyDB clusters in a project.
60 | * `get_cluster`: Gets information about a specified AlloyDB cluster.
61 | * `create_instance`: Creates a new AlloyDB instance within a cluster.
62 | * `list_instances`: Lists all instances within an AlloyDB cluster.
63 | * `get_instance`: Gets information about a specified AlloyDB instance.
64 | * `create_user`: Creates a new database user in an AlloyDB cluster.
65 | * `list_users`: Lists all database users within an AlloyDB cluster.
66 | * `get_user`: Gets information about a specified database user in an
67 | AlloyDB cluster.
68 | * `wait_for_operation`: Polls the operations API to track the status of
69 | long-running operations.
70 |
71 | ## AlloyDB Postgres Observability
72 |
73 | * `--prebuilt` value: `alloydb-postgres-observability`
74 | * **Permissions:**
75 | * **Monitoring Viewer** (`roles/monitoring.viewer`) is required on the
76 | project to view monitoring data.
77 | * **Tools:**
78 | * `get_system_metrics`: Fetches system level cloud monitoring data
79 | (timeseries metrics) for an AlloyDB instance using a PromQL query.
80 | * `get_query_metrics`: Fetches query level cloud monitoring data
81 | (timeseries metrics) for queries running in an AlloyDB instance using a
82 | PromQL query.
83 |
84 | ## BigQuery
85 |
86 | * `--prebuilt` value: `bigquery`
87 | * **Environment Variables:**
88 | * `BIGQUERY_PROJECT`: The GCP project ID.
89 | * `BIGQUERY_LOCATION`: (Optional) The dataset location.
90 | * `BIGQUERY_USE_CLIENT_OAUTH`: (Optional) If `true`, forwards the client's
91 | OAuth access token for authentication. Defaults to `false`.
92 | * **Permissions:**
93 | * **BigQuery User** (`roles/bigquery.user`) to execute queries and view
94 | metadata.
95 | * **BigQuery Metadata Viewer** (`roles/bigquery.metadataViewer`) to view
96 | all datasets.
97 | * **BigQuery Data Editor** (`roles/bigquery.dataEditor`) to create or
98 | modify datasets and tables.
99 | * **Gemini for Google Cloud** (`roles/cloudaicompanion.user`) to use the
100 | conversational analytics API.
101 | * **Tools:**
102 | * `analyze_contribution`: Use this tool to perform contribution analysis,
103 | also called key driver analysis.
104 | * `ask_data_insights`: Use this tool to perform data analysis, get
105 | insights, or answer complex questions about the contents of specific
106 | BigQuery tables. For more information on required roles, API setup, and
107 | IAM configuration, see the setup and authentication section of the
108 | [Conversational Analytics API
109 | documentation](https://cloud.google.com/gemini/docs/conversational-analytics-api/overview).
110 | * `execute_sql`: Executes a SQL statement.
111 | * `forecast`: Use this tool to forecast time series data.
112 | * `get_dataset_info`: Gets dataset metadata.
113 | * `get_table_info`: Gets table metadata.
114 | * `list_dataset_ids`: Lists datasets.
115 | * `list_table_ids`: Lists tables.
116 | * `search_catalog`: Search for entries based on the provided query.
117 |
118 | ## Cloud SQL for MySQL
119 |
120 | * `--prebuilt` value: `cloud-sql-mysql`
121 | * **Environment Variables:**
122 | * `CLOUD_SQL_MYSQL_PROJECT`: The GCP project ID.
123 | * `CLOUD_SQL_MYSQL_REGION`: The region of your Cloud SQL instance.
124 | * `CLOUD_SQL_MYSQL_INSTANCE`: The ID of your Cloud SQL instance.
125 | * `CLOUD_SQL_MYSQL_DATABASE`: The name of the database to connect to.
126 | * `CLOUD_SQL_MYSQL_USER`: The database username.
127 | * `CLOUD_SQL_MYSQL_PASSWORD`: The password for the database user.
128 | * `CLOUD_SQL_MYSQL_IP_TYPE`: The IP type i.e. "Public
129 | or "Private" (Default: Public).
130 | * **Permissions:**
131 | * **Cloud SQL Client** (`roles/cloudsql.client`) to connect to the
132 | instance.
133 | * Database-level permissions (e.g., `SELECT`, `INSERT`) are required to
134 | execute queries.
135 | * **Tools:**
136 | * `execute_sql`: Executes a SQL query.
137 | * `list_tables`: Lists tables in the database.
138 | * `get_query_plan`: Provides information about how MySQL executes a SQL
139 | statement.
140 | * `list_active_queries`: Lists ongoing queries.
141 | * `list_tables_missing_unique_indexes`: Looks for tables that do not have
142 | primary or unique key contraint.
143 | * `list_table_fragmentation`: Displays table fragmentation in MySQL.
144 |
145 | ## Cloud SQL for MySQL Observability
146 |
147 | * `--prebuilt` value: `cloud-sql-mysql-observability`
148 | * **Permissions:**
149 | * **Monitoring Viewer** (`roles/monitoring.viewer`) is required on the
150 | project to view monitoring data.
151 | * **Tools:**
152 | * `get_system_metrics`: Fetches system level cloud monitoring data
153 | (timeseries metrics) for a MySQL instance using a PromQL query.
154 | * `get_query_metrics`: Fetches query level cloud monitoring data
155 | (timeseries metrics) for queries running in a MySQL instance using a
156 | PromQL query.
157 |
158 | ## Cloud SQL for MySQL Admin
159 |
160 | * `--prebuilt` value: `cloud-sql-mysql-admin`
161 | * **Permissions:**
162 | * **Cloud SQL Viewer** (`roles/cloudsql.viewer`): Provides read-only
163 | access to resources.
164 | * `get_instance`
165 | * `list_instances`
166 | * `list_databases`
167 | * `wait_for_operation`
168 | * **Cloud SQL Editor** (`roles/cloudsql.editor`): Provides permissions to
169 | manage existing resources.
170 | * All `viewer` tools
171 | * `create_database`
172 | * **Cloud SQL Admin** (`roles/cloudsql.admin`): Provides full control over
173 | all resources.
174 | * All `editor` and `viewer` tools
175 | * `create_instance`
176 | * `create_user`
177 | * **Tools:**
178 | * `create_instance`: Creates a new Cloud SQL for MySQL instance.
179 | * `get_instance`: Gets information about a Cloud SQL instance.
180 | * `list_instances`: Lists Cloud SQL instances in a project.
181 | * `create_database`: Creates a new database in a Cloud SQL instance.
182 | * `list_databases`: Lists all databases for a Cloud SQL instance.
183 | * `create_user`: Creates a new user in a Cloud SQL instance.
184 | * `wait_for_operation`: Waits for a Cloud SQL operation to complete.
185 |
186 | ## Cloud SQL for PostgreSQL
187 |
188 | * `--prebuilt` value: `cloud-sql-postgres`
189 | * **Environment Variables:**
190 | * `CLOUD_SQL_POSTGRES_PROJECT`: The GCP project ID.
191 | * `CLOUD_SQL_POSTGRES_REGION`: The region of your Cloud SQL instance.
192 | * `CLOUD_SQL_POSTGRES_INSTANCE`: The ID of your Cloud SQL instance.
193 | * `CLOUD_SQL_POSTGRES_DATABASE`: The name of the database to connect to.
194 | * `CLOUD_SQL_POSTGRES_USER`: (Optional) The database username. Defaults to
195 | IAM authentication if unspecified.
196 | * `CLOUD_SQL_POSTGRES_PASSWORD`: (Optional) The password for the database
197 | user. Defaults to IAM authentication if unspecified.
198 | * `CLOUD_SQL_POSTGRES_IP_TYPE`: (Optional) The IP type i.e. "Public" or
199 | "Private" (Default: Public).
200 | * **Permissions:**
201 | * **Cloud SQL Client** (`roles/cloudsql.client`) to connect to the
202 | instance.
203 | * Database-level permissions (e.g., `SELECT`, `INSERT`) are required to
204 | execute queries.
205 | * **Tools:**
206 | * `execute_sql`: Executes a SQL query.
207 | * `list_tables`: Lists tables in the database.
208 | * `list_autovacuum_configurations`: Lists autovacuum configurations in the
209 | database.
210 | * `list_memory_configurations`: Lists memory-related configurations in the
211 | database.
212 | * `list_top_bloated_tables`: List top bloated tables in the database.
213 | * `list_replication_slots`: Lists replication slots in the database.
214 | * `list_invalid_indexes`: Lists invalid indexes in the database.
215 | * `get_query_plan`: Generate the execution plan of a statement.
216 | * `list_views`: Lists views in the database from pg_views with a default
217 | limit of 50 rows. Returns schemaname, viewname and the ownername.
218 | * `list_schemas`: Lists schemas in the database.
219 |
220 | ## Cloud SQL for PostgreSQL Observability
221 |
222 | * `--prebuilt` value: `cloud-sql-postgres-observability`
223 | * **Permissions:**
224 | * **Monitoring Viewer** (`roles/monitoring.viewer`) is required on the
225 | project to view monitoring data.
226 | * **Tools:**
227 | * `get_system_metrics`: Fetches system level cloud monitoring data
228 | (timeseries metrics) for a Postgres instance using a PromQL query.
229 | * `get_query_metrics`: Fetches query level cloud monitoring data
230 | (timeseries metrics) for queries running in Postgres instance using a
231 | PromQL query.
232 |
233 | ## Cloud SQL for PostgreSQL Admin
234 |
235 | * `--prebuilt` value: `cloud-sql-postgres-admin`
236 | * **Permissions:**
237 | * **Cloud SQL Viewer** (`roles/cloudsql.viewer`): Provides read-only
238 | access to resources.
239 | * `get_instance`
240 | * `list_instances`
241 | * `list_databases`
242 | * `wait_for_operation`
243 | * **Cloud SQL Editor** (`roles/cloudsql.editor`): Provides permissions to
244 | manage existing resources.
245 | * All `viewer` tools
246 | * `create_database`
247 | * **Cloud SQL Admin** (`roles/cloudsql.admin`): Provides full control over
248 | all resources.
249 | * All `editor` and `viewer` tools
250 | * `create_instance`
251 | * `create_user`
252 | * **Tools:**
253 | * `create_instance`: Creates a new Cloud SQL for PostgreSQL instance.
254 | * `get_instance`: Gets information about a Cloud SQL instance.
255 | * `list_instances`: Lists Cloud SQL instances in a project.
256 | * `create_database`: Creates a new database in a Cloud SQL instance.
257 | * `list_databases`: Lists all databases for a Cloud SQL instance.
258 | * `create_user`: Creates a new user in a Cloud SQL instance.
259 | * `wait_for_operation`: Waits for a Cloud SQL operation to complete.
260 |
261 | ## Cloud SQL for SQL Server
262 |
263 | * `--prebuilt` value: `cloud-sql-mssql`
264 | * **Environment Variables:**
265 | * `CLOUD_SQL_MSSQL_PROJECT`: The GCP project ID.
266 | * `CLOUD_SQL_MSSQL_REGION`: The region of your Cloud SQL instance.
267 | * `CLOUD_SQL_MSSQL_INSTANCE`: The ID of your Cloud SQL instance.
268 | * `CLOUD_SQL_MSSQL_DATABASE`: The name of the database to connect to.
269 | * `CLOUD_SQL_MSSQL_USER`: The database username.
270 | * `CLOUD_SQL_MSSQL_PASSWORD`: The password for the database user.
271 | * `CLOUD_SQL_MSSQL_IP_TYPE`: (Optional) The IP type i.e. "Public" or
272 | "Private" (Default: Public).
273 | * **Permissions:**
274 | * **Cloud SQL Client** (`roles/cloudsql.client`) to connect to the
275 | instance.
276 | * Database-level permissions (e.g., `SELECT`, `INSERT`) are required to
277 | execute queries.
278 | * **Tools:**
279 | * `execute_sql`: Executes a SQL query.
280 | * `list_tables`: Lists tables in the database.
281 |
282 | ## Cloud SQL for SQL Server Observability
283 |
284 | * `--prebuilt` value: `cloud-sql-mssql-observability`
285 | * **Permissions:**
286 | * **Monitoring Viewer** (`roles/monitoring.viewer`) is required on the
287 | project to view monitoring data.
288 | * **Tools:**
289 | * `get_system_metrics`: Fetches system level cloud monitoring data
290 | (timeseries metrics) for a SQL Server instance using a PromQL query.
291 |
292 | ## Cloud SQL for SQL Server Admin
293 |
294 | * `--prebuilt` value: `cloud-sql-mssql-admin`
295 | * **Permissions:**
296 | * **Cloud SQL Viewer** (`roles/cloudsql.viewer`): Provides read-only
297 | access to resources.
298 | * `get_instance`
299 | * `list_instances`
300 | * `list_databases`
301 | * `wait_for_operation`
302 | * **Cloud SQL Editor** (`roles/cloudsql.editor`): Provides permissions to
303 | manage existing resources.
304 | * All `viewer` tools
305 | * `create_database`
306 | * **Cloud SQL Admin** (`roles/cloudsql.admin`): Provides full control over
307 | all resources.
308 | * All `editor` and `viewer` tools
309 | * `create_instance`
310 | * `create_user`
311 | * **Tools:**
312 | * `create_instance`: Creates a new Cloud SQL for SQL Server instance.
313 | * `get_instance`: Gets information about a Cloud SQL instance.
314 | * `list_instances`: Lists Cloud SQL instances in a project.
315 | * `create_database`: Creates a new database in a Cloud SQL instance.
316 | * `list_databases`: Lists all databases for a Cloud SQL instance.
317 | * `create_user`: Creates a new user in a Cloud SQL instance.
318 | * `wait_for_operation`: Waits for a Cloud SQL operation to complete.
319 |
320 | ## Dataplex
321 |
322 | * `--prebuilt` value: `dataplex`
323 | * **Environment Variables:**
324 | * `DATAPLEX_PROJECT`: The GCP project ID.
325 | * **Permissions:**
326 | * **Dataplex Reader** (`roles/dataplex.viewer`) to search and look up
327 | entries.
328 | * **Dataplex Editor** (`roles/dataplex.editor`) to modify entries.
329 | * **Tools:**
330 | * `dataplex_search_entries`: Searches for entries in Dataplex Catalog.
331 | * `dataplex_lookup_entry`: Retrieves a specific entry from Dataplex
332 | Catalog.
333 | * `dataplex_search_aspect_types`: Finds aspect types relevant to the
334 | query.
335 |
336 | ## Firestore
337 |
338 | * `--prebuilt` value: `firestore`
339 | * **Environment Variables:**
340 | * `FIRESTORE_PROJECT`: The GCP project ID.
341 | * `FIRESTORE_DATABASE`: (Optional) The Firestore database ID. Defaults to
342 | "(default)".
343 | * **Permissions:**
344 | * **Cloud Datastore User** (`roles/datastore.user`) to get documents, list
345 | collections, and query collections.
346 | * **Firebase Rules Viewer** (`roles/firebaserules.viewer`) to get and
347 | validate Firestore rules.
348 | * **Tools:**
349 | * `get_documents`: Gets multiple documents from Firestore by their paths.
350 | * `add_documents`: Adds a new document to a Firestore collection.
351 | * `update_document`: Updates an existing document in Firestore.
352 | * `list_collections`: Lists Firestore collections for a given parent path.
353 | * `delete_documents`: Deletes multiple documents from Firestore.
354 | * `query_collection`: Retrieves one or more Firestore documents from a
355 | collection.
356 | * `get_rules`: Retrieves the active Firestore security rules.
357 | * `validate_rules`: Checks the provided Firestore Rules source for syntax
358 | and validation errors.
359 |
360 | ## Looker
361 |
362 | * `--prebuilt` value: `looker`
363 | * **Environment Variables:**
364 | * `LOOKER_BASE_URL`: The URL of your Looker instance.
365 | * `LOOKER_CLIENT_ID`: The client ID for the Looker API.
366 | * `LOOKER_CLIENT_SECRET`: The client secret for the Looker API.
367 | * `LOOKER_VERIFY_SSL`: Whether to verify SSL certificates.
368 | * `LOOKER_USE_CLIENT_OAUTH`: Whether to use OAuth for authentication.
369 | * `LOOKER_SHOW_HIDDEN_MODELS`: Whether to show hidden models.
370 | * `LOOKER_SHOW_HIDDEN_EXPLORES`: Whether to show hidden explores.
371 | * `LOOKER_SHOW_HIDDEN_FIELDS`: Whether to show hidden fields.
372 | * **Permissions:**
373 | * A Looker account with permissions to access the desired models,
374 | explores, and data is required.
375 | * **Tools:**
376 | * `get_models`: Retrieves the list of LookML models.
377 | * `get_explores`: Retrieves the list of explores in a model.
378 | * `get_dimensions`: Retrieves the list of dimensions in an explore.
379 | * `get_measures`: Retrieves the list of measures in an explore.
380 | * `get_filters`: Retrieves the list of filters in an explore.
381 | * `get_parameters`: Retrieves the list of parameters in an explore.
382 | * `query`: Runs a query against the LookML model.
383 | * `query_sql`: Generates the SQL for a query.
384 | * `query_url`: Generates a URL for a query in Looker.
385 | * `get_looks`: Searches for saved looks.
386 | * `run_look`: Runs the query associated with a look.
387 | * `make_look`: Creates a new look.
388 | * `get_dashboards`: Searches for saved dashboards.
389 | * `make_dashboard`: Creates a new dashboard.
390 | * `add_dashboard_element`: Adds a tile to a dashboard.
391 | * `health_pulse`: Test the health of a Looker instance.
392 | * `health_analyze`: Analyze the LookML usage of a Looker instance.
393 | * `health_vacuum`: Suggest LookML elements that can be removed.
394 | * `dev_mode`: Activate developer mode.
395 | * `get_projects`: Get the LookML projects in a Looker instance.
396 | * `get_project_files`: List the project files in a project.
397 | * `get_project_file`: Get the content of a LookML file.
398 | * `create_project_file`: Create a new LookML file.
399 | * `update_project_file`: Update an existing LookML file.
400 | * `delete_project_file`: Delete a LookML file.
401 | * `get_connections`: Get the available connections in a Looker instance.
402 | * `get_connection_schemas`: Get the available schemas in a connection.
403 | * `get_connection_databases`: Get the available databases in a connection.
404 | * `get_connection_tables`: Get the available tables in a connection.
405 | * `get_connection_table_columns`: Get the available columns for a table.
406 |
407 | ## Looker Conversational Analytics
408 |
409 | * `--prebuilt` value: `looker-conversational-analytics`
410 | * **Environment Variables:**
411 | * `LOOKER_BASE_URL`: The URL of your Looker instance.
412 | * `LOOKER_CLIENT_ID`: The client ID for the Looker API.
413 | * `LOOKER_CLIENT_SECRET`: The client secret for the Looker API.
414 | * `LOOKER_VERIFY_SSL`: Whether to verify SSL certificates.
415 | * `LOOKER_USE_CLIENT_OAUTH`: Whether to use OAuth for authentication.
416 | * `LOOKER_PROJECT`: The GCP Project to use for Conversational Analytics.
417 | * `LOOKER_LOCATION`: The GCP Location to use for Conversational Analytics.
418 | * **Permissions:**
419 | * A Looker account with permissions to access the desired models,
420 | explores, and data is required.
421 | * **Looker Instance User** (`roles/looker.instanceUser`): IAM role to
422 | access Looker.
423 | * **Gemini for Google Cloud User** (`roles/cloudaicompanion.user`): IAM
424 | role to access Conversational Analytics.
425 | * **Gemini Data Analytics Stateless Chat User (Beta)**
426 | (`roles/geminidataanalytics.dataAgentStatelessUser`): IAM role to
427 | access Conversational Analytics.
428 | * **Tools:**
429 | * `ask_data_insights`: Ask a question of the data.
430 | * `get_models`: Retrieves the list of LookML models.
431 | * `get_explores`: Retrieves the list of explores in a model.
432 |
433 | ## Microsoft SQL Server
434 |
435 | * `--prebuilt` value: `mssql`
436 | * **Environment Variables:**
437 | * `MSSQL_HOST`: The hostname or IP address of the SQL Server instance.
438 | * `MSSQL_PORT`: The port number for the SQL Server instance.
439 | * `MSSQL_DATABASE`: The name of the database to connect to.
440 | * `MSSQL_USER`: The database username.
441 | * `MSSQL_PASSWORD`: The password for the database user.
442 | * **Permissions:**
443 | * Database-level permissions (e.g., `SELECT`, `INSERT`) are required to
444 | execute queries.
445 | * **Tools:**
446 | * `execute_sql`: Executes a SQL query.
447 | * `list_tables`: Lists tables in the database.
448 |
449 | ## MySQL
450 |
451 | * `--prebuilt` value: `mysql`
452 | * **Environment Variables:**
453 | * `MYSQL_HOST`: The hostname or IP address of the MySQL server.
454 | * `MYSQL_PORT`: The port number for the MySQL server.
455 | * `MYSQL_DATABASE`: The name of the database to connect to.
456 | * `MYSQL_USER`: The database username.
457 | * `MYSQL_PASSWORD`: The password for the database user.
458 | * **Permissions:**
459 | * Database-level permissions (e.g., `SELECT`, `INSERT`) are required to
460 | execute queries.
461 | * **Tools:**
462 | * `execute_sql`: Executes a SQL query.
463 | * `list_tables`: Lists tables in the database.
464 | * `get_query_plan`: Provides information about how MySQL executes a SQL
465 | statement.
466 | * `list_active_queries`: Lists ongoing queries.
467 | * `list_tables_missing_unique_indexes`: Looks for tables that do not have
468 | primary or unique key contraint.
469 | * `list_table_fragmentation`: Displays table fragmentation in MySQL.
470 |
471 | ## OceanBase
472 |
473 | * `--prebuilt` value: `oceanbase`
474 | * **Environment Variables:**
475 | * `OCEANBASE_HOST`: The hostname or IP address of the OceanBase server.
476 | * `OCEANBASE_PORT`: The port number for the OceanBase server.
477 | * `OCEANBASE_DATABASE`: The name of the database to connect to.
478 | * `OCEANBASE_USER`: The database username.
479 | * `OCEANBASE_PASSWORD`: The password for the database user.
480 | * **Permissions:**
481 | * Database-level permissions (e.g., `SELECT`, `INSERT`) are required to
482 | execute queries.
483 | * **Tools:**
484 | * `execute_sql`: Executes a SQL query.
485 | * `list_tables`: Lists tables in the database.
486 |
487 | ## PostgreSQL
488 |
489 | * `--prebuilt` value: `postgres`
490 | * **Environment Variables:**
491 | * `POSTGRES_HOST`: The hostname or IP address of the PostgreSQL server.
492 | * `POSTGRES_PORT`: The port number for the PostgreSQL server.
493 | * `POSTGRES_DATABASE`: The name of the database to connect to.
494 | * `POSTGRES_USER`: The database username.
495 | * `POSTGRES_PASSWORD`: The password for the database user.
496 | * `POSTGRES_QUERY_PARAMS`: (Optional) Raw query to be added to the db
497 | connection string.
498 | * **Permissions:**
499 | * Database-level permissions (e.g., `SELECT`, `INSERT`) are required to
500 | execute queries.
501 | * **Tools:**
502 | * `execute_sql`: Executes a SQL query.
503 | * `list_tables`: Lists tables in the database.
504 | * `list_autovacuum_configurations`: Lists autovacuum configurations in the
505 | database.
506 | * `list_memory_configurations`: Lists memory-related configurations in the
507 | database.
508 | * `list_top_bloated_tables`: List top bloated tables in the database.
509 | * `list_replication_slots`: Lists replication slots in the database.
510 | * `list_invalid_indexes`: Lists invalid indexes in the database.
511 | * `get_query_plan`: Generate the execution plan of a statement.
512 | * `list_views`: Lists views in the database from pg_views with a default
513 | limit of 50 rows. Returns schemaname, viewname and the ownername.
514 | * `list_schemas`: Lists schemas in the database.
515 |
516 | ## Google Cloud Serverless for Apache Spark
517 |
518 | * `--prebuilt` value: `serverless-spark`
519 | * **Environment Variables:**
520 | * `SERVERLESS_SPARK_PROJECT`: The GCP project ID
521 | * `SERVERLESS_SPARK_LOCATION`: The GCP Location.
522 | * **Permissions:**
523 | * **Dataproc Serverless Viewer** (`roles/dataproc.serverlessViewer`) to
524 | view serverless batches.
525 | * **Dataproc Serverless Editor** (`roles/dataproc.serverlessEditor`) to
526 | view serverless batches.
527 | * **Tools:**
528 | * `list_batches`: Lists Spark batches.
529 |
530 | ## Spanner (GoogleSQL dialect)
531 |
532 | * `--prebuilt` value: `spanner`
533 | * **Environment Variables:**
534 | * `SPANNER_PROJECT`: The GCP project ID.
535 | * `SPANNER_INSTANCE`: The Spanner instance ID.
536 | * `SPANNER_DATABASE`: The Spanner database ID.
537 | * **Permissions:**
538 | * **Cloud Spanner Database Reader** (`roles/spanner.databaseReader`) to
539 | execute DQL queries and list tables.
540 | * **Cloud Spanner Database User** (`roles/spanner.databaseUser`) to
541 | execute DML queries.
542 | * **Tools:**
543 | * `execute_sql`: Executes a DML SQL query.
544 | * `execute_sql_dql`: Executes a DQL SQL query.
545 | * `list_tables`: Lists tables in the database.
546 |
547 | ## Spanner (PostgreSQL dialect)
548 |
549 | * `--prebuilt` value: `spanner-postgres`
550 | * **Environment Variables:**
551 | * `SPANNER_PROJECT`: The GCP project ID.
552 | * `SPANNER_INSTANCE`: The Spanner instance ID.
553 | * `SPANNER_DATABASE`: The Spanner database ID.
554 | * **Permissions:**
555 | * **Cloud Spanner Database Reader** (`roles/spanner.databaseReader`) to
556 | execute DQL queries and list tables.
557 | * **Cloud Spanner Database User** (`roles/spanner.databaseUser`) to
558 | execute DML queries.
559 | * **Tools:**
560 | * `execute_sql`: Executes a DML SQL query using the PostgreSQL interface
561 | for Spanner.
562 | * `execute_sql_dql`: Executes a DQL SQL query using the PostgreSQL
563 | interface for Spanner.
564 | * `list_tables`: Lists tables in the database.
565 |
566 | ## SQLite
567 |
568 | * `--prebuilt` value: `sqlite`
569 | * **Environment Variables:**
570 | * `SQLITE_DATABASE`: The path to the SQLite database file (e.g.,
571 | `./sample.db`).
572 | * **Permissions:**
573 | * File system read/write permissions for the specified database file.
574 | * **Tools:**
575 | * `execute_sql`: Executes a SQL query.
576 | * `list_tables`: Lists tables in the database.
577 |
578 | ## Neo4j
579 |
580 | * `--prebuilt` value: `neo4j`
581 | * **Environment Variables:**
582 | * `NEO4J_URI`: The URI of the Neo4j instance (e.g.,
583 | `bolt://localhost:7687`).
584 | * `NEO4J_DATABASE`: The name of the Neo4j database to connect to.
585 | * `NEO4J_USERNAME`: The username for the Neo4j instance.
586 | * `NEO4J_PASSWORD`: The password for the Neo4j instance.
587 | * **Permissions:**
588 | * **Database-level permissions** are required to execute Cypher queries.
589 | * **Tools:**
590 | * `execute_cypher`: Executes a Cypher query.
591 | * `get_schema`: Retrieves the schema of the Neo4j database.
592 |
```
--------------------------------------------------------------------------------
/tests/spanner/spanner_integration_test.go:
--------------------------------------------------------------------------------
```go
1 | // Copyright 2024 Google 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.
14 |
15 | package spanner
16 |
17 | import (
18 | "bytes"
19 | "context"
20 | "encoding/json"
21 | "fmt"
22 | "io"
23 | "net/http"
24 | "os"
25 | "regexp"
26 | "strings"
27 | "testing"
28 | "time"
29 |
30 | "cloud.google.com/go/spanner"
31 | database "cloud.google.com/go/spanner/admin/database/apiv1"
32 | "cloud.google.com/go/spanner/admin/database/apiv1/databasepb"
33 | "github.com/google/uuid"
34 | "github.com/googleapis/genai-toolbox/internal/testutils"
35 | "github.com/googleapis/genai-toolbox/internal/tools"
36 | "github.com/googleapis/genai-toolbox/tests"
37 | )
38 |
39 | var (
40 | SpannerSourceKind = "spanner"
41 | SpannerToolKind = "spanner-sql"
42 | SpannerProject = os.Getenv("SPANNER_PROJECT")
43 | SpannerDatabase = os.Getenv("SPANNER_DATABASE")
44 | SpannerInstance = os.Getenv("SPANNER_INSTANCE")
45 | )
46 |
47 | func getSpannerVars(t *testing.T) map[string]any {
48 | switch "" {
49 | case SpannerProject:
50 | t.Fatal("'SPANNER_PROJECT' not set")
51 | case SpannerDatabase:
52 | t.Fatal("'SPANNER_DATABASE' not set")
53 | case SpannerInstance:
54 | t.Fatal("'SPANNER_INSTANCE' not set")
55 | }
56 |
57 | return map[string]any{
58 | "kind": SpannerSourceKind,
59 | "project": SpannerProject,
60 | "instance": SpannerInstance,
61 | "database": SpannerDatabase,
62 | }
63 | }
64 |
65 | func initSpannerClients(ctx context.Context, project, instance, dbname string) (*spanner.Client, *database.DatabaseAdminClient, error) {
66 | // Configure the connection to the database
67 | db := fmt.Sprintf("projects/%s/instances/%s/databases/%s", project, instance, dbname)
68 |
69 | // Configure session pool to automatically clean inactive transactions
70 | sessionPoolConfig := spanner.SessionPoolConfig{
71 | TrackSessionHandles: true,
72 | InactiveTransactionRemovalOptions: spanner.InactiveTransactionRemovalOptions{
73 | ActionOnInactiveTransaction: spanner.WarnAndClose,
74 | },
75 | }
76 |
77 | // Create Spanner client (for queries)
78 | dataClient, err := spanner.NewClientWithConfig(context.Background(), db, spanner.ClientConfig{SessionPoolConfig: sessionPoolConfig})
79 | if err != nil {
80 | return nil, nil, fmt.Errorf("unable to create new Spanner client: %w", err)
81 | }
82 |
83 | // Create Spanner admin client (for creating databases)
84 | adminClient, err := database.NewDatabaseAdminClient(ctx)
85 | if err != nil {
86 | return nil, nil, fmt.Errorf("unable to create new Spanner admin client: %w", err)
87 | }
88 |
89 | return dataClient, adminClient, nil
90 | }
91 |
92 | func TestSpannerToolEndpoints(t *testing.T) {
93 | sourceConfig := getSpannerVars(t)
94 | ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
95 | defer cancel()
96 |
97 | var args []string
98 |
99 | // Create Spanner client
100 | dataClient, adminClient, err := initSpannerClients(ctx, SpannerProject, SpannerInstance, SpannerDatabase)
101 | if err != nil {
102 | t.Fatalf("unable to create Spanner client: %s", err)
103 | }
104 |
105 | // create table name with UUID
106 | tableNameParam := "param_table_" + strings.ReplaceAll(uuid.New().String(), "-", "")
107 | tableNameAuth := "auth_table_" + strings.ReplaceAll(uuid.New().String(), "-", "")
108 | tableNameTemplateParam := "template_param_table_" + strings.ReplaceAll(uuid.New().String(), "-", "")
109 |
110 | // set up data for param tool
111 | createParamTableStmt, insertParamTableStmt, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, paramTestParams := getSpannerParamToolInfo(tableNameParam)
112 | dbString := fmt.Sprintf(
113 | "projects/%s/instances/%s/databases/%s",
114 | SpannerProject,
115 | SpannerInstance,
116 | SpannerDatabase,
117 | )
118 | teardownTable1 := setupSpannerTable(t, ctx, adminClient, dataClient, createParamTableStmt, insertParamTableStmt, tableNameParam, dbString, paramTestParams)
119 | defer teardownTable1(t)
120 |
121 | // set up data for auth tool
122 | createAuthTableStmt, insertAuthTableStmt, authToolStmt, authTestParams := getSpannerAuthToolInfo(tableNameAuth)
123 | teardownTable2 := setupSpannerTable(t, ctx, adminClient, dataClient, createAuthTableStmt, insertAuthTableStmt, tableNameAuth, dbString, authTestParams)
124 | defer teardownTable2(t)
125 |
126 | // set up data for template param tool
127 | createStatementTmpl := fmt.Sprintf("CREATE TABLE %s (id INT64, name STRING(MAX), age INT64) PRIMARY KEY (id)", tableNameTemplateParam)
128 | teardownTableTmpl := setupSpannerTable(t, ctx, adminClient, dataClient, createStatementTmpl, "", tableNameTemplateParam, dbString, nil)
129 | defer teardownTableTmpl(t)
130 |
131 | // Write config into a file and pass it to command
132 | toolsFile := tests.GetToolsConfig(sourceConfig, SpannerToolKind, paramToolStmt, idParamToolStmt, nameParamToolStmt, arrayToolStmt, authToolStmt)
133 | toolsFile = addSpannerExecuteSqlConfig(t, toolsFile)
134 | toolsFile = addSpannerReadOnlyConfig(t, toolsFile)
135 | toolsFile = addTemplateParamConfig(t, toolsFile)
136 | toolsFile = addSpannerListTablesConfig(t, toolsFile)
137 |
138 | cmd, cleanup, err := tests.StartCmd(ctx, toolsFile, args...)
139 | if err != nil {
140 | t.Fatalf("command initialization returned an error: %s", err)
141 | }
142 | defer cleanup()
143 |
144 | waitCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
145 | defer cancel()
146 | out, err := testutils.WaitForString(waitCtx, regexp.MustCompile(`Server ready to serve`), cmd.Out)
147 | if err != nil {
148 | t.Logf("toolbox command logs: \n%s", out)
149 | t.Fatalf("toolbox didn't start successfully: %s", err)
150 | }
151 |
152 | // Get configs for tests
153 | select1Want := "[{\"\":\"1\"}]"
154 | invokeParamWant := "[{\"id\":\"1\",\"name\":\"Alice\"},{\"id\":\"3\",\"name\":\"Sid\"}]"
155 | accessSchemaWant := "[{\"schema_name\":\"INFORMATION_SCHEMA\"}]"
156 | toolInvokeMyToolById4Want := `[{"id":"4","name":null}]`
157 | mcpMyFailToolWant := `"jsonrpc":"2.0","id":"invoke-fail-tool","result":{"content":[{"type":"text","text":"unable to execute client: unable to parse row: spanner: code = \"InvalidArgument\", desc = \"Syntax error: Unexpected identifier \\\\\\\"SELEC\\\\\\\" [at 1:1]\\\\nSELEC 1;\\\\n^\"`
158 | mcpMyToolId3NameAliceWant := `{"jsonrpc":"2.0","id":"my-tool","result":{"content":[{"type":"text","text":"{\"id\":\"1\",\"name\":\"Alice\"}"},{"type":"text","text":"{\"id\":\"3\",\"name\":\"Sid\"}"}]}}`
159 | mcpSelect1Want := `{"jsonrpc":"2.0","id":"invoke my-auth-required-tool","result":{"content":[{"type":"text","text":"{\"\":\"1\"}"}]}}`
160 | tmplSelectAllWwant := "[{\"age\":\"21\",\"id\":\"1\",\"name\":\"Alex\"},{\"age\":\"100\",\"id\":\"2\",\"name\":\"Alice\"}]"
161 | tmplSelectId1Want := "[{\"age\":\"21\",\"id\":\"1\",\"name\":\"Alex\"}]"
162 |
163 | // Run tests
164 | tests.RunToolGetTest(t)
165 | tests.RunToolInvokeTest(t, select1Want,
166 | tests.WithMyToolId3NameAliceWant(invokeParamWant),
167 | tests.WithMyArrayToolWant(invokeParamWant),
168 | tests.WithMyToolById4Want(toolInvokeMyToolById4Want),
169 | )
170 | tests.RunMCPToolCallMethod(t, mcpMyFailToolWant, mcpSelect1Want, tests.WithMcpMyToolId3NameAliceWant(mcpMyToolId3NameAliceWant))
171 | tests.RunToolInvokeWithTemplateParameters(
172 | t, tableNameTemplateParam,
173 | tests.WithSelectAllWant(tmplSelectAllWwant),
174 | tests.WithTmplSelectId1Want(tmplSelectId1Want),
175 | tests.DisableDdlTest(),
176 | )
177 | runSpannerSchemaToolInvokeTest(t, accessSchemaWant)
178 | runSpannerExecuteSqlToolInvokeTest(t, select1Want, invokeParamWant, tableNameParam, tableNameAuth)
179 | runSpannerListTablesTest(t, tableNameParam, tableNameAuth, tableNameTemplateParam)
180 | }
181 |
182 | // getSpannerToolInfo returns statements and param for my-tool for spanner-sql kind
183 | func getSpannerParamToolInfo(tableName string) (string, string, string, string, string, string, map[string]any) {
184 | createStatement := fmt.Sprintf("CREATE TABLE %s (id INT64, name STRING(MAX)) PRIMARY KEY (id)", tableName)
185 | insertStatement := fmt.Sprintf("INSERT INTO %s (id, name) VALUES (1, @name1), (2, @name2), (3, @name3), (4, @name4)", tableName)
186 | toolStatement := fmt.Sprintf("SELECT * FROM %s WHERE id = @id OR name = @name", tableName)
187 | idToolStatement := fmt.Sprintf("SELECT * FROM %s WHERE id = @id", tableName)
188 | nameToolStatement := fmt.Sprintf("SELECT * FROM %s WHERE name = @name", tableName)
189 | arrayToolStatement := fmt.Sprintf("SELECT * FROM %s WHERE id IN UNNEST(@idArray) AND name IN UNNEST(@nameArray)", tableName)
190 | params := map[string]any{"name1": "Alice", "name2": "Jane", "name3": "Sid", "name4": nil}
191 | return createStatement, insertStatement, toolStatement, idToolStatement, nameToolStatement, arrayToolStatement, params
192 | }
193 |
194 | // getSpannerAuthToolInfo returns statements and param of my-auth-tool for spanner-sql kind
195 | func getSpannerAuthToolInfo(tableName string) (string, string, string, map[string]any) {
196 | createStatement := fmt.Sprintf("CREATE TABLE %s (id INT64, name STRING(MAX), email STRING(MAX)) PRIMARY KEY (id)", tableName)
197 | insertStatement := fmt.Sprintf("INSERT INTO %s (id, name, email) VALUES (1, @name1, @email1), (2, @name2, @email2)", tableName)
198 | toolStatement := fmt.Sprintf("SELECT name FROM %s WHERE email = @email", tableName)
199 | params := map[string]any{
200 | "name1": "Alice",
201 | "email1": tests.ServiceAccountEmail,
202 | "name2": "Jane",
203 | "email2": "[email protected]",
204 | }
205 | return createStatement, insertStatement, toolStatement, params
206 | }
207 |
208 | // setupSpannerTable creates and inserts data into a table of tool
209 | // compatible with spanner-sql tool
210 | func setupSpannerTable(t *testing.T, ctx context.Context, adminClient *database.DatabaseAdminClient, dataClient *spanner.Client, createStatement, insertStatement, tableName, dbString string, params map[string]any) func(*testing.T) {
211 |
212 | // Create table
213 | op, err := adminClient.UpdateDatabaseDdl(ctx, &databasepb.UpdateDatabaseDdlRequest{
214 | Database: dbString,
215 | Statements: []string{createStatement},
216 | })
217 | if err != nil {
218 | t.Fatalf("unable to start create table operation %s: %s", tableName, err)
219 | }
220 | err = op.Wait(ctx)
221 | if err != nil {
222 | t.Fatalf("unable to create test table %s: %s", tableName, err)
223 | }
224 |
225 | // Insert test data
226 | if insertStatement != "" {
227 | _, err = dataClient.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error {
228 | stmt := spanner.Statement{
229 | SQL: insertStatement,
230 | Params: params,
231 | }
232 | _, err := txn.Update(ctx, stmt)
233 | return err
234 | })
235 | if err != nil {
236 | t.Fatalf("unable to insert test data: %s", err)
237 | }
238 | }
239 |
240 | return func(t *testing.T) {
241 | // tear down test
242 | op, err = adminClient.UpdateDatabaseDdl(ctx, &databasepb.UpdateDatabaseDdlRequest{
243 | Database: dbString,
244 | Statements: []string{fmt.Sprintf("DROP TABLE %s", tableName)},
245 | })
246 | if err != nil {
247 | t.Errorf("unable to start drop %s operation: %s", tableName, err)
248 | return
249 | }
250 |
251 | opErr := op.Wait(ctx)
252 | if opErr != nil {
253 | t.Errorf("Teardown failed: %s", opErr)
254 | }
255 | }
256 | }
257 |
258 | // addSpannerExecuteSqlConfig gets the tools config for `spanner-execute-sql`
259 | func addSpannerExecuteSqlConfig(t *testing.T, config map[string]any) map[string]any {
260 | tools, ok := config["tools"].(map[string]any)
261 | if !ok {
262 | t.Fatalf("unable to get tools from config")
263 | }
264 | tools["my-exec-sql-tool-read-only"] = map[string]any{
265 | "kind": "spanner-execute-sql",
266 | "source": "my-instance",
267 | "description": "Tool to execute sql",
268 | "readOnly": true,
269 | }
270 | tools["my-exec-sql-tool"] = map[string]any{
271 | "kind": "spanner-execute-sql",
272 | "source": "my-instance",
273 | "description": "Tool to execute sql",
274 | }
275 | tools["my-auth-exec-sql-tool"] = map[string]any{
276 | "kind": "spanner-execute-sql",
277 | "source": "my-instance",
278 | "description": "Tool to execute sql",
279 | "authRequired": []string{
280 | "my-google-auth",
281 | },
282 | }
283 | config["tools"] = tools
284 | return config
285 | }
286 |
287 | func addSpannerReadOnlyConfig(t *testing.T, config map[string]any) map[string]any {
288 | tools, ok := config["tools"].(map[string]any)
289 | if !ok {
290 | t.Fatalf("unable to get tools from config")
291 | }
292 | tools["access-schema-read-only"] = map[string]any{
293 | "kind": "spanner-sql",
294 | "source": "my-instance",
295 | "description": "Tool to access information schema in read-only mode.",
296 | "statement": "SELECT schema_name FROM `INFORMATION_SCHEMA`.SCHEMATA WHERE schema_name='INFORMATION_SCHEMA';",
297 | "readOnly": true,
298 | }
299 | tools["access-schema"] = map[string]any{
300 | "kind": "spanner-sql",
301 | "source": "my-instance",
302 | "description": "Tool to access information schema.",
303 | "statement": "SELECT schema_name FROM `INFORMATION_SCHEMA`.SCHEMATA WHERE schema_name='INFORMATION_SCHEMA';",
304 | }
305 | config["tools"] = tools
306 | return config
307 | }
308 |
309 | // addSpannerListTablesConfig adds the spanner-list-tables tool configuration
310 | func addSpannerListTablesConfig(t *testing.T, config map[string]any) map[string]any {
311 | tools, ok := config["tools"].(map[string]any)
312 | if !ok {
313 | t.Fatalf("unable to get tools from config")
314 | }
315 |
316 | // Add spanner-list-tables tool
317 | tools["list-tables-tool"] = map[string]any{
318 | "kind": "spanner-list-tables",
319 | "source": "my-instance",
320 | "description": "Lists tables with their schema information",
321 | }
322 |
323 | config["tools"] = tools
324 | return config
325 | }
326 |
327 | func addTemplateParamConfig(t *testing.T, config map[string]any) map[string]any {
328 | toolsMap, ok := config["tools"].(map[string]any)
329 | if !ok {
330 | t.Fatalf("unable to get tools from config")
331 | }
332 | toolsMap["insert-table-templateParams-tool"] = map[string]any{
333 | "kind": "spanner-sql",
334 | "source": "my-instance",
335 | "description": "Insert tool with template parameters",
336 | "statement": "INSERT INTO {{.tableName}} ({{array .columns}}) VALUES ({{.values}})",
337 | "templateParameters": []tools.Parameter{
338 | tools.NewStringParameter("tableName", "some description"),
339 | tools.NewArrayParameter("columns", "The columns to insert into", tools.NewStringParameter("column", "A column name that will be returned from the query.")),
340 | tools.NewStringParameter("values", "The values to insert as a comma separated string"),
341 | },
342 | }
343 | toolsMap["select-templateParams-tool"] = map[string]any{
344 | "kind": "spanner-sql",
345 | "source": "my-instance",
346 | "description": "Create table tool with template parameters",
347 | "statement": "SELECT * FROM {{.tableName}}",
348 | "templateParameters": []tools.Parameter{
349 | tools.NewStringParameter("tableName", "some description"),
350 | },
351 | }
352 | toolsMap["select-templateParams-combined-tool"] = map[string]any{
353 | "kind": "spanner-sql",
354 | "source": "my-instance",
355 | "description": "Create table tool with template parameters",
356 | "statement": "SELECT * FROM {{.tableName}} WHERE id = @id",
357 | "parameters": []tools.Parameter{tools.NewIntParameter("id", "the id of the user")},
358 | "templateParameters": []tools.Parameter{
359 | tools.NewStringParameter("tableName", "some description"),
360 | },
361 | }
362 | toolsMap["select-fields-templateParams-tool"] = map[string]any{
363 | "kind": "spanner-sql",
364 | "source": "my-instance",
365 | "description": "Create table tool with template parameters",
366 | "statement": "SELECT {{array .fields}} FROM {{.tableName}}",
367 | "templateParameters": []tools.Parameter{
368 | tools.NewStringParameter("tableName", "some description"),
369 | tools.NewArrayParameter("fields", "The fields to select from", tools.NewStringParameter("field", "A field that will be returned from the query.")),
370 | },
371 | }
372 | toolsMap["select-filter-templateParams-combined-tool"] = map[string]any{
373 | "kind": "spanner-sql",
374 | "source": "my-instance",
375 | "description": "Create table tool with template parameters",
376 | "statement": "SELECT * FROM {{.tableName}} WHERE {{.columnFilter}} = @name",
377 | "parameters": []tools.Parameter{tools.NewStringParameter("name", "the name of the user")},
378 | "templateParameters": []tools.Parameter{
379 | tools.NewStringParameter("tableName", "some description"),
380 | tools.NewStringParameter("columnFilter", "some description"),
381 | },
382 | }
383 | config["tools"] = toolsMap
384 | return config
385 | }
386 |
387 | func runSpannerExecuteSqlToolInvokeTest(t *testing.T, select1Want, invokeParamWant, tableNameParam, tableNameAuth string) {
388 | // Get ID token
389 | idToken, err := tests.GetGoogleIdToken(tests.ClientId)
390 | if err != nil {
391 | t.Fatalf("error getting Google ID token: %s", err)
392 | }
393 |
394 | // Test tool invoke endpoint
395 | invokeTcs := []struct {
396 | name string
397 | api string
398 | requestHeader map[string]string
399 | requestBody io.Reader
400 | want string
401 | isErr bool
402 | }{
403 | {
404 | name: "invoke my-exec-sql-tool-read-only",
405 | api: "http://127.0.0.1:5000/api/tool/my-exec-sql-tool-read-only/invoke",
406 | requestHeader: map[string]string{},
407 | requestBody: bytes.NewBuffer([]byte(`{"sql":"SELECT 1"}`)),
408 | want: select1Want,
409 | isErr: false,
410 | },
411 | {
412 | name: "invoke my-exec-sql-tool-read-only with data present in table",
413 | api: "http://127.0.0.1:5000/api/tool/my-exec-sql-tool-read-only/invoke",
414 | requestHeader: map[string]string{},
415 | requestBody: bytes.NewBuffer([]byte(fmt.Sprintf("{\"sql\":\"SELECT * FROM %s WHERE id = 3 OR name = 'Alice'\"}", tableNameParam))),
416 | want: invokeParamWant,
417 | isErr: false,
418 | },
419 | {
420 | name: "invoke my-exec-sql-tool-read-only create table",
421 | api: "http://127.0.0.1:5000/api/tool/my-exec-sql-tool-read-only/invoke",
422 | requestHeader: map[string]string{},
423 | requestBody: bytes.NewBuffer([]byte(`{"sql":"CREATE TABLE t (id SERIAL PRIMARY KEY, name TEXT)"}`)),
424 | isErr: true,
425 | },
426 | {
427 | name: "invoke my-exec-sql-tool-read-only drop table",
428 | api: "http://127.0.0.1:5000/api/tool/my-exec-sql-tool-read-only/invoke",
429 | requestHeader: map[string]string{},
430 | requestBody: bytes.NewBuffer([]byte(`{"sql":"DROP TABLE t"}`)),
431 | isErr: true,
432 | },
433 | {
434 | name: "invoke my-exec-sql-tool-read-only insert entry",
435 | api: "http://127.0.0.1:5000/api/tool/my-exec-sql-tool-read-only/invoke",
436 | requestHeader: map[string]string{},
437 | requestBody: bytes.NewBuffer([]byte(fmt.Sprintf("{\"sql\":\"INSERT INTO %s (id, name) VALUES (4, 'test_name')\"}", tableNameParam))),
438 | isErr: true,
439 | },
440 | {
441 | name: "invoke my-exec-sql-tool without body",
442 | api: "http://127.0.0.1:5000/api/tool/my-exec-sql-tool/invoke",
443 | requestHeader: map[string]string{},
444 | requestBody: bytes.NewBuffer([]byte(`{}`)),
445 | isErr: true,
446 | },
447 | {
448 | name: "invoke my-exec-sql-tool",
449 | api: "http://127.0.0.1:5000/api/tool/my-exec-sql-tool/invoke",
450 | requestHeader: map[string]string{},
451 | requestBody: bytes.NewBuffer([]byte(`{"sql":"SELECT 1"}`)),
452 | want: select1Want,
453 | isErr: false,
454 | },
455 | {
456 | name: "invoke my-exec-sql-tool create table",
457 | api: "http://127.0.0.1:5000/api/tool/my-exec-sql-tool/invoke",
458 | requestHeader: map[string]string{},
459 | requestBody: bytes.NewBuffer([]byte(`{"sql":"CREATE TABLE t (id SERIAL PRIMARY KEY, name TEXT)"}`)),
460 | isErr: true,
461 | },
462 | {
463 | name: "invoke my-exec-sql-tool drop table",
464 | api: "http://127.0.0.1:5000/api/tool/my-exec-sql-tool/invoke",
465 | requestHeader: map[string]string{},
466 | requestBody: bytes.NewBuffer([]byte(`{"sql":"DROP TABLE t"}`)),
467 | isErr: true,
468 | },
469 | {
470 | name: "invoke my-exec-sql-tool insert entry",
471 | api: "http://127.0.0.1:5000/api/tool/my-exec-sql-tool/invoke",
472 | requestHeader: map[string]string{},
473 | requestBody: bytes.NewBuffer([]byte(fmt.Sprintf("{\"sql\":\"INSERT INTO %s (id, name) VALUES (5, 'test_name')\"}", tableNameParam))),
474 | want: "null",
475 | isErr: false,
476 | },
477 | {
478 | name: "invoke my-exec-sql-tool without body",
479 | api: "http://127.0.0.1:5000/api/tool/my-exec-sql-tool/invoke",
480 | requestHeader: map[string]string{},
481 | requestBody: bytes.NewBuffer([]byte(`{}`)),
482 | isErr: true,
483 | },
484 | {
485 | name: "Invoke my-auth-exec-sql-tool with auth token",
486 | api: "http://127.0.0.1:5000/api/tool/my-auth-exec-sql-tool/invoke",
487 | requestHeader: map[string]string{"my-google-auth_token": idToken},
488 | requestBody: bytes.NewBuffer([]byte(`{"sql":"SELECT 1"}`)),
489 | isErr: false,
490 | want: select1Want,
491 | },
492 | {
493 | name: "Invoke my-auth-exec-sql-tool with invalid auth token",
494 | api: "http://127.0.0.1:5000/api/tool/my-auth-exec-sql-tool/invoke",
495 | requestHeader: map[string]string{"my-google-auth_token": "INVALID_TOKEN"},
496 | requestBody: bytes.NewBuffer([]byte(`{"sql":"SELECT 1"}`)),
497 | isErr: true,
498 | },
499 | {
500 | name: "Invoke my-auth-exec-sql-tool without auth token",
501 | api: "http://127.0.0.1:5000/api/tool/my-auth-exec-sql-tool/invoke",
502 | requestHeader: map[string]string{},
503 | requestBody: bytes.NewBuffer([]byte(`{"sql":"SELECT 1"}`)),
504 | isErr: true,
505 | },
506 | }
507 | for _, tc := range invokeTcs {
508 | t.Run(tc.name, func(t *testing.T) {
509 | // Send Tool invocation request
510 | req, err := http.NewRequest(http.MethodPost, tc.api, tc.requestBody)
511 | if err != nil {
512 | t.Fatalf("unable to create request: %s", err)
513 | }
514 | req.Header.Add("Content-type", "application/json")
515 | for k, v := range tc.requestHeader {
516 | req.Header.Add(k, v)
517 | }
518 | resp, err := http.DefaultClient.Do(req)
519 | if err != nil {
520 | t.Fatalf("unable to send request: %s", err)
521 | }
522 | defer resp.Body.Close()
523 |
524 | if resp.StatusCode != http.StatusOK {
525 | if tc.isErr {
526 | return
527 | }
528 | bodyBytes, _ := io.ReadAll(resp.Body)
529 | t.Fatalf("response status code is not 200, got %d: %s", resp.StatusCode, string(bodyBytes))
530 | }
531 |
532 | // Check response body
533 | var body map[string]interface{}
534 | err = json.NewDecoder(resp.Body).Decode(&body)
535 | if err != nil {
536 | t.Fatalf("error parsing response body")
537 | }
538 |
539 | got, ok := body["result"].(string)
540 | if !ok {
541 | t.Fatalf("unable to find result in response body")
542 | }
543 |
544 | if got != tc.want {
545 | t.Fatalf("unexpected value: got %q, want %q", got, tc.want)
546 | }
547 | })
548 | }
549 | }
550 |
551 | // Helper function to verify table list results
552 | func verifyTableListResult(t *testing.T, body map[string]interface{}, expectedTables []string, expectedSimpleFormat bool) {
553 | // Parse the result
554 | result, ok := body["result"].(string)
555 | if !ok {
556 | t.Fatalf("unable to find result in response body")
557 | }
558 |
559 | var tables []interface{}
560 | err := json.Unmarshal([]byte(result), &tables)
561 | if err != nil {
562 | t.Fatalf("unable to parse result as JSON array: %s", err)
563 | }
564 |
565 | // If we expect specific tables, verify they exist
566 | if len(expectedTables) > 0 {
567 | tableNames := make(map[string]bool)
568 | requiredKeys := []string{"schema_name", "object_name", "object_type", "columns", "constraints", "indexes"}
569 | if expectedSimpleFormat {
570 | requiredKeys = []string{"name"}
571 | }
572 |
573 | for _, table := range tables {
574 | tableMap, ok := table.(map[string]interface{})
575 | if !ok {
576 | continue
577 | }
578 |
579 | // Parse object_details JSON string into map[string]interface{}
580 | if objectDetailsStr, ok := tableMap["object_details"].(string); ok {
581 | var objectDetails map[string]interface{}
582 | if err := json.Unmarshal([]byte(objectDetailsStr), &objectDetails); err != nil {
583 | t.Errorf("failed to parse object_details JSON: %v for %v", err, objectDetailsStr)
584 | continue
585 | }
586 |
587 | for _, reqKey := range requiredKeys {
588 | if _, hasKey := objectDetails[reqKey]; !hasKey {
589 | t.Errorf("missing required key '%s', for object_details: %v", reqKey, objectDetails)
590 | }
591 | }
592 | }
593 |
594 | if name, ok := tableMap["object_name"].(string); ok {
595 | tableNames[name] = true
596 | }
597 | }
598 |
599 | for _, expected := range expectedTables {
600 | if !tableNames[expected] {
601 | t.Errorf("expected table %s not found in results", expected)
602 | }
603 | }
604 | }
605 | }
606 |
607 | // runSpannerListTablesTest tests the spanner-list-tables tool
608 | func runSpannerListTablesTest(t *testing.T, tableNameParam, tableNameAuth, tableNameTemplateParam string) {
609 | invokeTcs := []struct {
610 | name string
611 | requestBody io.Reader
612 | expectedTables []string // empty means don't check specific tables
613 | useSimpleFormat bool
614 | }{
615 | {
616 | name: "list all tables with detailed format",
617 | requestBody: bytes.NewBuffer([]byte(`{}`)),
618 | expectedTables: []string{tableNameParam, tableNameAuth, tableNameTemplateParam},
619 | },
620 | {
621 | name: "list tables with simple format",
622 | requestBody: bytes.NewBuffer([]byte(`{"output_format": "simple"}`)),
623 | expectedTables: []string{tableNameParam, tableNameAuth, tableNameTemplateParam},
624 | useSimpleFormat: true,
625 | },
626 | {
627 | name: "list specific tables",
628 | requestBody: bytes.NewBuffer([]byte(fmt.Sprintf(`{"table_names": "%s,%s"}`, tableNameParam, tableNameAuth))),
629 | expectedTables: []string{tableNameParam, tableNameAuth},
630 | },
631 | {
632 | name: "list non-existent table",
633 | requestBody: bytes.NewBuffer([]byte(`{"table_names": "non_existent_table_xyz"}`)),
634 | expectedTables: []string{},
635 | },
636 | }
637 |
638 | for _, tc := range invokeTcs {
639 | t.Run(tc.name, func(t *testing.T) {
640 | // Use RunRequest helper function from tests package
641 | url := "http://127.0.0.1:5000/api/tool/list-tables-tool/invoke"
642 | headers := map[string]string{}
643 |
644 | resp, respBody := tests.RunRequest(t, http.MethodPost, url, tc.requestBody, headers)
645 |
646 | if resp.StatusCode != http.StatusOK {
647 | t.Fatalf("response status code is not 200, got %d: %s", resp.StatusCode, string(respBody))
648 | }
649 |
650 | // Check response body
651 | var body map[string]interface{}
652 | err := json.Unmarshal(respBody, &body)
653 | if err != nil {
654 | t.Fatalf("error parsing response body: %s", err)
655 | }
656 |
657 | verifyTableListResult(t, body, tc.expectedTables, tc.useSimpleFormat)
658 | })
659 | }
660 | }
661 |
662 | func runSpannerSchemaToolInvokeTest(t *testing.T, accessSchemaWant string) {
663 | invokeTcs := []struct {
664 | name string
665 | api string
666 | requestHeader map[string]string
667 | requestBody io.Reader
668 | want string
669 | isErr bool
670 | }{
671 | {
672 | name: "invoke list-tables-read-only",
673 | api: "http://127.0.0.1:5000/api/tool/access-schema-read-only/invoke",
674 | requestHeader: map[string]string{},
675 | requestBody: bytes.NewBuffer([]byte(`{}`)),
676 | want: accessSchemaWant,
677 | isErr: false,
678 | },
679 | {
680 | name: "invoke list-tables",
681 | api: "http://127.0.0.1:5000/api/tool/access-schema/invoke",
682 | requestHeader: map[string]string{},
683 | requestBody: bytes.NewBuffer([]byte(`{}`)),
684 | isErr: true,
685 | },
686 | }
687 | for _, tc := range invokeTcs {
688 | t.Run(tc.name, func(t *testing.T) {
689 | // Send Tool invocation request
690 | req, err := http.NewRequest(http.MethodPost, tc.api, tc.requestBody)
691 | if err != nil {
692 | t.Fatalf("unable to create request: %s", err)
693 | }
694 | req.Header.Add("Content-type", "application/json")
695 | for k, v := range tc.requestHeader {
696 | req.Header.Add(k, v)
697 | }
698 | resp, err := http.DefaultClient.Do(req)
699 | if err != nil {
700 | t.Fatalf("unable to send request: %s", err)
701 | }
702 | defer resp.Body.Close()
703 |
704 | if resp.StatusCode != http.StatusOK {
705 | if tc.isErr {
706 | return
707 | }
708 | bodyBytes, _ := io.ReadAll(resp.Body)
709 | t.Fatalf("response status code is not 200, got %d: %s", resp.StatusCode, string(bodyBytes))
710 | }
711 |
712 | // Check response body
713 | var body map[string]interface{}
714 | err = json.NewDecoder(resp.Body).Decode(&body)
715 | if err != nil {
716 | t.Fatalf("error parsing response body")
717 | }
718 |
719 | got, ok := body["result"].(string)
720 | if !ok {
721 | t.Fatalf("unable to find result in response body")
722 | }
723 |
724 | if got != tc.want {
725 | t.Fatalf("unexpected value: got %q, want %q", got, tc.want)
726 | }
727 | })
728 | }
729 | }
730 |
```
--------------------------------------------------------------------------------
/.ci/integration.cloudbuild.yaml:
--------------------------------------------------------------------------------
```yaml
1 | # Copyright 2024 Google 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.
14 |
15 | steps:
16 | - id: "install-dependencies"
17 | name: golang:1
18 | waitFor: ["-"]
19 | env:
20 | - "GOPATH=/gopath"
21 | volumes:
22 | - name: "go"
23 | path: "/gopath"
24 | script: |
25 | go get -d ./...
26 |
27 | - id: "compile-test-binary"
28 | name: golang:1
29 | waitFor: ["install-dependencies"]
30 | env:
31 | - "GOPATH=/gopath"
32 | volumes:
33 | - name: "go"
34 | path: "/gopath"
35 | script: |
36 | go test -c -race -cover \
37 | -coverpkg=./internal/sources/...,./internal/tools/... ./tests/...
38 | chmod +x .ci/test_with_coverage.sh
39 |
40 | - id: "cloud-sql-pg"
41 | name: golang:1
42 | waitFor: ["compile-test-binary"]
43 | entrypoint: /bin/bash
44 | env:
45 | - "GOPATH=/gopath"
46 | - "CLOUD_SQL_POSTGRES_PROJECT=$PROJECT_ID"
47 | - "CLOUD_SQL_POSTGRES_INSTANCE=$_CLOUD_SQL_POSTGRES_INSTANCE"
48 | - "CLOUD_SQL_POSTGRES_DATABASE=$_DATABASE_NAME"
49 | - "CLOUD_SQL_POSTGRES_REGION=$_REGION"
50 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
51 | secretEnv:
52 | ["CLOUD_SQL_POSTGRES_USER", "CLOUD_SQL_POSTGRES_PASS", "CLIENT_ID"]
53 | volumes:
54 | - name: "go"
55 | path: "/gopath"
56 | args:
57 | - -c
58 | - |
59 | .ci/test_with_coverage.sh \
60 | "Cloud SQL Postgres" \
61 | cloudsqlpg \
62 | postgressql \
63 | postgresexecutesql
64 |
65 | - id: "alloydb"
66 | name: golang:1
67 | waitFor: ["compile-test-binary"]
68 | entrypoint: /bin/bash
69 | env:
70 | - "GOPATH=/gopath"
71 | - "ALLOYDB_PROJECT=$PROJECT_ID"
72 | - "ALLOYDB_CLUSTER=$_ALLOYDB_POSTGRES_CLUSTER"
73 | - "ALLOYDB_INSTANCE=$_ALLOYDB_POSTGRES_INSTANCE"
74 | - "ALLOYDB_REGION=$_REGION"
75 | secretEnv: ["ALLOYDB_POSTGRES_USER"]
76 | volumes:
77 | - name: "go"
78 | path: "/gopath"
79 | args:
80 | - -c
81 | - |
82 | .ci/test_with_coverage.sh \
83 | "AlloyDB" \
84 | alloydb \
85 | alloydb
86 |
87 | - id: "alloydb-pg"
88 | name: golang:1
89 | waitFor: ["compile-test-binary"]
90 | entrypoint: /bin/bash
91 | env:
92 | - "GOPATH=/gopath"
93 | - "ALLOYDB_POSTGRES_PROJECT=$PROJECT_ID"
94 | - "ALLOYDB_POSTGRES_CLUSTER=$_ALLOYDB_POSTGRES_CLUSTER"
95 | - "ALLOYDB_POSTGRES_INSTANCE=$_ALLOYDB_POSTGRES_INSTANCE"
96 | - "ALLOYDB_POSTGRES_DATABASE=$_DATABASE_NAME"
97 | - "ALLOYDB_POSTGRES_REGION=$_REGION"
98 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
99 | secretEnv: ["ALLOYDB_POSTGRES_USER", "ALLOYDB_POSTGRES_PASS", "CLIENT_ID"]
100 | volumes:
101 | - name: "go"
102 | path: "/gopath"
103 | args:
104 | - -c
105 | - |
106 | .ci/test_with_coverage.sh \
107 | "AlloyDB Postgres" \
108 | alloydbpg \
109 | postgressql \
110 | postgresexecutesql
111 |
112 | - id: "alloydb-ai-nl"
113 | name: golang:1
114 | waitFor: ["compile-test-binary"]
115 | entrypoint: /bin/bash
116 | env:
117 | - "GOPATH=/gopath"
118 | - "ALLOYDB_AI_NL_PROJECT=$PROJECT_ID"
119 | - "ALLOYDB_AI_NL_CLUSTER=$_ALLOYDB_AI_NL_CLUSTER"
120 | - "ALLOYDB_AI_NL_INSTANCE=$_ALLOYDB_AI_NL_INSTANCE"
121 | - "ALLOYDB_AI_NL_DATABASE=$_AI_NL_DATABASE_NAME"
122 | - "ALLOYDB_AI_NL_REGION=$_REGION"
123 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
124 | secretEnv: ["ALLOYDB_AI_NL_USER", "ALLOYDB_AI_NL_PASS", "CLIENT_ID"]
125 | volumes:
126 | - name: "go"
127 | path: "/gopath"
128 | args:
129 | - -c
130 | - |
131 | .ci/test_with_coverage.sh \
132 | "AlloyDB AI NL" \
133 | alloydbainl \
134 | alloydbainl
135 |
136 | - id: "bigtable"
137 | name: golang:1
138 | waitFor: ["compile-test-binary"]
139 | entrypoint: /bin/bash
140 | env:
141 | - "GOPATH=/gopath"
142 | - "BIGTABLE_PROJECT=$PROJECT_ID"
143 | - "BIGTABLE_INSTANCE=$_BIGTABLE_INSTANCE"
144 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
145 | secretEnv: ["CLIENT_ID"]
146 | volumes:
147 | - name: "go"
148 | path: "/gopath"
149 | args:
150 | - -c
151 | - |
152 | .ci/test_with_coverage.sh \
153 | "Bigtable" \
154 | bigtable \
155 | bigtable
156 |
157 | - id: "bigquery"
158 | name: golang:1
159 | waitFor: ["compile-test-binary"]
160 | entrypoint: /bin/bash
161 | env:
162 | - "GOPATH=/gopath"
163 | - "BIGQUERY_PROJECT=$PROJECT_ID"
164 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
165 | secretEnv: ["CLIENT_ID"]
166 | volumes:
167 | - name: "go"
168 | path: "/gopath"
169 | args:
170 | - -c
171 | - |
172 | .ci/test_with_coverage.sh \
173 | "BigQuery" \
174 | bigquery \
175 | bigquery
176 |
177 | - id: "dataplex"
178 | name: golang:1
179 | waitFor: ["compile-test-binary"]
180 | entrypoint: /bin/bash
181 | env:
182 | - "GOPATH=/gopath"
183 | - "DATAPLEX_PROJECT=$PROJECT_ID"
184 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
185 | secretEnv: ["CLIENT_ID"]
186 | volumes:
187 | - name: "go"
188 | path: "/gopath"
189 | args:
190 | - -c
191 | - |
192 | .ci/test_with_coverage.sh \
193 | "Dataplex" \
194 | dataplex \
195 | dataplex
196 |
197 | - id: "dataform"
198 | name: golang:1
199 | waitFor: ["compile-test-binary"]
200 | entrypoint: /bin/bash
201 | env:
202 | - "GOPATH=/gopath"
203 | secretEnv: ["CLIENT_ID"]
204 | volumes:
205 | - name: "go"
206 | path: "/gopath"
207 | args:
208 | - -c
209 | - |
210 | apt-get update && apt-get install -y npm && \
211 | npm install -g @dataform/cli && \
212 | .ci/test_with_coverage.sh \
213 | "Dataform" \
214 | dataform \
215 | dataform
216 |
217 | - id: "postgres"
218 | name: golang:1
219 | waitFor: ["compile-test-binary"]
220 | entrypoint: /bin/bash
221 | env:
222 | - "GOPATH=/gopath"
223 | - "POSTGRES_DATABASE=$_DATABASE_NAME"
224 | - "POSTGRES_HOST=$_POSTGRES_HOST"
225 | - "POSTGRES_PORT=$_POSTGRES_PORT"
226 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
227 | secretEnv: ["POSTGRES_USER", "POSTGRES_PASS", "CLIENT_ID"]
228 | volumes:
229 | - name: "go"
230 | path: "/gopath"
231 | args:
232 | - -c
233 | - |
234 | .ci/test_with_coverage.sh \
235 | "Postgres" \
236 | postgres \
237 | postgressql \
238 | postgresexecutesql
239 |
240 | - id: "spanner"
241 | name: golang:1
242 | waitFor: ["compile-test-binary"]
243 | entrypoint: /bin/bash
244 | env:
245 | - "GOPATH=/gopath"
246 | - "SPANNER_PROJECT=$PROJECT_ID"
247 | - "SPANNER_DATABASE=$_DATABASE_NAME"
248 | - "SPANNER_INSTANCE=$_SPANNER_INSTANCE"
249 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
250 | secretEnv: ["CLIENT_ID"]
251 | volumes:
252 | - name: "go"
253 | path: "/gopath"
254 | args:
255 | - -c
256 | - |
257 | .ci/test_with_coverage.sh \
258 | "Spanner" \
259 | spanner \
260 | spanner
261 |
262 | - id: "neo4j"
263 | name: golang:1
264 | waitFor: ["compile-test-binary"]
265 | entrypoint: /bin/bash
266 | env:
267 | - "GOPATH=/gopath"
268 | - "NEO4J_DATABASE=$_NEO4J_DATABASE"
269 | - "NEO4J_URI=$_NEO4J_URI"
270 | secretEnv: ["NEO4J_USER", "NEO4J_PASS"]
271 | volumes:
272 | - name: "go"
273 | path: "/gopath"
274 | args:
275 | - -c
276 | - |
277 | .ci/test_with_coverage.sh \
278 | "Neo4j" \
279 | neo4j \
280 | neo4j
281 |
282 | - id: "cloud-sql-mssql"
283 | name: golang:1
284 | waitFor: ["compile-test-binary"]
285 | entrypoint: /bin/bash
286 | env:
287 | - "GOPATH=/gopath"
288 | - "CLOUD_SQL_MSSQL_PROJECT=$PROJECT_ID"
289 | - "CLOUD_SQL_MSSQL_INSTANCE=$_CLOUD_SQL_MSSQL_INSTANCE"
290 | - "CLOUD_SQL_MSSQL_IP=$_CLOUD_SQL_MSSQL_IP"
291 | - "CLOUD_SQL_MSSQL_DATABASE=$_DATABASE_NAME"
292 | - "CLOUD_SQL_MSSQL_REGION=$_REGION"
293 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
294 | secretEnv: ["CLOUD_SQL_MSSQL_USER", "CLOUD_SQL_MSSQL_PASS", "CLIENT_ID"]
295 | volumes:
296 | - name: "go"
297 | path: "/gopath"
298 | args:
299 | - -c
300 | - |
301 | .ci/test_with_coverage.sh \
302 | "Cloud SQL MSSQL" \
303 | cloudsqlmssql \
304 | mssql
305 |
306 | - id: "cloud-sql-mysql"
307 | name: golang:1
308 | waitFor: ["compile-test-binary"]
309 | entrypoint: /bin/bash
310 | env:
311 | - "GOPATH=/gopath"
312 | - "CLOUD_SQL_MYSQL_PROJECT=$PROJECT_ID"
313 | - "CLOUD_SQL_MYSQL_INSTANCE=$_CLOUD_SQL_MYSQL_INSTANCE"
314 | - "CLOUD_SQL_MYSQL_DATABASE=$_DATABASE_NAME"
315 | - "CLOUD_SQL_MYSQL_REGION=$_REGION"
316 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
317 | secretEnv: ["CLOUD_SQL_MYSQL_USER", "CLOUD_SQL_MYSQL_PASS", "CLIENT_ID"]
318 | volumes:
319 | - name: "go"
320 | path: "/gopath"
321 | args:
322 | - -c
323 | - |
324 | .ci/test_with_coverage.sh \
325 | "Cloud SQL MySQL" \
326 | cloudsqlmysql \
327 | mysql || echo "Integration tests failed." # ignore test failures
328 |
329 | - id: "mysql"
330 | name: golang:1
331 | waitFor: ["compile-test-binary"]
332 | entrypoint: /bin/bash
333 | env:
334 | - "GOPATH=/gopath"
335 | - "MYSQL_DATABASE=$_DATABASE_NAME"
336 | - "MYSQL_HOST=$_MYSQL_HOST"
337 | - "MYSQL_PORT=$_MYSQL_PORT"
338 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
339 | secretEnv: ["MYSQL_USER", "MYSQL_PASS", "CLIENT_ID"]
340 | volumes:
341 | - name: "go"
342 | path: "/gopath"
343 | args:
344 | - -c
345 | - |
346 | .ci/test_with_coverage.sh \
347 | "MySQL" \
348 | mysql \
349 | mysql || echo "Integration tests failed." # ignore test failures
350 |
351 | - id: "mssql"
352 | name: golang:1
353 | waitFor: ["compile-test-binary"]
354 | entrypoint: /bin/bash
355 | env:
356 | - "GOPATH=/gopath"
357 | - "MSSQL_DATABASE=$_DATABASE_NAME"
358 | - "MSSQL_HOST=$_MSSQL_HOST"
359 | - "MSSQL_PORT=$_MSSQL_PORT"
360 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
361 | secretEnv: ["MSSQL_USER", "MSSQL_PASS", "CLIENT_ID"]
362 | volumes:
363 | - name: "go"
364 | path: "/gopath"
365 | args:
366 | - -c
367 | - |
368 | .ci/test_with_coverage.sh \
369 | "MSSQL" \
370 | mssql \
371 | mssql
372 |
373 | # - id: "dgraph"
374 | # name: golang:1
375 | # waitFor: ["compile-test-binary"]
376 | # entrypoint: /bin/bash
377 | # env:
378 | # - "GOPATH=/gopath"
379 | # - "DGRAPH_URL=$_DGRAPHURL"
380 | # volumes:
381 | # - name: "go"
382 | # path: "/gopath"
383 | # args:
384 | # - -c
385 | # - |
386 | # .ci/test_with_coverage.sh \
387 | # "Dgraph" \
388 | # dgraph \
389 | # dgraph
390 |
391 | - id: "http"
392 | name: golang:1
393 | waitFor: ["compile-test-binary"]
394 | entrypoint: /bin/bash
395 | env:
396 | - "GOPATH=/gopath"
397 | secretEnv: ["CLIENT_ID"]
398 | volumes:
399 | - name: "go"
400 | path: "/gopath"
401 | args:
402 | - -c
403 | - |
404 | .ci/test_with_coverage.sh \
405 | "HTTP" \
406 | http \
407 | http
408 |
409 | - id: "sqlite"
410 | name: golang:1
411 | waitFor: ["compile-test-binary"]
412 | entrypoint: /bin/bash
413 | env:
414 | - "GOPATH=/gopath"
415 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
416 | volumes:
417 | - name: "go"
418 | path: "/gopath"
419 | secretEnv: ["CLIENT_ID"]
420 | args:
421 | - -c
422 | - |
423 | .ci/test_with_coverage.sh \
424 | "SQLite" \
425 | sqlite \
426 | sqlite
427 |
428 | - id: "couchbase"
429 | name: golang:1
430 | waitFor: ["compile-test-binary"]
431 | entrypoint: /bin/bash
432 | env:
433 | - "GOPATH=/gopath"
434 | - "COUCHBASE_SCOPE=$_COUCHBASE_SCOPE"
435 | - "COUCHBASE_BUCKET=$_COUCHBASE_BUCKET"
436 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
437 | secretEnv:
438 | ["COUCHBASE_CONNECTION", "COUCHBASE_USER", "COUCHBASE_PASS", "CLIENT_ID"]
439 | volumes:
440 | - name: "go"
441 | path: "/gopath"
442 | args:
443 | - -c
444 | - |
445 | .ci/test_with_coverage.sh \
446 | "Couchbase" \
447 | couchbase \
448 | couchbase
449 |
450 | - id: "redis"
451 | name: golang:1
452 | waitFor: ["compile-test-binary"]
453 | entrypoint: /bin/bash
454 | env:
455 | - "GOPATH=/gopath"
456 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
457 | secretEnv: ["REDIS_ADDRESS", "REDIS_PASS", "CLIENT_ID"]
458 | volumes:
459 | - name: "go"
460 | path: "/gopath"
461 | args:
462 | - -c
463 | - |
464 | .ci/test_with_coverage.sh \
465 | "Redis" \
466 | redis \
467 | redis
468 |
469 | - id: "valkey"
470 | name: golang:1
471 | waitFor: ["compile-test-binary"]
472 | entrypoint: /bin/bash
473 | env:
474 | - "GOPATH=/gopath"
475 | - "VALKEY_DATABASE=$_VALKEY_DATABASE"
476 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
477 | secretEnv: ["VALKEY_ADDRESS", "CLIENT_ID"]
478 | volumes:
479 | - name: "go"
480 | path: "/gopath"
481 | args:
482 | - -c
483 | - |
484 | .ci/test_with_coverage.sh \
485 | "Valkey" \
486 | valkey \
487 | valkey
488 |
489 | - id: "oceanbase"
490 | name: golang:1
491 | waitFor: ["compile-test-binary"]
492 | entrypoint: /bin/bash
493 | env:
494 | - "GOPATH=/gopath"
495 | - "OCEANBASE_PORT=$_OCEANBASE_PORT"
496 | - "OCEANBASE_DATABASE=$_OCEANBASE_DATABASE"
497 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
498 | secretEnv:
499 | ["CLIENT_ID", "OCEANBASE_HOST", "OCEANBASE_USER", "OCEANBASE_PASSWORD"]
500 | volumes:
501 | - name: "go"
502 | path: "/gopath"
503 | args:
504 | - -c
505 | - |
506 | .ci/test_with_coverage.sh \
507 | "OceanBase" \
508 | oceanbase \
509 | oceanbase
510 |
511 | - id: "firestore"
512 | name: golang:1
513 | waitFor: ["compile-test-binary"]
514 | entrypoint: /bin/bash
515 | env:
516 | - "GOPATH=/gopath"
517 | - "FIRESTORE_PROJECT=$PROJECT_ID"
518 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
519 | secretEnv: ["CLIENT_ID"]
520 | volumes:
521 | - name: "go"
522 | path: "/gopath"
523 | args:
524 | - -c
525 | - |
526 | .ci/test_with_coverage.sh \
527 | "Firestore" \
528 | firestore \
529 | firestore
530 |
531 | - id: "looker"
532 | name: golang:1
533 | waitFor: ["compile-test-binary"]
534 | entrypoint: /bin/bash
535 | env:
536 | - "GOPATH=/gopath"
537 | - "FIRESTORE_PROJECT=$PROJECT_ID"
538 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
539 | - "LOOKER_VERIFY_SSL=$_LOOKER_VERIFY_SSL"
540 | - "LOOKER_PROJECT=$_LOOKER_PROJECT"
541 | - "LOOKER_LOCATION=$_LOOKER_LOCATION"
542 | secretEnv:
543 | [
544 | "CLIENT_ID",
545 | "LOOKER_BASE_URL",
546 | "LOOKER_CLIENT_ID",
547 | "LOOKER_CLIENT_SECRET",
548 | ]
549 | volumes:
550 | - name: "go"
551 | path: "/gopath"
552 | args:
553 | - -c
554 | - |
555 | .ci/test_with_coverage.sh \
556 | "Looker" \
557 | looker \
558 | looker
559 |
560 | - id: "mindsdb"
561 | name: golang:1
562 | waitFor: ["compile-test-binary"]
563 | entrypoint: /bin/bash
564 | env:
565 | - "GOPATH=/gopath"
566 | - "MINDSDB_PORT=$_MINDSDB_PORT"
567 | - "MINDSDB_DATABASE=$_MINDSDB_DATABASE"
568 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
569 | secretEnv: ["MINDSDB_HOST", "MINDSDB_USER", "MINDSDB_PASS", "CLIENT_ID"]
570 | volumes:
571 | - name: "go"
572 | path: "/gopath"
573 | args:
574 | - -c
575 | - |
576 | .ci/test_with_coverage.sh \
577 | "MindsDB" \
578 | mindsdb \
579 | mindsdb
580 |
581 | - id: "cloud-sql"
582 | name: golang:1
583 | waitFor: ["compile-test-binary"]
584 | entrypoint: /bin/bash
585 | env:
586 | - "GOPATH=/gopath"
587 | secretEnv: ["CLIENT_ID"]
588 | volumes:
589 | - name: "go"
590 | path: "/gopath"
591 | args:
592 | - -c
593 | - |
594 | .ci/test_with_coverage.sh \
595 | "Cloud SQL Wait for Operation" \
596 | cloudsql \
597 | cloudsql
598 |
599 | - id: "tidb"
600 | name: golang:1
601 | waitFor: ["compile-test-binary"]
602 | entrypoint: /bin/bash
603 | env:
604 | - "GOPATH=/gopath"
605 | - "TIDB_DATABASE=$_DATABASE_NAME"
606 | - "TIDB_HOST=$_TIDB_HOST"
607 | - "TIDB_PORT=$_TIDB_PORT"
608 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
609 | secretEnv: ["CLIENT_ID", "TIDB_USER", "TIDB_PASS"]
610 | volumes:
611 | - name: "go"
612 | path: "/gopath"
613 | args:
614 | - -c
615 | - |
616 | .ci/test_with_coverage.sh \
617 | "TiDB" \
618 | tidb \
619 | tidbsql tidbexecutesql
620 |
621 | - id: "firebird"
622 | name: golang:1
623 | waitFor: ["compile-test-binary"]
624 | entrypoint: /bin/bash
625 | env:
626 | - "GOPATH=/gopath"
627 | - "FIREBIRD_DATABASE=$_FIREBIRD_DATABASE_NAME"
628 | - "FIREBIRD_HOST=$_FIREBIRD_HOST"
629 | - "FIREBIRD_PORT=$_FIREBIRD_PORT"
630 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
631 | secretEnv: ["CLIENT_ID", "FIREBIRD_USER", "FIREBIRD_PASS"]
632 | volumes:
633 | - name: "go"
634 | path: "/gopath"
635 | args:
636 | - -c
637 | - |
638 | .ci/test_with_coverage.sh \
639 | "Firebird" \
640 | firebird \
641 | firebirdsql firebirdexecutesql
642 |
643 | - id: "clickhouse"
644 | name: golang:1
645 | waitFor: ["compile-test-binary"]
646 | entrypoint: /bin/bash
647 | env:
648 | - "GOPATH=/gopath"
649 | - "CLICKHOUSE_DATABASE=$_CLICKHOUSE_DATABASE"
650 | - "CLICKHOUSE_PORT=$_CLICKHOUSE_PORT"
651 | - "CLICKHOUSE_PROTOCOL=$_CLICKHOUSE_PROTOCOL"
652 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
653 | secretEnv: ["CLICKHOUSE_HOST", "CLICKHOUSE_USER", "CLIENT_ID"]
654 | volumes:
655 | - name: "go"
656 | path: "/gopath"
657 | args:
658 | - -c
659 | - |
660 | .ci/test_with_coverage.sh \
661 | "ClickHouse" \
662 | clickhouse \
663 | clickhouse
664 |
665 | - id: "trino"
666 | name: golang:1
667 | waitFor: ["compile-test-binary"]
668 | entrypoint: /bin/bash
669 | env:
670 | - "GOPATH=/gopath"
671 | - "TRINO_HOST=$_TRINO_HOST"
672 | - "TRINO_PORT=$_TRINO_PORT"
673 | - "TRINO_CATALOG=$_TRINO_CATALOG"
674 | - "TRINO_SCHEMA=$_TRINO_SCHEMA"
675 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
676 | secretEnv: ["CLIENT_ID", "TRINO_USER"]
677 | volumes:
678 | - name: "go"
679 | path: "/gopath"
680 | args:
681 | - -c
682 | - |
683 | .ci/test_with_coverage.sh \
684 | "Trino" \
685 | trino \
686 | trinosql trinoexecutesql
687 |
688 | - id: "yugabytedb"
689 | name: golang:1
690 | waitFor: ["compile-test-binary"]
691 | entrypoint: /bin/bash
692 | env:
693 | - "GOPATH=/gopath"
694 | - "YUGABYTEDB_DATABASE=$_YUGABYTEDB_DATABASE"
695 | - "YUGABYTEDB_PORT=$_YUGABYTEDB_PORT"
696 | - "YUGABYTEDB_LOADBALANCE=$_YUGABYTEDB_LOADBALANCE"
697 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
698 | secretEnv:
699 | ["YUGABYTEDB_USER", "YUGABYTEDB_PASS", "YUGABYTEDB_HOST", "CLIENT_ID"]
700 | volumes:
701 | - name: "go"
702 | path: "/gopath"
703 | args:
704 | - -c
705 | - |
706 | ./yugabytedb.test -test.v
707 |
708 | - id: "elasticsearch"
709 | name: golang:1
710 | waitFor: ["compile-test-binary"]
711 | entrypoint: /bin/bash
712 | env:
713 | - "GOPATH=/gopath"
714 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
715 | secretEnv: ["CLIENT_ID", "ELASTICSEARCH_USER", "ELASTICSEARCH_PASS", "ELASTICSEARCH_HOST"]
716 | volumes:
717 | - name: "go"
718 | path: "/gopath"
719 | args:
720 | - -c
721 | - |
722 | .ci/test_with_coverage.sh \
723 | "Elasticsearch" \
724 | elasticsearch \
725 | elasticsearch
726 |
727 |
728 | - id: "cassandra"
729 | name: golang:1
730 | waitFor: ["compile-test-binary"]
731 | entrypoint: /bin/bash
732 | env:
733 | - "GOPATH=/gopath"
734 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
735 | secretEnv: ["CLIENT_ID", "CASSANDRA_USER", "CASSANDRA_PASS", "CASSANDRA_HOST"]
736 | volumes:
737 | - name: "go"
738 | path: "/gopath"
739 | args:
740 | - -c
741 | - |
742 | .ci/test_with_coverage.sh \
743 | "Cassandra" \
744 | cassandra \
745 | cassandra
746 |
747 | - id: "oracle"
748 | name: golang:1
749 | waitFor: ["compile-test-binary"]
750 | entrypoint: /bin/bash
751 | env:
752 | - "GOPATH=/gopath"
753 | - "SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT_EMAIL"
754 | - "ORACLE_SERVER_NAME=$_ORACLE_SERVER_NAME"
755 | secretEnv: ["CLIENT_ID", "ORACLE_USER", "ORACLE_PASS", "ORACLE_HOST"]
756 | volumes:
757 | - name: "go"
758 | path: "/gopath"
759 | args:
760 | - -c
761 | - |
762 | .ci/test_with_coverage.sh \
763 | "Oracle" \
764 | oracle \
765 | oracle
766 |
767 | - id: "serverless-spark"
768 | name: golang:1
769 | waitFor: ["compile-test-binary"]
770 | entrypoint: /bin/bash
771 | env:
772 | - "GOPATH=/gopath"
773 | - "SERVERLESS_SPARK_LOCATION=$_REGION"
774 | - "SERVERLESS_SPARK_PROJECT=$PROJECT_ID"
775 | - "SERVERLESS_SPARK_SERVICE_ACCOUNT=$SERVICE_ACCOUNT_EMAIL"
776 | secretEnv: ["CLIENT_ID"]
777 | volumes:
778 | - name: "go"
779 | path: "/gopath"
780 | args:
781 | - -c
782 | - |
783 | .ci/test_with_coverage.sh \
784 | "Serverless Spark" \
785 | serverlessspark
786 |
787 | availableSecrets:
788 | secretManager:
789 | - versionName: projects/$PROJECT_ID/secrets/cloud_sql_pg_user/versions/latest
790 | env: CLOUD_SQL_POSTGRES_USER
791 | - versionName: projects/$PROJECT_ID/secrets/cloud_sql_pg_pass/versions/latest
792 | env: CLOUD_SQL_POSTGRES_PASS
793 | - versionName: projects/$PROJECT_ID/secrets/alloydb_pg_user/versions/latest
794 | env: ALLOYDB_POSTGRES_USER
795 | - versionName: projects/$PROJECT_ID/secrets/alloydb_pg_pass/versions/latest
796 | env: ALLOYDB_POSTGRES_PASS
797 | - versionName: projects/$PROJECT_ID/secrets/alloydb_ai_nl_user/versions/latest
798 | env: ALLOYDB_AI_NL_USER
799 | - versionName: projects/$PROJECT_ID/secrets/alloydb_ai_nl_pass/versions/latest
800 | env: ALLOYDB_AI_NL_PASS
801 | - versionName: projects/$PROJECT_ID/secrets/postgres_user/versions/latest
802 | env: POSTGRES_USER
803 | - versionName: projects/$PROJECT_ID/secrets/postgres_pass/versions/latest
804 | env: POSTGRES_PASS
805 | - versionName: projects/$PROJECT_ID/secrets/client_id/versions/latest
806 | env: CLIENT_ID
807 | - versionName: projects/$PROJECT_ID/secrets/neo4j_user/versions/latest
808 | env: NEO4J_USER
809 | - versionName: projects/$PROJECT_ID/secrets/neo4j_pass/versions/latest
810 | env: NEO4J_PASS
811 | - versionName: projects/$PROJECT_ID/secrets/cloud_sql_mssql_user/versions/latest
812 | env: CLOUD_SQL_MSSQL_USER
813 | - versionName: projects/$PROJECT_ID/secrets/cloud_sql_mssql_pass/versions/latest
814 | env: CLOUD_SQL_MSSQL_PASS
815 | - versionName: projects/$PROJECT_ID/secrets/cloud_sql_mysql_user/versions/latest
816 | env: CLOUD_SQL_MYSQL_USER
817 | - versionName: projects/$PROJECT_ID/secrets/cloud_sql_mysql_pass/versions/latest
818 | env: CLOUD_SQL_MYSQL_PASS
819 | - versionName: projects/$PROJECT_ID/secrets/mysql_user/versions/latest
820 | env: MYSQL_USER
821 | - versionName: projects/$PROJECT_ID/secrets/mysql_pass/versions/latest
822 | env: MYSQL_PASS
823 | - versionName: projects/$PROJECT_ID/secrets/mssql_user/versions/latest
824 | env: MSSQL_USER
825 | - versionName: projects/$PROJECT_ID/secrets/mssql_pass/versions/latest
826 | env: MSSQL_PASS
827 | - versionName: projects/$PROJECT_ID/secrets/couchbase_connection/versions/latest
828 | env: COUCHBASE_CONNECTION
829 | - versionName: projects/$PROJECT_ID/secrets/couchbase_user/versions/latest
830 | env: COUCHBASE_USER
831 | - versionName: projects/$PROJECT_ID/secrets/couchbase_pass/versions/latest
832 | env: COUCHBASE_PASS
833 | - versionName: projects/$PROJECT_ID/secrets/memorystore_redis_address/versions/latest
834 | env: REDIS_ADDRESS
835 | - versionName: projects/$PROJECT_ID/secrets/memorystore_redis_pass/versions/latest
836 | env: REDIS_PASS
837 | - versionName: projects/$PROJECT_ID/secrets/memorystore_valkey_address/versions/latest
838 | env: VALKEY_ADDRESS
839 | - versionName: projects/$PROJECT_ID/secrets/looker_base_url/versions/latest
840 | env: LOOKER_BASE_URL
841 | - versionName: projects/$PROJECT_ID/secrets/looker_client_id/versions/latest
842 | env: LOOKER_CLIENT_ID
843 | - versionName: projects/$PROJECT_ID/secrets/looker_client_secret/versions/latest
844 | env: LOOKER_CLIENT_SECRET
845 | - versionName: projects/$PROJECT_ID/secrets/tidb_user/versions/latest
846 | env: TIDB_USER
847 | - versionName: projects/$PROJECT_ID/secrets/tidb_pass/versions/latest
848 | env: TIDB_PASS
849 | - versionName: projects/$PROJECT_ID/secrets/clickhouse_host/versions/latest
850 | env: CLICKHOUSE_HOST
851 | - versionName: projects/$PROJECT_ID/secrets/clickhouse_user/versions/latest
852 | env: CLICKHOUSE_USER
853 | - versionName: projects/$PROJECT_ID/secrets/firebird_user/versions/latest
854 | env: FIREBIRD_USER
855 | - versionName: projects/$PROJECT_ID/secrets/firebird_pass/versions/latest
856 | env: FIREBIRD_PASS
857 | - versionName: projects/$PROJECT_ID/secrets/trino_user/versions/latest
858 | env: TRINO_USER
859 | - versionName: projects/$PROJECT_ID/secrets/oceanbase_host/versions/latest
860 | env: OCEANBASE_HOST
861 | - versionName: projects/$PROJECT_ID/secrets/oceanbase_user/versions/latest
862 | env: OCEANBASE_USER
863 | - versionName: projects/$PROJECT_ID/secrets/oceanbase_pass/versions/latest
864 | env: OCEANBASE_PASSWORD
865 | - versionName: projects/$PROJECT_ID/secrets/mindsdb_host/versions/latest
866 | env: MINDSDB_HOST
867 | - versionName: projects/$PROJECT_ID/secrets/mindsdb_user/versions/latest
868 | env: MINDSDB_USER
869 | - versionName: projects/$PROJECT_ID/secrets/mindsdb_pass/versions/latest
870 | env: MINDSDB_PASS
871 | - versionName: projects/$PROJECT_ID/secrets/yugabytedb_host/versions/latest
872 | env: YUGABYTEDB_HOST
873 | - versionName: projects/$PROJECT_ID/secrets/yugabytedb_user/versions/latest
874 | env: YUGABYTEDB_USER
875 | - versionName: projects/$PROJECT_ID/secrets/yugabytedb_pass/versions/latest
876 | env: YUGABYTEDB_PASS
877 | - versionName: projects/$PROJECT_ID/secrets/elastic_search_host/versions/latest
878 | env: ELASTICSEARCH_HOST
879 | - versionName: projects/$PROJECT_ID/secrets/elastic_search_user/versions/latest
880 | env: ELASTICSEARCH_USER
881 | - versionName: projects/$PROJECT_ID/secrets/elastic_search_pass/versions/latest
882 | env: ELASTICSEARCH_PASS
883 | - versionName: projects/$PROJECT_ID/secrets/cassandra_user/versions/latest
884 | env: CASSANDRA_USER
885 | - versionName: projects/$PROJECT_ID/secrets/cassandra_pass/versions/latest
886 | env: CASSANDRA_PASS
887 | - versionName: projects/$PROJECT_ID/secrets/cassandra_host/versions/latest
888 | env: CASSANDRA_HOST
889 | - versionName: projects/$PROJECT_ID/secrets/oracle_user/versions/latest
890 | env: ORACLE_USER
891 | - versionName: projects/$PROJECT_ID/secrets/oracle_pass/versions/latest
892 | env: ORACLE_PASS
893 | - versionName: projects/$PROJECT_ID/secrets/oracle_host/versions/latest
894 | env: ORACLE_HOST
895 |
896 | options:
897 | logging: CLOUD_LOGGING_ONLY
898 | automapSubstitutions: true
899 | substitutionOption: "ALLOW_LOOSE"
900 | dynamicSubstitutions: true
901 | pool:
902 | name: projects/$PROJECT_ID/locations/us-central1/workerPools/integration-testing # Necessary for VPC network connection
903 |
904 | substitutions:
905 | _DATABASE_NAME: test_database
906 | _AI_NL_DATABASE_NAME: ainl_update_testing
907 | _FIREBIRD_DATABASE_NAME: /firebird/test_database.fdb
908 | _REGION: "us-central1"
909 | _CLOUD_SQL_POSTGRES_INSTANCE: "cloud-sql-pg-testing"
910 | _ALLOYDB_POSTGRES_CLUSTER: "alloydb-pg-testing"
911 | _ALLOYDB_POSTGRES_INSTANCE: "alloydb-pg-testing-instance"
912 | _ALLOYDB_AI_NL_CLUSTER: "alloydb-ai-nl-testing"
913 | _ALLOYDB_AI_NL_INSTANCE: "alloydb-ai-nl-testing-instance"
914 | _BIGTABLE_INSTANCE: "bigtable-testing-instance"
915 | _POSTGRES_HOST: 127.0.0.1
916 | _POSTGRES_PORT: "5432"
917 | _SPANNER_INSTANCE: "spanner-testing"
918 | _NEO4J_DATABASE: "neo4j"
919 | _CLOUD_SQL_MSSQL_INSTANCE: "cloud-sql-mssql-testing"
920 | _CLOUD_SQL_MYSQL_INSTANCE: "cloud-sql-mysql-testing"
921 | _MYSQL_HOST: 127.0.0.1
922 | _MYSQL_PORT: "3306"
923 | _MSSQL_HOST: 127.0.0.1
924 | _MSSQL_PORT: "1433"
925 | _DGRAPHURL: "https://play.dgraph.io"
926 | _COUCHBASE_BUCKET: "couchbase-bucket"
927 | _COUCHBASE_SCOPE: "couchbase-scope"
928 | _LOOKER_LOCATION: "us"
929 | _LOOKER_PROJECT: "149671255749"
930 | _LOOKER_VERIFY_SSL: "true"
931 | _TIDB_HOST: 127.0.0.1
932 | _TIDB_PORT: "4000"
933 | _CLICKHOUSE_DATABASE: "default"
934 | _CLICKHOUSE_PORT: "8123"
935 | _CLICKHOUSE_PROTOCOL: "http"
936 | _FIREBIRD_HOST: 127.0.0.1
937 | _FIREBIRD_PORT: "3050"
938 | _TRINO_HOST: 127.0.0.1
939 | _TRINO_PORT: "8080"
940 | _TRINO_CATALOG: "memory"
941 | _TRINO_SCHEMA: "default"
942 | _OCEANBASE_PORT: "2883"
943 | _OCEANBASE_DATABASE: "oceanbase"
944 | _MINDSDB_PORT: "47335"
945 | _MINDSDB_DATABASE: "mindsdb_test"
946 | _YUGABYTEDB_DATABASE: "yugabyte"
947 | _YUGABYTEDB_PORT: "5433"
948 | _YUGABYTEDB_LOADBALANCE: "false"
949 | _ORACLE_SERVER_NAME: "FREEPDB1"
950 |
```