go-ora Oracle Driver

repository·master·Indexed 21 days ago

https://github.com/sijms/go-ora

A pure Go implementation of an Oracle database driver compatible with the standard database/sql package, eliminating the need for Oracle Client libraries or CGO. It supports Oracle server 10.2+ (v2) and Oracle 23ai (v3), featuring support for LOBs, User-Defined Types (UDT), Oracle Wallets via io.Reader, Advanced Queuing (AQ), and Oracle 23ai Vector and JSON types.

Tokens
29.2K
Snippets
113
Records
146
Agent score
75%

What's inside go-ora

  1. Wallet Reader implementation details and constraints

    master

    When using the io.Reader wallet loading feature, keep the following in mind:

    • Supported Files: This feature supports cwallet.sso files only.
    • Concurrency: The implementation is concurrency-safe. Each OracleConnector maintains its own wallet configuration. You can safely use different wallets in different goroutines without interference or global state modification.
    • Immediate Read: The wallet data is read immediately when WithWallet() is called.
    • Compatibility: Backward compatibility is maintained; file path-based loading via URL parameters still works as expected.
  2. How User-Defined Types (UDT) work

    master

    To use Oracle UDTs in Go, define a corresponding Go struct with udt tags. You must register the type with the driver before executing queries that use it.

    // 1. Define the Go struct matching the Oracle OBJECT
    type Address struct {
        Street string `udt:"STREET"`
        City   string `udt:"CITY"`
    }
    
    // 2. Register the type with the driver
    if drv, ok := db.Driver().(*go_ora.OracleDriver); ok {
        err := drv.Conn.RegisterType("SCHEMA", "ADDRESS_TYPE", Address{})
    }
    
    // 3. Use in queries
    var addr Address
    rows, err := db.Query("SELECT address_type('123 Main', 'NYC') FROM dual")
    rows.Scan(&addr)
  3. Run tests for all issues or specific features

    master

    You can execute tests for the entire issue folder or isolate specific issues/features for testing using these methods:

    To test all issues: Run the tests for the entire folder.

    To test only specific issues or features:

    1. Create a new folder.
    2. Copy global_var.go into the new folder.
    3. Copy the required test files into the new folder.
    4. Run the tests specifically on that folder.
  4. Configure environment variables for go-ora tests

    master

    When running tests or demonstrations within the v3/TestIssues directory, you must define the following environment variables to establish a connection to your Oracle instance:

    • USER: Your database username.
    • PASSWORD: Your database password.
    • SERVER: The IP address or server name of the Oracle host.
    • PORT: The connection port (defaults to 1521).
    • SERVICE: The Oracle service name.
    • SSL: Set to TRUE if using a secure connection, otherwise false.
    • WALLET: The file path to your Oracle wallet (required if SSL=TRUE).
  5. Load Oracle Wallets using io.Reader

    master

    Instead of providing a file path, you can load Oracle Wallets (cwallet.sso) using any object that implements the io.Reader interface. This allows you to source wallets from embedded files, remote HTTP sources, S3, Secrets Managers (like HashiCorp Vault), or in-memory data.

    When using WithWallet(reader), the wallet data is read immediately. You can safely close the reader after the WithWallet() call returns.

    import (
        "database/sql"
        "os"
    
        go_ora "github.com/sijms/go-ora/v2"
    )
    
    func main() {
        // Create a new connector - isolated from other connections
        connector := go_ora.NewConnector(
            "oracle://user:pass@server:1521/service?SSL=enable",
        )
    
        // Open wallet file (could be any io.Reader)
        walletFile, _ := os.Open("/path/to/cwallet.sso")
        defer walletFile.Close()
    
        // Load wallet from reader - data is read immediately
        connector.WithWallet(walletFile)
    
        // Use sql.OpenDB with the connector
        db := sql.OpenDB(connector)
        defer db.Close()
    }
  6. Run tests for go-ora issues

    master

    To verify specific issues or features within the v3/TestIssues directory, you can use the following approaches:

    Test all issues

    Run the tests for the entire folder to execute all available test cases.

    Test specific issues or features

    If you want to isolate a specific issue or feature for testing:

    1. Create a new folder.
    2. Copy global_var.go into the new folder.
    3. Copy the specific required test files into the new folder.
    4. Run the tests specifically on that new folder.
  7. Configure environment variables for go-ora

    master

    When running tests or using certain connection configurations, you can define the following environment variables to specify your Oracle connection details:

    • USER: The database username.
    • PASSWORD: The database password.
    • SERVER: The IP address or server name.
    • PORT: The port number (defaults to 1521).
    • SERVICE: The Oracle service name.
    • SSL: Set to TRUE if the connection is secure, otherwise false.
    • WALLET: The path to the wallet directory (required if SSL is set to TRUE).
  8. Quick Start with go-ora

    master

    To use go-ora, import the driver with a blank identifier _ "github.com/sijms/go-ora/v2" and use the standard database/sql package. Connection strings follow the oracle://user:pass@server:port/service format.

    package main
    
    import (
        "database/sql"
        "fmt"
        "log"
    
        _ "github.com/sijms/go-ora/v2"
    )
    
    func main() {
        connStr := "oracle://user:pass@server:1521/service"
        db, err := sql.Open("oracle", connStr)
        if err != nil {
            log.Fatal(err)
        }
        defer db.Close()
    
        if err := db.Ping(); err != nil {
            log.Fatal(err)
        }
    
        var version string
        err = db.QueryRow("SELECT * FROM v$version").Scan(&version)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(version)
    }
  9. Migrate from v2 to v3

    master

    When upgrading from v2 to v3, note the following breaking changes:

    • Import Path: Change github.com/sijms/go-ora/v2 to github.com/sijms/go-ora/v3.
    • Types: Types moved from the driver package to github.com/sijms/go-ora/v3/types.
    • AQ: Use aq.CreateQueue instead of dbms.NewAQ.
    • UDT: Use go_ora.RegisterType with struct tags instead of manual setup.
    • Session Params: Use go_ora.AddSessionParam / DelSessionParam instead of URL options.
  10. Quick Start with go-ora v3

    master

    To use go-ora with the standard database/sql package, import the driver with a blank identifier and use the oracle driver name with a connection URL. The URL format is oracle://user:pass@host:port/service.

    package main
    
    import (
        "database/sql"
        "fmt"
        "log"
    
        _ "github.com/sijms/go-ora/v3"
    )
    
    func main() {
        db, err := sql.Open("oracle", "oracle://user:pass@host:1521/service")
        if err != nil {
            log.Fatal(err)
        }
        defer db.Close()
    
        if err := db.Ping(); err != nil {
            log.Fatal(err)
        }
    
        fmt.Println("Connected to Oracle")
    }