Skip to content
This repository has been archived by the owner on Jun 4, 2024. It is now read-only.

oracle: new connector #437

Merged
merged 5 commits into from
May 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ matrix:
- os: osx
osx_image: xcode9.0
language: node_js
node_js: "6"
node_js: "8"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to confirm. Once this is moved in we will need to use NodeJS 8? Will earlier versions work? Not an issue just want to know.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The oracle connector won't work in electron and yarn will refuse to install.

If you force yarn to ignore the node version (yarn install --ignore-engines), then Falcon seems to work (I mean everything I tried, except the Oracle connector).

env:
- ELECTRON_CACHE=$HOME/.cache/electron
- ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
Expand Down
153 changes: 115 additions & 38 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,48 @@ Note that this section targets contributors and those who wish to set up and run

If you're interested in using the distributed App, [download the latest release.](https://github.com/plotly/falcon-sql-client/releases)


## Prerequisites
It is recommended to use node v6.12 with the latest electron-builder

## Install
Falcon development requires node v8 and yarn v1. Some connectors (e.g. the
Oracle connector) have additional requirements (see further below the section on
testing).

Start by cloning the repo via git:

```bash
git clone https://github.com/plotly/falcon-sql-client falcon-sql-client
```

And then install dependencies with **yarn**.
## Install

```bash
```sh
$ git clone https://github.com/plotly/falcon-sql-client falcon-sql-client
$ cd falcon-sql-client
$ yarn install
```


## Build and Run the Electron App

First, build the native dependencies against Electron:
```sh
$ yarn run rebuild:modules:electron
```

*Note: See package.json for the version of node that is required*
Then:

## Run as an Electron App
Run the app with
```bash
```sh
$ yarn run build
$ yarn run start
```

## Run as a Server

Build and run the app:
```bash
$ yarn install
$ yarn run heroku-postbuild
$ yarn run start-headless
```
## Build and Run the Web App

Build (after it was already built for electron desktop) and run the app:
```bash
If, last time, Falcon was built as an Electron app, then the native modules need
rebuilding against Node:
```sh
$ yarn run rebuild:modules:node
```

To build and run the web app:
```sh
$ yarn run heroku-postbuild
$ yarn run start-headless
```
Expand All @@ -62,7 +64,8 @@ CORS_ALLOWED_ORIGINS:

The database connector runs as a server by default as part of [Plotly On-Premise](https://plot.ly/products/on-premise). On Plotly On-Premise, every user who has access to the on-premise server also has access to the database connector, no extra installation or SSL configuration is necessary. If you would like to try out Plotly On-Premise at your company, please [get in touch with our team](https://plotly.typeform.com/to/seG7Vb), we'd love to help you out.

## Run as a docker image

## Run as a Docker Container

Build and run the docker image:
```
Expand All @@ -74,8 +77,11 @@ The web app will be accessible in your browser at `http://localhost:9494`.

See the [Dockerfile](https://github.com/plotly/falcon-sql-client/blob/master/Dockerfile) for more information.


## Developing

*([TODO] This section needs updating)*

Run watchers for the electron main process, the web bundle (the front-end), and the headless-bundle:
```bash
$ yarn run watch-main
Expand All @@ -89,7 +95,7 @@ $ yarn run watch-web
$ yarn run watch-headless
```

Then, view the the app in the electron window with:
Then, view the app in the electron window with:

```bash
$ yarn run dev
Expand All @@ -106,20 +112,79 @@ $ yarn start

and in your web browser by visiting http://localhost:9494


## Testing

There are unit tests for the nodejs backend and integration tests to test the flow of the app.
Falcon is tested in three ways:

Run unit tests:
```bash
$ yarn run test-unit-all
- backend tests: stored under `test/backend` and run by `yarn run test-unit-all`
- frontend tests: stored under `test/app` and run by `yarn run test-jest`
- integration tests: stored in `test/integration_test.js` and run by `yarn run test-e2e`

In some cases, we also provide `Dockerfile`s to build containers with a sample
database for testing. These can be found under `test/docker`.


### IBM DB2 Test Database

In folder `test/docker/ibmdb2`, we provide a `Dockerfile` to setup an IBM DB2
Express database for testing.

To build the docker image, run `yarn run docker:db2:build`.

And to start the docker container, run `yarn run docker:db2:start`.

More details can be found in `test/docker/ibmdb2/README.md`.


### Oracle Test Database

In folder `test/docker/oracle`, we provide a `Dockerfile` to setup an Oracle
Express database for testing.

To build the docker image, run `yarn run docker:oracle:build`.

And to start the docker container, run `yarn run docker:oracle:start`.

More details can be found in `test/docker/oracle/README.md`.


#### Installation of Oracle Client Libraries

Unlike IBM DB2's case and as of this writing, the Oracle bindings for Node.js,
[oracledb](https://www.npmjs.com/package/oracledb), are incomplete and users are
required to create an account on
[Oracle](https://login.oracle.com/mysso/signon.jsp) before downloading the
missing Oracle Client libraries.

The installation procedure is very well documented
[here](https://github.com/oracle/node-oracledb/blob/master/INSTALL.md#instructions).

The procedure for Ubuntu:

1. Install requirements: `sudo apt-get -qq update && sudo apt-get --no-install-recommends -qq install alien bc libaio1`
2. Create an account on [Oracle](https://login.oracle.com/mysso/signon.jsp)
3. Download the Oracle Instant Client from [here](http://download.oracle.com/otn/linux/oracle11g/xe/oracle-xe-11.2.0-1.0.x86_64.rpm.zip)
4. Unzip `rpm` package: `unzip oracle-xe-11.2.0-1.0.x86_64.rpm.zip`
5. Convert `rpm` package into `deb`: `alien oracle-xe-11.2.0-1.0.x86_64.rpm`
6. Install `deb` package: `sudo dpkg -i oracle-instantclient12.2-basiclite_12.2.0.1.0-2_amd64.deb`


#### Running the Unit Tests for Oracle Connector

First, open a terminal and start the container that runs test Oracle database:
```sh
$ yarn run docker:oracle:start
```
and wait until the message `Ready` is shown.

Run integration tests:
```bash
$ yarn run test-e2e
Then, open another terminal and run:
```sh
$ export LD_LIBRARY_PATH=/usr/lib/oracle/12.2/client64/lib:$LD_LIBRARY_PATH
$ yarn run test-unit-oracle
```


## Builds and Releases

- Update package.json with the new semver version
Expand All @@ -129,13 +194,25 @@ $ yarn run test-e2e

Builds are uploaded to https://github.com/plotly/falcon-sql-client/releases.


## Troubleshooting
The Falcon Configuration information is installed in the user's home directory.
For example Unix and Mac (~/.plotly/connector) and for Windows (%userprofile%\.plotly\connector\). If you have tried the install
process and the app is still not running, this may be related to some corrupted
configuration files. You can try removing the existing configuration files and then
restarting the build process

```bash
Falcon keeps stores its configuration and logs in a folder under the user's home
directory:
- `%USERPROFILE%\.plotly\connector` (in Windows)
- `~/.plotly/connector` (in Mac and Linux)

While developing a new connector, a common issue is that Falcon's configuration
gets corrupted. This often leads to a failure at start up. Until we address this
issue in more user-friendly manner (issue #342), the solution is to delete
Falcon's configuration folder.

In Windows:
```sh
rmdir /s %USERPROFILE%\.plotly\connector
```

In Mac and Linux:
```sh
rm -rf ~/.plotly/connector/
```
```
17 changes: 9 additions & 8 deletions app/components/Settings/ConnectButton/ConnectButton.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ export default class ConnectButton extends Component {
}

/**
* @returns {boolean} true if waiting for a response to a connection request
*/
isConnecting() {
return this.props.connectRequest.status === 'loading';
* @returns {boolean} true if waiting for a response to a connection request
*/
isConnecting() {
return this.props.connectRequest.status === 'loading';
}

/**
* @returns {boolean} true if successfully connected to database
*/
isConnected() {
const status = Number(this.props.connectRequest.status);
return (status >= 200 || status < 300);
return (status >= 200 && status < 300);
}

/**
Expand All @@ -56,7 +56,7 @@ export default class ConnectButton extends Component {
*/
isSaved() {
const status = Number(this.props.saveConnectionsRequest.status);
return (status >= 200 || status < 300);
return (status >= 200 && status < 300);
}

/**
Expand Down Expand Up @@ -89,18 +89,19 @@ export default class ConnectButton extends Component {
buttonClick = connect;

const connectErrorMessage = pathOr(
null, ['content', 'error'], connectRequest
null, ['content', 'error', 'message'], connectRequest
);
const saveErrorMessage = pathOr(
null, ['content', 'error', 'message'], saveConnectionsRequest
);
const genericErrorMessage = 'Hm... had trouble connecting.';
const errorMessage = connectErrorMessage || saveErrorMessage || genericErrorMessage;
const errorMessage = String(connectErrorMessage || saveErrorMessage || genericErrorMessage);
error = <div className={'errorMessage'}>{errorMessage}</div>;

} else if (this.isConnected() && this.isSaved()) {
buttonText = 'Save changes';
buttonClick = connect;

} else {
buttonText = 'Connect';
buttonClick = connect;
Expand Down
2 changes: 2 additions & 0 deletions app/components/Settings/Preview/TableTree.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class TableTree extends Component {
return getPathNames(connectionObject.url)[2];
case DIALECTS.CSV:
return connectionObject.label || connectionObject.id || connectionObject.database;
case DIALECTS.ORACLE:
return connectionObject.connectionString;
default:
return connectionObject.database;
}
Expand Down
1 change: 1 addition & 0 deletions app/components/Settings/Preview/code-editor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ export default class CodeEditor extends React.Component {
[DIALECTS.MYSQL]: 'text/x-mysql',
[DIALECTS.SQLITE]: 'text/x-sqlite',
[DIALECTS.MARIADB]: 'text/x-mariadb',
[DIALECTS.ORACLE]: 'text/x-plsql',
[DIALECTS.POSTGRES]: 'text/x-pgsql',
[DIALECTS.REDSHIFT]: 'text/x-pgsql',
[DIALECTS.MSSQL]: 'text/x-mssql'
Expand Down
2 changes: 2 additions & 0 deletions app/components/Settings/Tabs/Tab.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export default class ConnectionTab extends Component {
label = `Elasticsearch (${connectionObject.host})`;
} else if (connectionObject.dialect === DIALECTS.ATHENA) {
label = `Athena (${connectionObject.database})`;
} else if (connectionObject.dialect === DIALECTS.ORACLE) {
label = `${connectionObject.connectionString}`;
} else if (connectionObject.dialect === DIALECTS.SQLITE) {
label = connectionObject.storage;
} else if (connectionObject.dialect === DIALECTS.DATA_WORLD) {
Expand Down
26 changes: 26 additions & 0 deletions app/constants/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {concat} from 'ramda';
export const DIALECTS = {
MYSQL: 'mysql',
MARIADB: 'mariadb',
ORACLE: 'oracle',
POSTGRES: 'postgres',
REDSHIFT: 'redshift',
ELASTICSEARCH: 'elasticsearch',
Expand All @@ -23,6 +24,7 @@ export const DIALECTS = {
export const SQL_DIALECTS_USING_EDITOR = [
'mysql',
'mariadb',
'oracle',
'postgres',
'redshift',
'mssql',
Expand Down Expand Up @@ -139,6 +141,22 @@ export const CONNECTION_CONFIG = {
}
]
),
[DIALECTS.ORACLE]: [
{'label': 'Username', 'value': 'username', 'type': 'text'},
{'label': 'Password', 'value': 'password', 'type': 'password'},
{
'label': 'Connection',
'value': 'connectionString',
'type': 'text',
'description': `
An Easy Connect string,
a Net Service Name from a local 'tnsnames.ora' file or an external naming service,
an SID of a local Oracle database instance,
or leave empty to connect to the local default database.
See https://oracle.github.io/node-oracledb/doc/api.html#connectionstrings for examples.
`
}
],
[DIALECTS.POSTGRES]: commonSqlOptions,
[DIALECTS.REDSHIFT]: commonSqlOptions,
[DIALECTS.SQLITE]: [
Expand Down Expand Up @@ -245,6 +263,7 @@ export const LOGOS = {
[DIALECTS.CSV]: 'images/csv-logo.png',
[DIALECTS.IBM_DB2]: 'images/ibmdb2-logo.png',
[DIALECTS.REDSHIFT]: 'images/redshift-logo.png',
[DIALECTS.ORACLE]: 'images/oracle-logo.png',
[DIALECTS.POSTGRES]: 'images/postgres-logo.png',
[DIALECTS.ELASTICSEARCH]: 'images/elastic-logo.png',
[DIALECTS.MYSQL]: 'images/mysql-logo.png',
Expand All @@ -263,6 +282,8 @@ export function PREVIEW_QUERY(connection, table, elasticsearchIndex) {
return 'SELECT TOP 1000 * FROM ?';
case DIALECTS.IBM_DB2:
return `SELECT * FROM ${table} FETCH FIRST 1000 ROWS ONLY`;
case DIALECTS.ORACLE:
return `SELECT * FROM ${table} WHERE ROWNUM <= 1000`;
case DIALECTS.APACHE_IMPALA:
case DIALECTS.APACHE_SPARK:
case DIALECTS.MYSQL:
Expand Down Expand Up @@ -382,6 +403,11 @@ export const SAMPLE_DBS = {
host: 'db2.test.plotly.host',
dialect: DIALECTS.IBM_DB2
},
[DIALECTS.ORACLE]: {
username: 'XDB',
password: 'xdb',
connectionString: 'localhost/XE'
},
[DIALECTS.POSTGRES]: {
username: 'masteruser',
password: 'connecttoplotly',
Expand Down
Binary file added app/images/oracle-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: 0.4.{build}

environment:
matrix:
- nodejs_version: 6
- nodejs_version: 8
POSTGRES_PATH: C:\Program Files\PostgreSQL\9.6

platform:
Expand Down
Loading