Documentation ¶
Overview ¶
Example (SqlFunction) ¶
// Example shows how to do a function call with binds // For testing, check if database tests are disabled if oci8.TestDisableDatabase { fmt.Println(3) return } oci8.OCI8Driver.Logger = log.New(os.Stderr, "oci8 ", log.Ldate|log.Ltime|log.LUTC|log.Llongfile) var openString string // [username/[password]@]host[:port][/service_name][?param1=value1&...¶mN=valueN] if len(oci8.TestUsername) > 0 { if len(oci8.TestPassword) > 0 { openString = oci8.TestUsername + "/" + oci8.TestPassword + "@" } else { openString = oci8.TestUsername + "@" } } openString += oci8.TestHostValid // A normal simple Open to localhost would look like: // db, err := sql.Open("oci8", "127.0.0.1") // For testing, need to use additional variables db, err := sql.Open("oci8", openString) if err != nil { fmt.Printf("Open error is not nil: %v", err) return } if db == nil { fmt.Println("db is nil") return } // defer close database defer func() { err = db.Close() if err != nil { fmt.Println("Close error is not nil:", err) } }() number := int64(2) query := ` declare function ADD_ONE(p_number INTEGER) return INTEGER as begin return p_number + 1; end ADD_ONE; begin :num1 := ADD_ONE(:num1); end;` ctx, cancel := context.WithTimeout(context.Background(), 55*time.Second) _, err = db.ExecContext(ctx, query, sql.Out{Dest: &number, In: true}) cancel() if err != nil { fmt.Println("ExecContext error is not nil:", err) return } if number != 3 { fmt.Println("number != 3") return } fmt.Println(number)
Output: 3
Example (SqlInsert) ¶
// Example shows how to do a single insert // For testing, check if database tests are disabled if oci8.TestDisableDatabase || oci8.TestDisableDestructive { fmt.Println(1) return } oci8.OCI8Driver.Logger = log.New(os.Stderr, "oci8 ", log.Ldate|log.Ltime|log.LUTC|log.Llongfile) var openString string // [username/[password]@]host[:port][/service_name][?param1=value1&...¶mN=valueN] if len(oci8.TestUsername) > 0 { if len(oci8.TestPassword) > 0 { openString = oci8.TestUsername + "/" + oci8.TestPassword + "@" } else { openString = oci8.TestUsername + "@" } } openString += oci8.TestHostValid // A normal simple Open to localhost would look like: // db, err := sql.Open("oci8", "127.0.0.1") // For testing, need to use additional variables db, err := sql.Open("oci8", openString) if err != nil { fmt.Printf("Open error is not nil: %v", err) return } if db == nil { fmt.Println("db is nil") return } // defer close database defer func() { err = db.Close() if err != nil { fmt.Println("Close error is not nil:", err) } }() // create table tableName := "E_INSERT_" + oci8.TestTimeString query := "create table " + tableName + " ( A INTEGER )" ctx, cancel := context.WithTimeout(context.Background(), 55*time.Second) _, err = db.ExecContext(ctx, query) cancel() if err != nil { fmt.Println("ExecContext error is not nil:", err) return } // insert row var result sql.Result query = "insert into " + tableName + " ( A ) values (:1)" ctx, cancel = context.WithTimeout(context.Background(), 55*time.Second) result, err = db.ExecContext(ctx, query, 1) cancel() if err != nil { fmt.Println("ExecContext error is not nil:", err) return } // can see number of RowsAffected if wanted var rowsAffected int64 rowsAffected, err = result.RowsAffected() if err != nil { fmt.Println("RowsAffected error is not nil:", err) return } // drop table query = "drop table " + tableName ctx, cancel = context.WithTimeout(context.Background(), 55*time.Second) _, err = db.ExecContext(ctx, query) cancel() if err != nil { fmt.Println("ExecContext error is not nil:", err) return } fmt.Println(rowsAffected)
Output: 1
Example (SqlManyInserts) ¶
// Example shows how to do a many inserts // For testing, check if database tests are disabled if oci8.TestDisableDatabase || oci8.TestDisableDestructive { fmt.Println(3) return } oci8.OCI8Driver.Logger = log.New(os.Stderr, "oci8 ", log.Ldate|log.Ltime|log.LUTC|log.Llongfile) var openString string // [username/[password]@]host[:port][/service_name][?param1=value1&...¶mN=valueN] if len(oci8.TestUsername) > 0 { if len(oci8.TestPassword) > 0 { openString = oci8.TestUsername + "/" + oci8.TestPassword + "@" } else { openString = oci8.TestUsername + "@" } } openString += oci8.TestHostValid // A normal simple Open to localhost would look like: // db, err := sql.Open("oci8", "127.0.0.1") // For testing, need to use additional variables db, err := sql.Open("oci8", openString) if err != nil { fmt.Printf("Open error is not nil: %v", err) return } if db == nil { fmt.Println("db is nil") return } // defer close database defer func() { err = db.Close() if err != nil { fmt.Println("Close error is not nil:", err) } }() // create table tableName := "E_MANY_INSERT_" + oci8.TestTimeString query := "create table " + tableName + " ( A INTEGER )" ctx, cancel := context.WithTimeout(context.Background(), 55*time.Second) _, err = db.ExecContext(ctx, query) cancel() if err != nil { fmt.Println("ExecContext error is not nil:", err) return } // prepare insert query statement var stmt *sql.Stmt query = "insert into " + tableName + " ( A ) values (:1)" ctx, cancel = context.WithTimeout(context.Background(), 55*time.Second) stmt, err = db.PrepareContext(ctx, query) cancel() if err != nil { fmt.Println("PrepareContext error is not nil:", err) return } // insert 3 rows for i := 0; i < 3; i++ { ctx, cancel = context.WithTimeout(context.Background(), 55*time.Second) _, err = stmt.ExecContext(ctx, i) cancel() if err != nil { stmt.Close() fmt.Println("ExecContext error is not nil:", err) return } } // close insert query statement err = stmt.Close() if err != nil { fmt.Println("Close error is not nil:", err) return } // select count/number of rows var rows *sql.Rows query = "select count(1) from " + tableName ctx, cancel = context.WithTimeout(context.Background(), 55*time.Second) defer cancel() rows, err = db.QueryContext(ctx, query) if err != nil { fmt.Println("QueryContext error is not nil:", err) return } if !rows.Next() { fmt.Println("no Next rows") return } var count int64 err = rows.Scan(&count) if err != nil { fmt.Println("Scan error is not nil:", err) return } if count != 3 { fmt.Println("count not equal to 3") return } if rows.Next() { fmt.Println("has Next rows") return } err = rows.Err() if err != nil { fmt.Println("Err error is not nil:", err) return } err = rows.Close() if err != nil { fmt.Println("Close error is not nil:", err) return } // drop table query = "drop table " + tableName ctx, cancel = context.WithTimeout(context.Background(), 55*time.Second) _, err = db.ExecContext(ctx, query) cancel() if err != nil { fmt.Println("ExecContext error is not nil:", err) return } fmt.Println(count)
Output: 3
Example (SqlRowid) ¶
// Example shows a few ways to get rowid // For testing, check if database tests are disabled if oci8.TestDisableDatabase || oci8.TestDisableDestructive { fmt.Println("done") return } oci8.OCI8Driver.Logger = log.New(os.Stderr, "oci8 ", log.Ldate|log.Ltime|log.LUTC|log.Llongfile) var openString string // [username/[password]@]host[:port][/service_name][?param1=value1&...¶mN=valueN] if len(oci8.TestUsername) > 0 { if len(oci8.TestPassword) > 0 { openString = oci8.TestUsername + "/" + oci8.TestPassword + "@" } else { openString = oci8.TestUsername + "@" } } openString += oci8.TestHostValid // A normal simple Open to localhost would look like: // db, err := sql.Open("oci8", "127.0.0.1") // For testing, need to use additional variables db, err := sql.Open("oci8", openString) if err != nil { fmt.Printf("Open error is not nil: %v", err) return } if db == nil { fmt.Println("db is nil") return } // defer close database defer func() { err = db.Close() if err != nil { fmt.Println("Close error is not nil:", err) } }() // create table tableName := "E_ROWID_" + oci8.TestTimeString query := "create table " + tableName + " ( A INTEGER )" ctx, cancel := context.WithTimeout(context.Background(), 55*time.Second) _, err = db.ExecContext(ctx, query) cancel() if err != nil { fmt.Println("ExecContext error is not nil:", err) return } // insert row and get rowid from returning var rowid1 string // rowid will be put into here var result sql.Result query = "insert into " + tableName + " ( A ) values (:1) returning rowid into :rowid1" ctx, cancel = context.WithTimeout(context.Background(), 55*time.Second) result, err = db.ExecContext(ctx, query, 1, sql.Named("rowid1", sql.Out{Dest: &rowid1})) cancel() if err != nil { fmt.Println("ExecContext error is not nil:", err) return } // get rowid from LastInsertId var rowid2 string // rowid will be put into here var id int64 id, err = result.LastInsertId() if err != nil { fmt.Println("LastInsertId error is not nil:", err) return } rowid2 = oci8.GetLastInsertId(id) // select rowid var rowid3 string // rowid will be put into here var rows *sql.Rows query = "select rowid from " + tableName ctx, cancel = context.WithTimeout(context.Background(), 55*time.Second) defer cancel() rows, err = db.QueryContext(ctx, query) if err != nil { fmt.Println("QueryContext error is not nil:", err) return } if !rows.Next() { fmt.Println("no Next rows") return } err = rows.Scan(&rowid3) if err != nil { fmt.Println("Scan error is not nil:", err) return } if rows.Next() { fmt.Println("has Next rows") return } err = rows.Err() if err != nil { fmt.Println("Err error is not nil:", err) return } err = rows.Close() if err != nil { fmt.Println("Close error is not nil:", err) return } // drop table query = "drop table " + tableName ctx, cancel = context.WithTimeout(context.Background(), 55*time.Second) _, err = db.ExecContext(ctx, query) cancel() if err != nil { fmt.Println("ExecContext error is not nil:", err) return } if len(rowid1) != len(rowid2) || len(rowid2) != len(rowid3) { fmt.Println("rowid len is not equal", rowid1, rowid2, rowid3) return } fmt.Println("done")
Output: done
Example (SqlSelect) ¶
// Example shows how to do a basic select // For testing, check if database tests are disabled if oci8.TestDisableDatabase { fmt.Println(1) return } oci8.OCI8Driver.Logger = log.New(os.Stderr, "oci8 ", log.Ldate|log.Ltime|log.LUTC|log.Llongfile) var openString string // [username/[password]@]host[:port][/service_name][?param1=value1&...¶mN=valueN] if len(oci8.TestUsername) > 0 { if len(oci8.TestPassword) > 0 { openString = oci8.TestUsername + "/" + oci8.TestPassword + "@" } else { openString = oci8.TestUsername + "@" } } openString += oci8.TestHostValid // A normal simple Open to localhost would look like: // db, err := sql.Open("oci8", "127.0.0.1") // For testing, need to use additional variables db, err := sql.Open("oci8", openString) if err != nil { fmt.Printf("Open error is not nil: %v", err) return } if db == nil { fmt.Println("db is nil") return } // defer close database defer func() { err = db.Close() if err != nil { fmt.Println("Close error is not nil:", err) } }() var rows *sql.Rows ctx, cancel := context.WithTimeout(context.Background(), 55*time.Second) defer cancel() rows, err = db.QueryContext(ctx, "select 1 from dual") if err != nil { fmt.Println("QueryContext error is not nil:", err) return } if !rows.Next() { fmt.Println("no Next rows") return } dest := make([]interface{}, 1) destPointer := make([]interface{}, 1) destPointer[0] = &dest[0] err = rows.Scan(destPointer...) if err != nil { fmt.Println("Scan error is not nil:", err) return } if len(dest) != 1 { fmt.Println("len dest != 1") return } data, ok := dest[0].(float64) if !ok { fmt.Println("dest type not float64") return } if data != 1 { fmt.Println("data not equal to 1") return } if rows.Next() { fmt.Println("has Next rows") return } err = rows.Err() if err != nil { fmt.Println("Err error is not nil:", err) return } err = rows.Close() if err != nil { fmt.Println("Close error is not nil:", err) return } fmt.Println(data)
Output: 1
Index ¶
- Variables
- func GetLastInsertId(id int64) string
- func NewConnector(hosts ...string) driver.Connector
- func QueryEscape(s string) string
- func QueryUnescape(s string) (string, error)
- type DSN
- type EscapeError
- type OCI8Conn
- func (conn *OCI8Conn) Begin() (driver.Tx, error)
- func (conn *OCI8Conn) BeginTx(ctx context.Context, txOptions driver.TxOptions) (driver.Tx, error)
- func (conn *OCI8Conn) Close() error
- func (conn *OCI8Conn) Ping(ctx context.Context) error
- func (conn *OCI8Conn) Prepare(query string) (driver.Stmt, error)
- func (conn *OCI8Conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error)
- type OCI8Connector
- type OCI8DriverStruct
- type OCI8Result
- type OCI8Rows
- func (rows *OCI8Rows) Close() error
- func (rows *OCI8Rows) ColumnTypeDatabaseTypeName(i int) string
- func (rows *OCI8Rows) ColumnTypeLength(i int) (length int64, ok bool)
- func (rows *OCI8Rows) ColumnTypeNullable(i int) (nullable, ok bool)
- func (rows *OCI8Rows) ColumnTypeScanType(i int) reflect.Type
- func (rows *OCI8Rows) Columns() []string
- func (rows *OCI8Rows) Next(dest []driver.Value) error
- type OCI8Stmt
- func (stmt *OCI8Stmt) CheckNamedValue(namedValue *driver.NamedValue) error
- func (stmt *OCI8Stmt) Close() error
- func (stmt *OCI8Stmt) Exec(values []driver.Value) (driver.Result, error)
- func (stmt *OCI8Stmt) ExecContext(ctx context.Context, namedValues []driver.NamedValue) (driver.Result, error)
- func (stmt *OCI8Stmt) NumInput() int
- func (stmt *OCI8Stmt) Query(values []driver.Value) (driver.Rows, error)
- func (stmt *OCI8Stmt) QueryContext(ctx context.Context, namedValues []driver.NamedValue) (driver.Rows, error)
- type OCI8Tx
- type Values
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrOCISuccessWithInfo is OCI_SUCCESS_WITH_INFO ErrOCISuccessWithInfo = errors.New("OCI_SUCCESS_WITH_INFO") // ErrNoRowid is result has no rowid ErrNoRowid = errors.New("result has no rowid") // OCI8Driver is the sql driver OCI8Driver = &OCI8DriverStruct{ Logger: log.New(ioutil.Discard, "", 0), } )
Functions ¶
func GetLastInsertId ¶
GetLastInsertId returns rowid from LastInsertId
func NewConnector ¶
NewConnector returns a new database connector
func QueryEscape ¶
QueryEscape escapes the string so it can be safely placed inside a URL query.
func QueryUnescape ¶
QueryUnescape does the inverse transformation of QueryEscape, converting %AB into the byte 0xAB and '+' into ' ' (space). It returns an error if any % is not followed by two hexadecimal digits.
Types ¶
type DSN ¶
type DSN struct { Connect string Username string Password string Location *time.Location // contains filtered or unexported fields }
DSN is Oracle Data Source Name
func ParseDSN ¶
ParseDSN parses a DSN used to connect to Oracle
It expects to receive a string in the form:
[username/[password]@]host[:port][/service_name][?param1=value1&...¶mN=valueN]
Connection timeout can be set in the Oracle files: sqlnet.ora as SQLNET.OUTBOUND_CONNECT_TIMEOUT or tnsnames.ora as CONNECT_TIMEOUT
Supported parameters are:
loc - the time location for timezone when reading/writing Go time/Oracle date
isolation - the isolation level that can be set to: READONLY, SERIALIZABLE, or DEFAULT
prefetch_rows - the number of top level rows to be prefetched. Defaults to 0. A 0 means unlimited rows.
prefetch_memory - the max memory for top level rows to be prefetched. Defaults to 4096. A 0 means unlimited memory.
questionph - when true, enables question mark placeholders. Defaults to false. (uses strconv.ParseBool to check for true)
type EscapeError ¶
type EscapeError string
EscapeError for invalid escape
func (EscapeError) Error ¶
func (e EscapeError) Error() string
Error returns string for invalid URL escape
type OCI8Conn ¶
type OCI8Conn struct {
// contains filtered or unexported fields
}
OCI8Conn is Oracle connection
type OCI8Connector ¶
OCI8Connector is the sql driver connector
func (*OCI8Connector) Driver ¶
func (oci8Connector *OCI8Connector) Driver() driver.Driver
Driver returns the OCI8 driver
type OCI8DriverStruct ¶
type OCI8DriverStruct struct { // Logger is used to log connection ping errors, defaults to discard // To log set it to something like: log.New(os.Stderr, "oci8 ", log.Ldate|log.Ltime|log.LUTC|log.Llongfile) Logger *log.Logger }
OCI8DriverStruct is Oracle driver struct
type OCI8Result ¶
type OCI8Result struct {
// contains filtered or unexported fields
}
OCI8Result is Oracle result
func (*OCI8Result) LastInsertId ¶
func (result *OCI8Result) LastInsertId() (int64, error)
LastInsertId returns last inserted ID
func (*OCI8Result) RowsAffected ¶
func (result *OCI8Result) RowsAffected() (int64, error)
RowsAffected returns rows affected
type OCI8Rows ¶
type OCI8Rows struct {
// contains filtered or unexported fields
}
OCI8Rows is Oracle rows
func (*OCI8Rows) ColumnTypeDatabaseTypeName ¶
ColumnTypeDatabaseTypeName implement RowsColumnTypeDatabaseTypeName.
func (*OCI8Rows) ColumnTypeLength ¶
ColumnTypeLength returns column length
func (*OCI8Rows) ColumnTypeNullable ¶
ColumnTypeNullable implement RowsColumnTypeNullable.
func (*OCI8Rows) ColumnTypeScanType ¶
ColumnTypeScanType implement RowsColumnTypeScanType.
type OCI8Stmt ¶
type OCI8Stmt struct {
// contains filtered or unexported fields
}
OCI8Stmt is Oracle statement
func (*OCI8Stmt) CheckNamedValue ¶
func (stmt *OCI8Stmt) CheckNamedValue(namedValue *driver.NamedValue) error
CheckNamedValue checks a named value
func (*OCI8Stmt) ExecContext ¶
func (stmt *OCI8Stmt) ExecContext(ctx context.Context, namedValues []driver.NamedValue) (driver.Result, error)
ExecContext run a exec query with context
func (*OCI8Stmt) QueryContext ¶
func (stmt *OCI8Stmt) QueryContext(ctx context.Context, namedValues []driver.NamedValue) (driver.Rows, error)
QueryContext runs a query with context
type OCI8Tx ¶
type OCI8Tx struct {
// contains filtered or unexported fields
}
OCI8Tx is Oracle transaction
type Values ¶
Values maps a string key to a list of values. It is typically used for query parameters and form values. Unlike in the http.Header map, the keys in a Values map are case-sensitive.
func ParseQuery ¶
ParseQuery parses the URL-encoded query string and returns a map listing the values specified for each key. ParseQuery always returns a non-nil map containing all the valid query parameters found; err describes the first decoding error encountered, if any.
func (Values) Add ¶
Add adds the value to key. It appends to any existing values associated with key.
func (Values) Encode ¶
Encode encodes the values into “URL encoded” form ("bar=baz&foo=quux") not sorted by key