diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 0017ec6630..a5fa5559f7 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -155,6 +155,8 @@ UNRELEASED * Enterprise Corda only: node configuration property ``database.schema`` and documented existing database properties. +* Enterprise Corda only: Compatibility with PostgreSQL 9.6 database. + .. _changelog_v1: Release 1.0 diff --git a/docs/source/node-database.rst b/docs/source/node-database.rst index d854586397..5d77f2911f 100644 --- a/docs/source/node-database.rst +++ b/docs/source/node-database.rst @@ -58,3 +58,25 @@ database { transactionIsolationLevel = "readCommitted" schema = [SCHEMA] } + +PostgreSQL +```````````````````````` +Corda supports PostgreSQL 9.6 database. +The property ``database.schema`` is optional. The value of ``database.schema`` is automatically wrapped in double quotes +to preserve case-sensitivity (e.g. `AliceCorp` becomes `"AliceCorp"`, without quotes PostgresSQL would treat the value as `alicecorp`). +Corda ships with PostgreSQL JDBC Driver 42.1.4 out-of-the-box. + +Example node configuration for PostgreSQL: + +.. sourcecode:: none + +dataSourceProperties = { + dataSourceClassName = "org.postgresql.ds.PGSimpleDataSource" + dataSource.url = "jdbc:postgresql://[HOST]:[PORT]/postgres" + dataSource.user = [USER] + dataSource.password = [PASSWORD] +} +database = { + transactionIsolationLevel = READ_COMMITTED + schema = [SCHEMA] +} diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/HibernateConfiguration.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/HibernateConfiguration.kt index 8669c79a8e..2857ed5372 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/HibernateConfiguration.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/HibernateConfiguration.kt @@ -51,7 +51,13 @@ class HibernateConfiguration( .setProperty("hibernate.connection.isolation", databaseConfig.transactionIsolationLevel.jdbcValue.toString()) databaseConfig.schema?.apply { - config.setProperty("hibernate.default_schema", databaseConfig.schema) + //preserving case-sensitive schema name for PostgreSQL by wrapping in double quotes, schema without double quotes would be treated as case-insensitive (lower cases) + val schemaName = if (jdbcUrl.contains(":postgresql:", ignoreCase = true) && !databaseConfig.schema.startsWith("\"")) { + "\"" + databaseConfig.schema + "\"" + } else { + databaseConfig.schema + } + config.setProperty("hibernate.default_schema", schemaName) } schemas.forEach { schema -> @@ -97,7 +103,7 @@ class HibernateConfiguration( applyBasicType(CordaWrapperBinaryType, CordaWrapperBinaryType.name) // When connecting to SqlServer (and only then) do we need to tell hibernate to use // nationalised (i.e. Unicode) strings by default - val forceUnicodeForSqlServer = jdbcUrl.contains(":sqlserver:", ignoreCase = true); + val forceUnicodeForSqlServer = jdbcUrl.contains(":sqlserver:", ignoreCase = true) enableGlobalNationalizedCharacterDataSupport(forceUnicodeForSqlServer) build() } diff --git a/testing/test-utils/src/main/resources/database-scripts/postgres/db-global-cleanup.sql b/testing/test-utils/src/main/resources/database-scripts/postgres/db-global-cleanup.sql new file mode 100644 index 0000000000..4fd1cf384b --- /dev/null +++ b/testing/test-utils/src/main/resources/database-scripts/postgres/db-global-cleanup.sql @@ -0,0 +1,3 @@ +DROP SCHEMA IF EXISTS "${schema}" CASCADE; +DROP OWNED by "${schema}"; +DROP USER "${schema}"; \ No newline at end of file diff --git a/testing/test-utils/src/main/resources/database-scripts/postgres/db-global-setup.sql b/testing/test-utils/src/main/resources/database-scripts/postgres/db-global-setup.sql new file mode 100644 index 0000000000..c41885d64b --- /dev/null +++ b/testing/test-utils/src/main/resources/database-scripts/postgres/db-global-setup.sql @@ -0,0 +1,10 @@ +DROP SCHEMA IF EXISTS "${schema}" CASCADE; +DROP OWNED by "${schema}"; +DROP USER IF EXISTS "${schema}"; +CREATE USER "${schema}" WITH LOGIN password '1234'; +CREATE SCHEMA "${schema}"; +GRANT ALL ON SCHEMA "${schema}" TO "${schema}"; +GRANT ALL ON ALL tables IN SCHEMA "${schema}" TO "${schema}"; +ALTER DEFAULT privileges IN SCHEMA "${schema}" GRANT ALL ON tables TO "${schema}"; +GRANT ALL ON ALL sequences IN SCHEMA "${schema}" TO "${schema}"; +ALTER DEFAULT privileges IN SCHEMA "${schema}" GRANT ALL ON sequences TO "${schema}"; \ No newline at end of file diff --git a/testing/test-utils/src/main/resources/database-scripts/postgres/db-setup.sql b/testing/test-utils/src/main/resources/database-scripts/postgres/db-setup.sql new file mode 100644 index 0000000000..aa34b09d5a --- /dev/null +++ b/testing/test-utils/src/main/resources/database-scripts/postgres/db-setup.sql @@ -0,0 +1,5 @@ +DROP SCHEMA IF EXISTS "${schema}" CASCADE; +CREATE SCHEMA "${schema}"; +GRANT ALL ON SCHEMA "${schema}" TO "${schema}"; +ALTER DEFAULT privileges IN SCHEMA "${schema}" GRANT ALL ON tables TO "${schema}"; +ALTER DEFAULT privileges IN SCHEMA "${schema}" GRANT ALL ON sequences TO "${schema}"; \ No newline at end of file diff --git a/testing/test-utils/src/main/resources/database-scripts/sql-server/db-global-setup.sql b/testing/test-utils/src/main/resources/database-scripts/sql-server/db-global-setup.sql index a9f9ef63d9..ac53ec2a1a 100644 --- a/testing/test-utils/src/main/resources/database-scripts/sql-server/db-global-setup.sql +++ b/testing/test-utils/src/main/resources/database-scripts/sql-server/db-global-setup.sql @@ -29,18 +29,20 @@ DROP TABLE IF EXISTS ${schema}.node_named_identities; DROP TABLE IF EXISTS ${schema}.children; DROP TABLE IF EXISTS ${schema}.parents; DROP TABLE IF EXISTS ${schema}.contract_cash_states; +DROP TABLE IF EXISTS ${schema}.contract_cash_states_v1; DROP TABLE IF EXISTS ${schema}.messages; DROP TABLE IF EXISTS ${schema}.state_participants; DROP TABLE IF EXISTS ${schema}.cash_states_v2; DROP TABLE IF EXISTS ${schema}.cash_states_v3; +DROP TABLE IF EXISTS ${schema}.cp_states_v1; DROP TABLE IF EXISTS ${schema}.cp_states_v2; DROP TABLE IF EXISTS ${schema}.dummy_deal_states; DROP TABLE IF EXISTS ${schema}.dummy_linear_states; DROP TABLE IF EXISTS ${schema}.dummy_linear_states_v2; DROP TABLE IF EXISTS ${schema}.node_mutual_exclusion; -DROP SEQUENCE IF EXISTS ${schema}.hibernate_sequence; DROP TABLE IF EXISTS ${schema}.DATABASECHANGELOG; DROP TABLE IF EXISTS ${schema}.DATABASECHANGELOGLOCK; +DROP SEQUENCE IF EXISTS ${schema}.hibernate_sequence; DROP USER IF EXISTS ${schema}; DROP LOGIN ${schema}; DROP SCHEMA IF EXISTS ${schema}; diff --git a/testing/test-utils/src/main/resources/integration-postgres.conf b/testing/test-utils/src/main/resources/integration-postgres.conf new file mode 100644 index 0000000000..447fcf52fa --- /dev/null +++ b/testing/test-utils/src/main/resources/integration-postgres.conf @@ -0,0 +1,10 @@ +dataSourceProperties = { + dataSourceClassName = "org.postgresql.ds.PGSimpleDataSource" + dataSource.url = "jdbc:postgresql://[HOST]:[PORT]/postgres" + dataSource.user = ${nodeOrganizationName} + dataSource.password = "1234" +} +database = { + transactionIsolationLevel = READ_COMMITTED + schema = ${nodeOrganizationName} +} \ No newline at end of file