Skip to content

Commit

Permalink
Restructuring Database.Connection to allow for database specific ty…
Browse files Browse the repository at this point in the history
…pes. (#3632)

- Added `databases`, `database`, `set_database`.
- Added `schemas`, `schema`, `set_schema`.
- Added `table_types`,
- Added `tables`.
- Moved the vast majority of the connection work into a lower level `JDBC_Connection` object.
- `Connection` represents the standard API for database connections and provides a base JDBC implementation.
- `SQLite_Connection` has the `Connection` API but with custom `databases` and `schemas` methods for SQLite.
- `Postgres_Connection` has the `Connection` API but with custom `set_database`, `databases`, `set_schema` and `schemas` methods for Postgres.
- Updated `Redshift` - no public API change.
  • Loading branch information
jdunkerley authored Sep 7, 2022
1 parent 551100a commit 2b425f8
Show file tree
Hide file tree
Showing 27 changed files with 1,038 additions and 461 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@
- [Implemented `Table.take` and `Table.drop` for the in-memory backend.][3647]
- [Implemented specialized storage for the in-memory Table.][3673]
- [Implemented `Table.distinct` for the in-memory backend.][3684]
- [Added `databases`, `schemas`, `tables` support to database Connection.][3632]

[debug-shortcuts]:
https://github.com/enso-org/enso/blob/develop/app/gui/docs/product/shortcuts.md#debug
Expand Down Expand Up @@ -293,6 +294,7 @@
[3617]: https://github.com/enso-org/enso/pull/3617
[3628]: https://github.com/enso-org/enso/pull/3628
[3629]: https://github.com/enso-org/enso/pull/3629
[3632]: https://github.com/enso-org/enso/pull/3632
[3641]: https://github.com/enso-org/enso/pull/3641
[3643]: https://github.com/enso-org/enso/pull/3643
[3644]: https://github.com/enso-org/enso/pull/3644
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ from Standard.Base import all

from Standard.Base.Data.Numbers import Parse_Error_Data

import Standard.Database.Data.Dialect
import Standard.Database.Connection.Connection
from Standard.Database.Connection.Credentials import Credentials_Data, Credentials
import Standard.Database.Internal.Postgres.Postgres_Connection
import Standard.Database.Connection.Connection_Options

from Standard.Database.Connection.Credentials import Credentials, Credentials_Data

import Standard.Database.Connection.SSL_Mode
from Standard.Database.Connection.SSL_Mode import all

import Standard.Database.Connection.Client_Certificate

import Standard.Database.Internal.Postgres.Pgpass

polyglot java import org.postgresql.Driver
Expand All @@ -20,10 +23,11 @@ type Postgres
- host: The hostname of the database server (defaults to localhost).
- port: The port of the database server (defaults to 5432).
- database: The database to connect to. If empty, the default database will be used.
- schema: The schema to connect to. If empty, the default schema will be used.
- credentials: The credentials to use for the connection (defaults to PGPass or No Authentication).
- use_ssl: Whether to use SSL (defaults to `Prefer`).
- client_cert: The client certificate to use or `Nothing` if not needed.
Postgres_Data (host:Text=default_postgres_host) (port:Integer=default_postgres_port) (database:Text=default_postgres_database) (credentials:(Credentials|Nothing)=Nothing) (use_ssl:SSL_Mode=Prefer) (client_cert:(Client_Certificate|Nothing)=Nothing)
Postgres_Data (host:Text=default_postgres_host) (port:Integer=default_postgres_port) (database:Text=default_postgres_database) (schema:Text="") (credentials:(Credentials|Nothing)=Nothing) (use_ssl:SSL_Mode=Prefer) (client_cert:(Client_Certificate|Nothing)=Nothing)

## Build the Connection resource.

Expand All @@ -34,7 +38,12 @@ type Postgres
if Driver.isRegistered.not then Driver.register

properties = options.merge self.jdbc_properties
Connection.create_jdbc_connection self.jdbc_url properties self.dialect

## Cannot use default argument values as gets in an infinite loop if you do.
make_new database schema =
Postgres_Data self.host self.port (database.if_nothing self.database) (schema.if_nothing self.schema) self.credentials self.use_ssl self.client_cert . connect options

Postgres_Connection.create self.jdbc_url properties make_new

## Provides the jdbc url for the connection.
jdbc_url : Text
Expand Down Expand Up @@ -65,11 +74,7 @@ type Postgres
cert_properties = if self.client_cert.is_nothing then [] else
self.client_cert.properties

credentials + ssl_properties + cert_properties

## Provides the dialect needed for creating SQL statements.
dialect : Dialect
dialect self = Dialect.postgres
(if self.schema == '' then [] else [Pair_Data 'currentSchema' self.schema]) + credentials + ssl_properties + cert_properties

## PRIVATE
Given an `SSL_Mode`, create the JDBC properties to secure a Postgres-based
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from Standard.Base import all

import Standard.Database.Data.Dialect
import Standard.Database.Internal.JDBC_Connection
import Standard.Database.Connection.Connection
from Standard.Database.Connection.Credentials import Credentials, Credentials_Data
import Standard.Database.Connection.Connection_Options
Expand Down Expand Up @@ -37,7 +38,9 @@ type Redshift
java_props = Properties.new
properties.each pair->
java_props.setProperty pair.first pair.second
Connection.create_jdbc_connection self.jdbc_url properties self.dialect

jdbc_connection = JDBC_Connection.create self.jdbc_url properties
Connection.Connection_Data jdbc_connection Dialect.redshift

## Provides the jdbc url for the connection.
jdbc_url : Text
Expand All @@ -54,11 +57,11 @@ type Redshift
credentials = case self.credentials of
Nothing -> Pgpass.read self.host self.port self.schema
AWS_Profile db_user profile ->
[Pair 'user' db_user] + (if profile == '' then [] else [Pair 'profile' profile])
[Pair_Data 'user' db_user] + (if profile == '' then [] else [Pair_Data 'profile' profile])
AWS_Key db_user access_key secret_access_key ->
[Pair 'user' db_user, Pair 'AccessKeyID' access_key, Pair 'SecretAccessKey' secret_access_key]
[Pair_Data 'user' db_user, Pair_Data 'AccessKeyID' access_key, Pair_Data 'SecretAccessKey' secret_access_key]
Credentials_Data username password ->
[Pair 'user' username, Pair 'password' password]
[Pair_Data 'user' username, Pair_Data 'password' password]

## Disabled as Redshift SSL settings are different to PostgreSQL.
ssl_properties = []
Expand All @@ -68,10 +71,6 @@ type Redshift

credentials + ssl_properties + cert_properties

## Provides the dialect needed for creating SQL statements.
dialect : Dialect
dialect self = Dialect.redshift

type AWS_Credential
## Access Redshift using IAM via an AWS profile.

Expand All @@ -80,7 +79,6 @@ type AWS_Credential
- profile: AWS profile name (if empty uses default).
AWS_Profile db_user:Text profile:Text=''


## Access Redshift using IAM via an AWS access key ID and secret access key.

Arguments:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
from Standard.Base import all

import Standard.Database.Data.Dialect
import Standard.Database.Connection.Connection
import Standard.Database.Internal.SQLite.SQLite_Connection
import Standard.Database.Connection.Connection_Options

## Connect to a SQLite DB File or InMemory DB.
type SQLite
## Connect to a SQLite DB File or InMemory DB.

Arguments:
- location: Location of the SQLite database to connect to.
SQLite_Data (location:(In_Memory|File|Text))

## Build the Connection resource.

Arguments:
- options: Overrides for the connection properties.
connect : Connection_Options
connect self options =
properties = options.merge self.jdbc_properties
Connection.create_jdbc_connection self.jdbc_url properties self.dialect
SQLite_Connection.create self.jdbc_url properties

## Provides the jdbc url for the connection.
jdbc_url : Text
Expand All @@ -24,9 +29,5 @@ type SQLite
jdbc_properties : Vector
jdbc_properties self = []

## Provides the dialect needed for creating SQL statements.
dialect : Dialect
dialect self = Dialect.sqlite

## Connect to an in-memory SQLite database.
type In_Memory
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Standard.Table.Data.Sort_Column

from Standard.Database.Data.Sql import Sql_Type
from Standard.Database.Data.Table import Integrity_Error
from Standard.Database.Error import Unsupported_Database_Operation_Error
from Standard.Database.Errors import Unsupported_Database_Operation_Error

type Column

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Standard.Database.Data.Dialect
import Standard.Database.Data.Dialect.Helpers
import Standard.Database.Data.Internal.Base_Generator
import Standard.Database.Data.Internal.IR
from Standard.Database.Error import Unsupported_Database_Operation_Error
from Standard.Database.Errors import Unsupported_Database_Operation_Error

## PRIVATE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Standard.Database.Data.Dialect
import Standard.Database.Data.Dialect.Helpers
import Standard.Database.Data.Internal.Base_Generator
import Standard.Database.Data.Internal.IR
from Standard.Database.Error import Unsupported_Database_Operation_Error_Data
from Standard.Database.Errors import Unsupported_Database_Operation_Error_Data

## PRIVATE

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ from Standard.Base.Data.Text.Text_Ordering import Text_Ordering_Data
from Standard.Table.Data.Aggregate_Column import all
import Standard.Database.Data.Internal.IR
from Standard.Database.Data.Sql import Sql_Type
from Standard.Database.Error import Unsupported_Database_Operation_Error_Data
from Standard.Database.Errors import Unsupported_Database_Operation_Error_Data

## PRIVATE
Creates an `Internal_Column` that computes the specified statistic.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Standard.Database.Data.Sql
import Standard.Database.Data.Internal.IR

from Standard.Database.Data.Sql import Sql_Type
from Standard.Database.Error import Unsupported_Database_Operation_Error
from Standard.Database.Errors import Unsupported_Database_Operation_Error

type Internal_Dialect

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ from Standard.Database.Data.Internal.IR import Internal_Column, Internal_Column_
from Standard.Table.Errors import No_Such_Column_Error, No_Such_Column_Error_Data
from Standard.Table.Data.Column_Selector import Column_Selector, By_Index, By_Name
from Standard.Table.Data.Data_Formatter import Data_Formatter
from Standard.Database.Error import Unsupported_Database_Operation_Error_Data
from Standard.Database.Errors import Unsupported_Database_Operation_Error_Data
import Standard.Table.Data.Column_Name_Mapping
import Standard.Table.Data.Position
import Standard.Table.Data.Sort_Column_Selector
Expand Down
10 changes: 0 additions & 10 deletions distribution/lib/Standard/Database/0.0.0-dev/src/Error.enso

This file was deleted.

80 changes: 80 additions & 0 deletions distribution/lib/Standard/Database/0.0.0-dev/src/Errors.enso
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from Standard.Base import all

polyglot java import java.sql.SQLException

## Indicates that a requested operation is not supported, for example because a
particular database backend does not support it.
type Unsupported_Database_Operation_Error
Unsupported_Database_Operation_Error_Data message

## UNSTABLE

Convert the SQL error to a textual representation.
to_text : Text
to_text self =
"Unsupported database operation: " + self.message

## UNSTABLE

Pretty print the error.
to_display_text : Text
to_display_text self =
"Unsupported database operation: " + self.message

type Sql_Error
## UNSTABLE

Indicates an error with executing a query, update or connecting to the
database.

Arguments:
- java_exception: The underlying exception.
- related_query (optional): A string representation of a query that this
error is related to.
Sql_Error_Data java_exception related_query=Nothing

## UNSTABLE

Convert the SQL error to a textual representation.
to_text : Text
to_text self =
query = if self.related_query.is_nothing.not then " [Query was: " + self.related_query + "]" else ""
"There was an SQL error: " + self.java_exception.getMessage.to_text + "." + query

## UNSTABLE

Pretty print the SQL error.
to_display_text : Text
to_display_text self = self.to_text

## PRIVATE

Throws an error as if a SQL Exception was thrown.
throw_sql_error : Text -> Sql_Error
throw_sql_error message =
Error.throw (Sql_Error_Data (SQLException.new message))

type Sql_Timeout_Error
## UNSTABLE

Indicates that an operation has timed out.

Arguments:
- java_exception: The underlying exception.
- related_query (optional): A string representation of a query that this
error is related to.
Sql_Timeout_Error_Data java_exception related_query=Nothing

## UNSTABLE

Convert the timeout error to a textual representation.
to_text : Text
to_text self =
query = if self.related_query.is_nothing.not then " [Query was: " + query + "]" else ""
"The SQL connection timed out: " + self.java_exception.getMessage + "." + query

## UNSTABLE

Pretty print the timeout error.
to_display_text : Text
to_display_text self = self.to_text
Loading

0 comments on commit 2b425f8

Please sign in to comment.