some how-to and why documentation
This commit is contained in:
parent
3f9a0298ab
commit
665549e1bc
164
dialects/oci8/README.md
Normal file
164
dialects/oci8/README.md
Normal file
@ -0,0 +1,164 @@
|
||||
# oci8 dialect
|
||||
|
||||
- [oci8 dialect](#oci8-dialect)
|
||||
- [Overview](#overview)
|
||||
- [Install oracle client (required by go module)](#install-oracle-client-required-by-go-module)
|
||||
- [Install the Module](#install-the-module)
|
||||
- [Basic Test](#basic-test)
|
||||
- [Running Oracle in Docker](#running-oracle-in-docker)
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
This document covers everything you need to install/configure/run to get the oci8 dialect up and running.
|
||||
|
||||
You'll find some additional documentation on various challenges and design decisions for the dialect in [doc.go](./doc.go)
|
||||
|
||||
## Install oracle client (required by go module)
|
||||
|
||||
Download instaclients from: https://www.oracle.com/database/technologies/instant-client/macos-intel-x86-downloads.html
|
||||
|
||||
You need the basic, sqlplus and sdk packages.
|
||||
|
||||
Move the zip instaclient files to `~/Library/Caches/Homebrew`
|
||||
|
||||
Install the clients with brew
|
||||
|
||||
```
|
||||
$ brew tap InstantClientTap/instantclient
|
||||
$ brew install instantclient-basic
|
||||
$ brew install instantclient-sqlplus
|
||||
$ brew install instantclient-sdk
|
||||
```
|
||||
|
||||
## Install the Module
|
||||
|
||||
```
|
||||
go get github.com/mattn/go-oci8
|
||||
```
|
||||
|
||||
Install pkg-config via brew
|
||||
|
||||
```
|
||||
$ brew install pkg-config
|
||||
```
|
||||
|
||||
Create `/usr/local/lib/pkgconfig/oci8.pc`
|
||||
Contents:
|
||||
```
|
||||
prefixdir=/usr/local/lib
|
||||
libdir=${prefixdir}
|
||||
includedir=${prefixdir}/sdk/include
|
||||
|
||||
Name: OCI
|
||||
Description: Oracle database driver
|
||||
Version: 12.2
|
||||
Libs: -L${libdir} -lclntsh
|
||||
Cflags: -I${includedir}%
|
||||
```
|
||||
|
||||
Test pkg-config for oci8
|
||||
```
|
||||
$ pkg-config --cflags --libs oci8
|
||||
-I/usr/local/lib/sdk/include -L/usr/local/lib -lclntsh
|
||||
```
|
||||
|
||||
### Basic Test
|
||||
|
||||
Once you've got Oracle up and running and you've created the gorm user with appropriate privs, try to run:
|
||||
```
|
||||
# chdir to the oci8 dialect's directory:
|
||||
$ cd dialect/oci8
|
||||
|
||||
# run a basic connection test
|
||||
$ go test -v -run Test_Connection
|
||||
=== RUN Test_Connection
|
||||
--- PASS: Test_Connection (0.06s)
|
||||
connection_test.go:29: The date is: 2020-02-14T20:09:37Z
|
||||
PASS
|
||||
ok github.com/jinzhu/gorm/dialects/oci8 1.609s
|
||||
```
|
||||
|
||||
## Running Oracle in Docker
|
||||
|
||||
Download the Oracle Express Edition version 18c (xe) Linux rpm from oracle.com
|
||||
|
||||
```
|
||||
git clone https://github.com/oracle/docker-images.git
|
||||
```
|
||||
|
||||
copy binary you downloaded
|
||||
```
|
||||
cp ~/Dowloads/<image-name> ./18.4.0
|
||||
```
|
||||
build image
|
||||
```
|
||||
./buildDockerImage.sh -x -v 18.4.0
|
||||
```
|
||||
start container
|
||||
```
|
||||
docker run -dit --name oracledb \
|
||||
-p 1521:1521 -p 5500:5500 -p 8080:8080 \
|
||||
-e ORACLE_PWD=oracle \
|
||||
-v $HOME/oracle/oradata:/opt/oracle/oradata \
|
||||
oracle/database:18.4.0-xe
|
||||
```
|
||||
|
||||
Check logs and wait for oracle to be ready…
|
||||
```
|
||||
❯ docker logs -f oracledb
|
||||
The Oracle base remains unchanged with value /opt/oracle
|
||||
#########################
|
||||
DATABASE IS READY TO USE!
|
||||
#########################
|
||||
```
|
||||
|
||||
Connect via sqlplus as sysdba via container
|
||||
```
|
||||
❯ docker exec -it oracledb sqlplus sys/oracle@localhost:1521/XE as sysdba
|
||||
|
||||
SQL*Plus: Release 18.0.0.0.0 - Production on Mon Feb 10 16:33:44 2020
|
||||
Version 18.4.0.0.0
|
||||
|
||||
Copyright (c) 1982, 2018, Oracle. All rights reserved.
|
||||
|
||||
|
||||
Connected to:
|
||||
Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production
|
||||
Version 18.4.0.0.0
|
||||
|
||||
SQL>
|
||||
```
|
||||
|
||||
Connect via sqlplus as system user via container:
|
||||
```
|
||||
docker exec -it oracledb sqlplus system/oracle@localhost:1521/XE
|
||||
|
||||
SQL*Plus: Release 18.0.0.0.0 - Production on Mon Feb 10 17:08:04 2020
|
||||
Version 18.4.0.0.0
|
||||
|
||||
Copyright (c) 1982, 2018, Oracle. All rights reserved.
|
||||
|
||||
Last Successful login time: Mon Feb 10 2020 17:07:07 +00:00
|
||||
|
||||
Connected to:
|
||||
Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production
|
||||
Version 18.4.0.0.0
|
||||
|
||||
SQL>
|
||||
```
|
||||
|
||||
create a gorm user
|
||||
```
|
||||
docker exec -it oracledb sqlplus system/oracle@localhost:1521/XE
|
||||
|
||||
SQL>
|
||||
-- creating user in the default PDB
|
||||
ALTER SESSION SET CONTAINER = XEPDB1;
|
||||
create user gorm identified by gorm;
|
||||
-- we need some privs
|
||||
GRANT CONNECT, RESOURCE, DBA TO gorm;
|
||||
GRANT CREATE SESSION TO gorm;
|
||||
GRANT UNLIMITED TABLESPACE TO gorm;
|
||||
```
|
||||
|
48
dialects/oci8/doc.go
Normal file
48
dialects/oci8/doc.go
Normal file
@ -0,0 +1,48 @@
|
||||
package oci8
|
||||
|
||||
/*
|
||||
|
||||
Understanding Oracle
|
||||
|
||||
It's a bit different than the other RDBMS databases and I'll just try to
|
||||
hightlight a few of the important ones the dialect has to deal with:
|
||||
|
||||
1. Oracle upper cases all non-quoted identifiers. That means the dialect
|
||||
has to decide what to do:
|
||||
1. quote all identifiers which would require developers to quote every
|
||||
identifer they passed in a string to gorm.
|
||||
2. only quote identifers that conflict with reserved words and leave all
|
||||
other identifiers unquoted, which means Oracle will automatically
|
||||
upper case them. This would allow developers to pass unquoted
|
||||
identifiers in strings they passed to gorm and make the experience
|
||||
align better with the other dialects.
|
||||
We chose option #2.
|
||||
|
||||
This design decision has the following side affects:
|
||||
a. you must be case insensitive when matching column names, like in
|
||||
the Scope.scan function
|
||||
b. Devs will have to escape reserved words when they reference them
|
||||
in things like: First(&CreditCard{}, `"number" = ?`)
|
||||
|
||||
|
||||
2. Oracle handles last inserted id a bit differently, and requires a sql.Out
|
||||
parameter to return the value. Since Oracle parameters are positional, you
|
||||
need to know how many other bind variables there are before adding the returning
|
||||
clause. (see createCallback() )
|
||||
|
||||
3. Oracle doesn't let you specify "AS <tablename> " when selecting a count
|
||||
from a dynamic table, so you just omit it. (see Scope.count() )
|
||||
|
||||
4. Oracle handles foreign keys a bit differently:
|
||||
A. REFERENCES is implicit
|
||||
B. ON UPDATE is not supported
|
||||
(see scope.addForeignKey() )
|
||||
|
||||
5. Searching a blob requires using a function from the dbms_lob package like
|
||||
instr() and specifying the offset and number of matches.
|
||||
(see oci8.SearchBlob() )
|
||||
|
||||
6 Trailing semicolons are not allowed at the end of Oracle sql statements
|
||||
(so they were removed in the unit tests)
|
||||
|
||||
*/
|
Loading…
x
Reference in New Issue
Block a user