diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3c6e209..78dba59 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,11 +16,25 @@ jobs: build-darwin: strategy: matrix: + goarch: [amd64, arm64] + variant: [full, lite, minimal] include: - goarch: amd64 runner: macos-15-intel - goarch: arm64 runner: macos-latest + - variant: full + tags: "" + suffix: "" + cgo: "1" + - variant: lite + tags: noduckdb,nosnowflake,noracle + suffix: lite- + cgo: "0" + - variant: minimal + tags: noduckdb,nosnowflake,noracle,noclickhouse,nofirebird,nosqlserver + suffix: minimal- + cgo: "0" runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v4 @@ -33,19 +47,35 @@ jobs: - name: Build env: - CGO_ENABLED: 1 + CGO_ENABLED: ${{ matrix.cgo }} GOOS: darwin GOARCH: ${{ matrix.goarch }} run: | mkdir -p dist - go build -buildvcs=false -ldflags="-s -w -X main.Version=${{ github.ref_name }}" -o dist/${{ env.APP_NAME }}-darwin-${{ matrix.goarch }} ./cmd/squix + go build -buildvcs=false -ldflags="-s -w -X main.Version=${{ github.ref_name }}" -tags "${{ matrix.tags }}" -o dist/${{ env.APP_NAME }}-${{ matrix.suffix }}darwin-${{ matrix.goarch }} ./cmd/squix - uses: actions/upload-artifact@v4 with: - name: darwin-${{ matrix.goarch }} - path: dist/${{ env.APP_NAME }}-darwin-${{ matrix.goarch }} + name: darwin-${{ matrix.goarch }}-${{ matrix.variant }} + path: dist/${{ env.APP_NAME }}-${{ matrix.suffix }}darwin-${{ matrix.goarch }} build-windows: + strategy: + matrix: + variant: [full, lite, minimal] + include: + - variant: full + tags: "" + suffix: "" + cgo: "1" + - variant: lite + tags: noduckdb,nosnowflake,noracle + suffix: lite- + cgo: "0" + - variant: minimal + tags: noduckdb,nosnowflake,noracle,noclickhouse,nofirebird,nosqlserver + suffix: minimal- + cgo: "0" runs-on: windows-latest steps: - uses: actions/checkout@v4 @@ -58,27 +88,39 @@ jobs: - name: Build env: - CGO_ENABLED: 1 + CGO_ENABLED: ${{ matrix.cgo }} GOOS: windows GOARCH: amd64 run: | mkdir dist - go build -buildvcs=false -ldflags="-s -w -X main.Version=${{ github.ref_name }}" -o dist/${{ env.APP_NAME }}-windows-amd64.exe ./cmd/squix + go build -buildvcs=false -ldflags="-s -w -X main.Version=${{ github.ref_name }}" -tags "${{ matrix.tags }}" -o dist/${{ env.APP_NAME }}-${{ matrix.suffix }}windows-amd64.exe ./cmd/squix - uses: actions/upload-artifact@v4 with: - name: windows-amd64 - path: dist/${{ env.APP_NAME }}-windows-amd64.exe + name: windows-amd64-${{ matrix.variant }} + path: dist/${{ env.APP_NAME }}-${{ matrix.suffix }}windows-amd64.exe build-linux: strategy: matrix: + goarch: [amd64, arm64] + variant: [full, lite, minimal] include: - - goarch: amd64 - packages: "" - goarch: arm64 + variant: full cc: aarch64-linux-gnu-gcc - packages: "gcc-aarch64-linux-gnu g++-aarch64-linux-gnu" + - variant: full + tags: "" + suffix: "" + cgo: "1" + - variant: lite + tags: noduckdb,nosnowflake,noracle + suffix: lite- + cgo: "0" + - variant: minimal + tags: noduckdb,nosnowflake,noracle,noclickhouse,nofirebird,nosqlserver + suffix: minimal- + cgo: "0" runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -90,23 +132,23 @@ jobs: go-version: ${{ env.GO_VERSION }} - name: Install cross-compiler - if: matrix.packages != '' - run: sudo apt-get update && sudo apt-get install -y ${{ matrix.packages }} + if: matrix.goarch == 'arm64' && matrix.variant == 'full' + run: sudo apt-get update && sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu - name: Build env: - CGO_ENABLED: 1 + CGO_ENABLED: ${{ matrix.cgo }} GOOS: linux GOARCH: ${{ matrix.goarch }} CC: ${{ matrix.cc }} run: | mkdir -p dist - go build -buildvcs=false -ldflags="-s -w -X main.Version=${{ github.ref_name }}" -o dist/${{ env.APP_NAME }}-linux-${{ matrix.goarch }} ./cmd/squix + go build -buildvcs=false -ldflags="-s -w -X main.Version=${{ github.ref_name }}" -tags "${{ matrix.tags }}" -o dist/${{ env.APP_NAME }}-${{ matrix.suffix }}linux-${{ matrix.goarch }} ./cmd/squix - uses: actions/upload-artifact@v4 with: - name: linux-${{ matrix.goarch }} - path: dist/${{ env.APP_NAME }}-linux-${{ matrix.goarch }} + name: linux-${{ matrix.goarch }}-${{ matrix.variant }} + path: dist/${{ env.APP_NAME }}-${{ matrix.suffix }}linux-${{ matrix.goarch }} create-release: needs: diff --git a/Makefile b/Makefile index 9ce2547..e27b0f4 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,21 @@ -.PHONY: test test-verbose lint fmt vet build ci clean +.PHONY: test test-verbose lint fmt vet build build-lite build-minimal ci clean BINARY=squix VERSION=$(shell git describe --tags --always --dirty 2>/dev/null || echo dev) -LDFLAGS=-ldflags "-X main.Version=$(VERSION)" +LDFLAGS=-ldflags "-s -w -X main.Version=$(VERSION)" + +LITE_TAGS=noduckdb,nosnowflake,noracle +MINIMAL_TAGS=noduckdb,nosnowflake,noracle,noclickhouse,nofirebird,nosqlserver build: go build $(LDFLAGS) -o $(BINARY) ./cmd/squix +build-lite: + go build $(LDFLAGS) -tags "$(LITE_TAGS)" -o $(BINARY)-lite ./cmd/squix + +build-minimal: + go build $(LDFLAGS) -tags "$(MINIMAL_TAGS)" -o $(BINARY)-minimal ./cmd/squix + test: go test ./... @@ -25,4 +34,4 @@ vet: ci: fmt vet lint test clean: - rm -f $(BINARY) + rm -f $(BINARY) $(BINARY)-lite $(BINARY)-minimal diff --git a/README.md b/README.md index 7477cdc..11a33e2 100644 --- a/README.md +++ b/README.md @@ -81,10 +81,7 @@ go build -o squix ./cmd/squix ``` The squix binary will be available in the root project directory -DuckDB requires CGO and is included in the default build. To build without DuckDB: -```bash -CGO_ENABLED=0 go build -o squix ./cmd/squix -``` +See [Build variants](docs/features.md#build-variants) for the full/lite/minimal builds and which drivers each one includes.
diff --git a/build-local.sh b/build-local.sh index c474e93..91d5465 100755 --- a/build-local.sh +++ b/build-local.sh @@ -9,6 +9,9 @@ BUILD_DIR="./dist" NATIVE_OS=$(go env GOOS) NATIVE_ARCH=$(go env GOARCH) +LITE_TAGS="noduckdb,nosnowflake,noracle" +MINIMAL_TAGS="noduckdb,nosnowflake,noracle,noclickhouse,nofirebird,nosqlserver" + echo "Building $APP_NAME version $VERSION" echo "==================================" @@ -17,54 +20,81 @@ rm -rf "$BUILD_DIR" mkdir -p "$BUILD_DIR" FULL_DRIVERS=() -LIMITED_DRIVERS=() -# Build with appropriate CGO setting based on target arch +# Build with appropriate CGO setting based on target arch. +# Variants: +# full - every driver (DuckDB needs CGO; only the native platform gets CGO=1) +# lite - no DuckDB/Snowflake/Oracle, works without CGO +# minimal - lite minus ClickHouse/Firebird/SQL Server (postgres, mysql, sqlite) build_platform() { local platform=$1 local goos=$2 local goarch=$3 - local output=$4 + local name_suffix=$4 echo "" - echo "Building $platform..." + echo "Building $platform ($name_suffix)..." + + local tags="" + if [ "$name_suffix" = "lite" ]; then tags=$LITE_TAGS; fi + if [ "$name_suffix" = "minimal" ]; then tags=$MINIMAL_TAGS; fi + + local output_name="${APP_NAME}-${platform}" + if [ "$name_suffix" != "full" ]; then + output_name="${APP_NAME}-${name_suffix}-${platform}" + fi + if [ "$goos" = "windows" ]; then + output_name="${output_name}.exe" + fi + + local cgo=0 + if [ "$name_suffix" = "full" ] && [ "$goos" = "$NATIVE_OS" ] && [ "$goarch" = "$NATIVE_ARCH" ]; then + cgo=1 + fi + + local extra_args=() + if [ -n "$tags" ]; then + extra_args=(-tags "$tags") + fi - if [ "$goos" = "$NATIVE_OS" ] && [ "$goarch" = "$NATIVE_ARCH" ]; then - CGO_ENABLED=1 GOOS=$goos GOARCH=$goarch go build -ldflags="-s -w -X main.Version=$VERSION" -o "$output" ./cmd/squix + CGO_ENABLED=$cgo GOOS=$goos GOARCH=$goarch go build \ + -ldflags="-s -w -X main.Version=$VERSION" \ + "${extra_args[@]}" \ + -o "$BUILD_DIR/$output_name" ./cmd/squix + + if [ "$cgo" = "1" ]; then FULL_DRIVERS+=("$platform") - else - CGO_ENABLED=0 GOOS=$goos GOARCH=$goarch go build -ldflags="-s -w -X main.Version=$VERSION" -o "$output" ./cmd/squix - LIMITED_DRIVERS+=("$platform") fi - echo "✓ Built $platform successfully" + echo "✓ Built $output_name successfully" } -# Build Linux AMD64 -build_platform "Linux AMD64" "linux" "amd64" "$BUILD_DIR/${APP_NAME}-linux-amd64" +for suffix in full lite minimal; do + # Build Linux AMD64 + build_platform "linux-amd64" "linux" "amd64" "$suffix" -# Build Linux ARM64 -build_platform "Linux ARM64" "linux" "arm64" "$BUILD_DIR/${APP_NAME}-linux-arm64" + # Build Linux ARM64 + build_platform "linux-arm64" "linux" "arm64" "$suffix" -# Build Windows AMD64 -build_platform "Windows AMD64" "windows" "amd64" "$BUILD_DIR/${APP_NAME}-windows-amd64.exe" + # Build Windows AMD64 + build_platform "windows-amd64" "windows" "amd64" "$suffix" -# Build macOS AMD64 -build_platform "macOS AMD64" "darwin" "amd64" "$BUILD_DIR/${APP_NAME}-darwin-amd64" + # Build macOS AMD64 + build_platform "darwin-amd64" "darwin" "amd64" "$suffix" -# Build macOS ARM64 -build_platform "macOS ARM64" "darwin" "arm64" "$BUILD_DIR/${APP_NAME}-darwin-arm64" + # Build macOS ARM64 + build_platform "darwin-arm64" "darwin" "arm64" "$suffix" +done echo "" echo "==================================" echo "Build complete!" -echo "==================================" echo "" -echo "Full driver support (CGO_ENABLED=1):" +echo "Full driver support (CGO_ENABLED=1, native platform only):" for p in "${FULL_DRIVERS[@]}"; do echo " ✓ $p"; done echo "" -echo "Limited driver support - no DuckDB (CGO_ENABLED=0):" -for p in "${LIMITED_DRIVERS[@]}"; do echo " ✓ $p"; done +echo "DuckDB is not included in non-native full builds (CGO_ENABLED=0):" +echo " use the lite/minimal variants for those platforms instead" echo "" # Create source code archives @@ -78,17 +108,7 @@ echo "" echo "Generating checksums for all artifacts..." find "$BUILD_DIR" -type f -exec sha256sum {} + | sed "s|$BUILD_DIR/||" > "$BUILD_DIR/checksums.txt" echo "✓ Checksums generated in $BUILD_DIR/checksums.txt" - -echo "" -echo "==================================" -echo "All tasks complete!" -echo "==================================" -echo "" -echo "Binaries location: $BUILD_DIR/" -echo "Source archives location: $BUILD_DIR/source/" -echo "Checksum file: $BUILD_DIR/checksums.txt" echo "" ls -lh "$BUILD_DIR/" echo "" ls -lh "$BUILD_DIR/source/" -echo "" diff --git a/cmd/squix/app.go b/cmd/squix/app.go index 073d798..6bd1f3c 100644 --- a/cmd/squix/app.go +++ b/cmd/squix/app.go @@ -32,6 +32,11 @@ func (a *App) Run() { os.Exit(0) } + if os.Args[1] == "--drivers" { + a.handleDrivers() + os.Exit(0) + } + command := os.Args[1] switch command { case "init": @@ -125,6 +130,11 @@ func (a *App) printUsage() { "List database connections", ), ) + fmt.Println( + " squix --drivers " + styles.Faint.Render( + "List database drivers in this build", + ), + ) fmt.Println( " squix disconnect " + styles.Faint.Render( "Disconnect from current database", diff --git a/cmd/squix/drivers.go b/cmd/squix/drivers.go new file mode 100644 index 0000000..fe7b3d0 --- /dev/null +++ b/cmd/squix/drivers.go @@ -0,0 +1,22 @@ +package main + +import ( + "fmt" + + "github.com/eduardofuncao/squix/internal/db" + "github.com/eduardofuncao/squix/internal/styles" +) + +func (a *App) handleDrivers() { + fmt.Println(styles.Title.Render("Drivers in this build")) + for _, t := range db.KnownDBTypes() { + if db.IsDriverBuilt(t) { + fmt.Println(" " + styles.Success.Render("✓") + " " + t) + } else { + msg := "✗ " + t + " — not included (excluded via -tags " + db.DriverBuildTag(t) + ")" + fmt.Println(" " + styles.Faint.Render(msg)) + } + } + fmt.Println() + fmt.Println(styles.Faint.Render("Rebuild without the tag, or install the full squix build, to enable excluded drivers.")) +} diff --git a/docs/features.md b/docs/features.md index aa073a8..c7dc168 100644 --- a/docs/features.md +++ b/docs/features.md @@ -161,3 +161,31 @@ squix@mydb> status | `list`, `ls`, `\l` | List queries or connections | Multi-line: type SQL without trailing `;` to continue. End with `;` or press Enter on blank line to execute. + +## Build variants + +Squix ships in three variants so you can trade driver coverage for binary size and portability. DuckDB is the only driver needing CGO; the slimmer variants build without it. + +| Variant | Excluded drivers | Included drivers | +|---------|------------------|------------------| +| full | none | postgres, mysql, sqlite, sqlserver, clickhouse, oracle, firebird, duckdb, snowflake | +| lite | duckdb, snowflake, oracle | postgres, mysql, sqlite, sqlserver, clickhouse, firebird | +| minimal | duckdb, snowflake, oracle, clickhouse, firebird, sqlserver | postgres, mysql, sqlite | + +Check what your binary supports: + +```bash +squix --drivers +``` + +Excluded drivers report which build tag removes them, e.g. `not included (excluded via -tags noduckdb)`. Rebuild without the tag, or install the full build, to enable them. + +Build a variant from source: + +```bash +make build # full +make build-lite # lite (-tags "noduckdb,nosnowflake,noracle") +make build-minimal # minimal (-tags "noduckdb,nosnowflake,noracle,noclickhouse,nofirebird,nosqlserver") +``` + +Or via Nix flakes: `squix.packages..default` / `.lite` / `.minimal`. Release pages carry all three per platform (`squix--`, `squix-lite--`, `squix-minimal--`); the Homebrew formula and nixpkgs package track the full build. diff --git a/flake.nix b/flake.nix index 6c75612..ae5cddd 100644 --- a/flake.nix +++ b/flake.nix @@ -12,35 +12,60 @@ pkgs = import nixpkgs { inherit system; }; - in - { - packages.default = pkgs.buildGoModule { - pname = "squix"; - version = "0.5.3-beta"; # update when cutting a release + + version = "0.5.4-beta"; # update when cutting a release + + mkSquix = { pname, tags ? [ ] }: pkgs.buildGoModule { + inherit pname version tags; src = ./.; # Run: nix build .#default 2>&1 | grep "got:" to get real hash vendorHash = "sha256-kSv3VAQi+qdT29gZAjLmHauItaMFd9NG7bdRtQE1MZo="; - enableCGO = true; - - # Native dependencies (none needed - all drivers are pure Go) + # DuckDB is the only driver needing CGO; lite/minimal exclude it. + enableCGO = ! (builtins.elem "noduckdb" tags); # Linker flags ldflags = [ "-s" "-w" - "-X main.Version=${self.packages.${system}.default.version}" + "-X main.Version=${version}" ]; + postInstall = pkgs.lib.optionalString (pname != "squix") '' + mv "$out/bin/squix" "$out/bin/${pname}" + ''; + meta = with pkgs.lib; { description = "Minimal CLI tool for managing SQL queries across multiple databases"; homepage = "https://github.com/eduardofuncao/squix"; license = licenses.mit; - mainProgram = "squix"; + mainProgram = pname; }; }; + in + { + packages.default = mkSquix { pname = "squix"; }; + + # No DuckDB, Snowflake, Oracle + packages.lite = mkSquix { + pname = "squix-lite"; + tags = [ "noduckdb" "nosnowflake" "noracle" ]; + }; + + # Only Postgres, MySQL, SQLite + packages.minimal = mkSquix { + pname = "squix-minimal"; + tags = [ + "noduckdb" + "nosnowflake" + "noracle" + "noclickhouse" + "nofirebird" + "nosqlserver" + ]; + }; devShells.default = pkgs.mkShell { buildInputs = with pkgs; [ diff --git a/internal/db/clickhouse_connection.go b/internal/db/clickhouse_connection.go index 3ba98f3..5720ea4 100644 --- a/internal/db/clickhouse_connection.go +++ b/internal/db/clickhouse_connection.go @@ -1,3 +1,5 @@ +//go:build !noclickhouse + package db import ( @@ -9,6 +11,12 @@ import ( _ "github.com/ClickHouse/clickhouse-go/v2" ) +func init() { + registerDriver(func(name, connStr string) (DatabaseConnection, error) { + return NewClickHouseConnection(name, EncodeUserinfo(connStr)) + }, "clickhouse") +} + type ClickHouseConnection struct { *BaseConnection db *sql.DB diff --git a/internal/db/connection_factory.go b/internal/db/connection_factory.go index 0ef6ccc..8b84d98 100644 --- a/internal/db/connection_factory.go +++ b/internal/db/connection_factory.go @@ -1,30 +1,75 @@ package db -import ( - "fmt" -) +import "fmt" + +type driverCtor func(name, connString string) (DatabaseConnection, error) + +// Excluded drivers never appear here: each _connection.go registers +// itself from init() behind a build tag. +var builtDrivers = map[string]driverCtor{} + +func registerDriver(ctor driverCtor, aliases ...string) { + for _, alias := range aliases { + builtDrivers[alias] = ctor + } +} + +var canonicalTypes = []string{ + "postgres", + "mysql", + "sqlite", + "sqlserver", + "clickhouse", + "oracle", + "firebird", + "duckdb", + "snowflake", +} + +var excludedByTag = map[string]string{ + "postgres": "nopostgres", + "postgresql": "nopostgres", + "mysql": "nomysql", + "mariadb": "nomysql", + "sqlite": "nosqlite", + "sqlite3": "nosqlite", + "sqlserver": "nosqlserver", + "mssql": "nosqlserver", + "clickhouse": "noclickhouse", + "oracle": "noracle", + "godror": "noracle", + "firebird": "nofirebird", + "interbase": "nofirebird", + "duckdb": "noduckdb", + "snowflake": "nosnowflake", +} func CreateConnection(name, dbType, connString string) (DatabaseConnection, error) { - switch dbType { - case "postgres", "postgresql": - return NewPostgresConnection(name, EncodeUserinfo(connString)) - case "mysql", "mariadb": - return NewMySQLConnection(name, connString) - case "sqlite", "sqlite3": - return NewSQLiteConnection(name, connString) - case "sqlserver", "mssql": - return NewSQLServerConnection(name, EncodeUserinfo(connString)) - case "duckdb": - return NewDuckDBConnection(name, connString) - case "clickhouse": - return NewClickHouseConnection(name, EncodeUserinfo(connString)) - case "godror", "oracle": - return NewOracleConnection(name, EncodeUserinfo(connString)) - case "firebird", "interbase": - return NewFirebirdConnection(name, EncodeUserinfo(connString)) - case "snowflake": - return NewSnowflakeConnection(name, EncodeUserinfo(connString)) - default: - return nil, fmt.Errorf("driver not implemented for %s", dbType) + if ctor, ok := builtDrivers[dbType]; ok { + return ctor(name, connString) } + if _, known := excludedByTag[dbType]; known { + return nil, NotIncludedError(dbType) + } + return nil, fmt.Errorf("driver not implemented for %s", dbType) +} + +func NotIncludedError(dbType string) error { + return fmt.Errorf( + "%s driver is not included in this build (excluded via -tags %s); use a full squix build or rebuild without the tag", + dbType, excludedByTag[dbType], + ) +} + +func KnownDBTypes() []string { + return canonicalTypes +} + +func IsDriverBuilt(dbType string) bool { + _, ok := builtDrivers[dbType] + return ok +} + +func DriverBuildTag(dbType string) string { + return excludedByTag[dbType] } diff --git a/internal/db/duckdb_connection.go b/internal/db/duckdb_connection.go index c3201c0..a5d52b3 100644 --- a/internal/db/duckdb_connection.go +++ b/internal/db/duckdb_connection.go @@ -1,4 +1,4 @@ -//go:build cgo +//go:build cgo && !noduckdb package db @@ -10,6 +10,12 @@ import ( _ "github.com/duckdb/duckdb-go/v2" ) +func init() { + registerDriver(func(name, connStr string) (DatabaseConnection, error) { + return NewDuckDBConnection(name, connStr) + }, "duckdb") +} + type DuckDBConnection struct { *BaseConnection db *sql.DB diff --git a/internal/db/duckdb_connection_stub.go b/internal/db/duckdb_connection_stub.go deleted file mode 100644 index 559dab4..0000000 --- a/internal/db/duckdb_connection_stub.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build !cgo - -package db - -import "fmt" - -type DuckDBConnection struct { - *BaseConnection -} - -func NewDuckDBConnection(name, connStr string) (*DuckDBConnection, error) { - return nil, fmt.Errorf("duckdb driver not available: build with CGO_ENABLED=1 to enable") -} - -func (d *DuckDBConnection) GetUniqueConstraints(tableName string) ([]string, error) { - return nil, fmt.Errorf("duckdb driver not available") -} diff --git a/internal/db/firebird_connection.go b/internal/db/firebird_connection.go index c547509..b134901 100644 --- a/internal/db/firebird_connection.go +++ b/internal/db/firebird_connection.go @@ -1,3 +1,5 @@ +//go:build !nofirebird + package db import ( @@ -8,6 +10,12 @@ import ( _ "github.com/nakagami/firebirdsql" ) +func init() { + registerDriver(func(name, connStr string) (DatabaseConnection, error) { + return NewFirebirdConnection(name, EncodeUserinfo(connStr)) + }, "firebird", "interbase") +} + type FirebirdConnection struct { *BaseConnection db *sql.DB diff --git a/internal/db/inference.go b/internal/db/inference.go index eb99ec3..84ca0f0 100644 --- a/internal/db/inference.go +++ b/internal/db/inference.go @@ -50,17 +50,13 @@ func InferDBType(connString string) string { return "" } -// GetSupportedDBTypes returns a list of all supported database types. +// GetSupportedDBTypes returns the drivers compiled into this binary. func GetSupportedDBTypes() []string { - return []string{ - "postgres", - "mysql", - "sqlite", - "sqlserver", - "clickhouse", - "oracle", - "firebird", - "duckdb", - "snowflake", + var supported []string + for _, t := range canonicalTypes { + if IsDriverBuilt(t) { + supported = append(supported, t) + } } + return supported } diff --git a/internal/db/mysql_connection.go b/internal/db/mysql_connection.go index c656704..e2dc008 100644 --- a/internal/db/mysql_connection.go +++ b/internal/db/mysql_connection.go @@ -1,3 +1,5 @@ +//go:build !nomysql + package db import ( @@ -8,6 +10,12 @@ import ( _ "github.com/go-sql-driver/mysql" ) +func init() { + registerDriver(func(name, connStr string) (DatabaseConnection, error) { + return NewMySQLConnection(name, connStr) + }, "mysql", "mariadb") +} + type MySQLConnection struct { *BaseConnection db *sql.DB diff --git a/internal/db/oracle_connection.go b/internal/db/oracle_connection.go index 3404741..5a724de 100644 --- a/internal/db/oracle_connection.go +++ b/internal/db/oracle_connection.go @@ -1,3 +1,5 @@ +//go:build !noracle + package db import ( @@ -8,6 +10,12 @@ import ( _ "github.com/sijms/go-ora/v2" ) +func init() { + registerDriver(func(name, connStr string) (DatabaseConnection, error) { + return NewOracleConnection(name, EncodeUserinfo(connStr)) + }, "oracle", "godror") +} + type OracleConnection struct { *BaseConnection db *sql.DB diff --git a/internal/db/postgres_connection.go b/internal/db/postgres_connection.go index aaf4393..bff8437 100644 --- a/internal/db/postgres_connection.go +++ b/internal/db/postgres_connection.go @@ -1,3 +1,5 @@ +//go:build !nopostgres + package db import ( @@ -8,6 +10,12 @@ import ( _ "github.com/lib/pq" ) +func init() { + registerDriver(func(name, connStr string) (DatabaseConnection, error) { + return NewPostgresConnection(name, EncodeUserinfo(connStr)) + }, "postgres", "postgresql") +} + type PostgresConnection struct { *BaseConnection db *sql.DB diff --git a/internal/db/snowflake_connection.go b/internal/db/snowflake_connection.go index dd6b686..a45ed8d 100644 --- a/internal/db/snowflake_connection.go +++ b/internal/db/snowflake_connection.go @@ -1,3 +1,5 @@ +//go:build !nosnowflake + package db import ( @@ -13,6 +15,12 @@ import ( "github.com/youmark/pkcs8" ) +func init() { + registerDriver(func(name, connStr string) (DatabaseConnection, error) { + return NewSnowflakeConnection(name, EncodeUserinfo(connStr)) + }, "snowflake") +} + type SnowflakeConnection struct { *BaseConnection db *sql.DB diff --git a/internal/db/sqlite_connection.go b/internal/db/sqlite_connection.go index 0d7a553..41e1709 100644 --- a/internal/db/sqlite_connection.go +++ b/internal/db/sqlite_connection.go @@ -1,3 +1,5 @@ +//go:build !nosqlite + package db import ( @@ -8,6 +10,12 @@ import ( _ "modernc.org/sqlite" ) +func init() { + registerDriver(func(name, connStr string) (DatabaseConnection, error) { + return NewSQLiteConnection(name, connStr) + }, "sqlite", "sqlite3") +} + type SQLiteConnection struct { *BaseConnection db *sql.DB diff --git a/internal/db/sqlserver_connection.go b/internal/db/sqlserver_connection.go index c2285fc..dac6985 100644 --- a/internal/db/sqlserver_connection.go +++ b/internal/db/sqlserver_connection.go @@ -1,3 +1,5 @@ +//go:build !nosqlserver + package db import ( @@ -8,6 +10,12 @@ import ( _ "github.com/microsoft/go-mssqldb" ) +func init() { + registerDriver(func(name, connStr string) (DatabaseConnection, error) { + return NewSQLServerConnection(name, EncodeUserinfo(connStr)) + }, "sqlserver", "mssql") +} + type SQLServerConnection struct { *BaseConnection db *sql.DB @@ -431,7 +439,7 @@ func (s *SQLServerConnection) ApplyRowLimit(sql string, limit int) string { return sql } - // Don't apply row limit if select-statement contains distinct + // Don't apply row limit if select-statement contains distinct if strings.Contains(trimmedSQL, "DISTINCT") { return sql }