Compare commits

...

47 Commits
2.1.0 ... 2

Author SHA1 Message Date
Maxime Rainville a60fc4cf24
Merge pull request #146 from creative-commoners/pulls/2/dispatch-ci
MNT Use gha-dispatch-ci
2023-03-23 14:15:32 +13:00
Steve Boyd d2fbce5319 MNT Use gha-dispatch-ci 2023-03-21 14:32:24 +13:00
Steve Boyd beb0f84f2d Merge branch '2.3' into 2 2022-08-03 14:33:11 +12:00
Guy Sartorelli 6d5c35116a
Merge pull request #132 from creative-commoners/pulls/2.3/standardise-modules
MNT Standardise modules
2022-08-03 10:09:54 +12:00
Steve Boyd 41fd4718a2 MNT Standardise modules 2022-08-02 17:55:18 +12:00
Steve Boyd 448828c20a Merge branch '2.3' into 2 2022-07-26 16:45:04 +12:00
Guy Sartorelli faf9d033ff
Merge pull request #130 from creative-commoners/pulls/2.3/module-standards
MNT Use GitHub Actions CI
2022-07-15 12:45:58 +12:00
Steve Boyd d7b4ccb202 MNT Use GitHub Actions CI 2022-07-15 12:23:59 +12:00
Guy Sartorelli c9bce8fe57 Merge branch '2.3' into 2 2022-06-14 11:31:28 +12:00
Sabina Talipova 4bbabf2421
Merge pull request #128 from creative-commoners/pulls/2.3/phpunit9
Approved
2022-06-07 08:00:53 +12:00
Steve Boyd 22e3951244 MNT Test using PHPUnit9 2022-06-02 12:21:46 +12:00
Steve Boyd 321d0d853b Merge branch '2.3' into 2 2022-04-22 09:32:30 +12:00
Guy Sartorelli 84e13ffde3
Merge pull request #127 from creative-commoners/pulls/2.3/chars
FIX Ignore invalid byte character
2022-04-21 18:40:22 +12:00
Steve Boyd 17e9f5388c FIX Ignore invalid byte character 2022-04-21 14:14:28 +12:00
Steve Boyd 222f20529c
Update build status badge 2021-01-21 16:37:01 +13:00
Steve Boyd c46272e751 Merge branch '2.3' into 2 2021-01-18 13:59:53 +13:00
Steve Boyd afec73997a
Merge pull request #121 from creative-commoners/pulls/2.3/travis-matrix
MNT Rearrange travis matrix
2021-01-18 13:58:22 +13:00
Steve Boyd d3c8e2915e MNT Rearrange travis matrix 2021-01-18 11:37:36 +13:00
Steve Boyd a709a741b0 Merge branch '2.3' into 2 2021-01-02 20:09:58 +13:00
Maxime Rainville dd4df9800b
Merge pull request #119 from creative-commoners/pulls/2.3/travis-shared
MNT Travis shared config, use sminnee/phpunit
2020-12-21 15:03:34 +13:00
Steve Boyd 082742ad23 MNT Travis shared config, use sminnee/phpunit 2020-12-02 15:41:59 +13:00
Robbie Averill a7c3450d43 Merge branch 'pulls/docs-known-issue' into 2
# Conflicts:
 #	README.md
 #
2019-11-27 17:33:06 -08:00
Robbie Averill 0be39423a3 Merge branch '2.3' into 2 2019-11-27 17:28:00 -08:00
Robbie Averill 3d50b3f9ec Merge branch '2.2' into 2.3 2019-11-27 17:27:36 -08:00
Maxime Rainville 3e38f845e3 Bump branch alias to 2.4. 2019-10-02 14:48:55 +13:00
Maxime Rainville 4e3d3df565 Remove branch alias for 2.3.0 release 2019-10-02 14:45:33 +13:00
Maxime Rainville 753d73e1fe
BUG Fix issues preventing a site from being migrated from SS3 to SS4 (#104)
* BUG Enum value change wasn't being detected by alterTableAlterColumn because backslashes were not accounting

* BUG Update renameTable to also rename constraints

* BUG Add unit tests to cover requireTable and renameTable

* Fix liniting errors

* MINOR Update build to use xenial and add extra PHP version
2019-09-26 10:25:41 +12:00
Guy Marriott beed6c7fb7
API Increased support to 9.2 (#102)
API Increased support to 9.2
2019-09-17 16:17:43 -07:00
Ingo Schommer bf4fb87a01 API Increased support to 9.2
Anything older than 9.3 is unsupported by Postgres: https://www.postgresql.org/support/versioning/.
I don't think we should claim support in our module for unsupported versions,
particularly if we don't have CI on them.

Since we're *only* running CI on 9.2 at the moment, that's the safe claim
for our module support, even though it's already unsupported by Postgres.
See https://docs.travis-ci.com/user/database-setup/#using-a-different-postgresql-version

I'll raise a separate ticket about testing and supporting newer versions,
it's out of scope for this PR.
2019-09-03 15:41:23 +12:00
Ingo Schommer 66376db094 DOCS Known issue about collations
Moving from https://docs.silverstripe.org/en/4/getting_started/server_requirements/
since it's too much noise there.

Also removing the maintainer contact, that's an outdated concept.
2019-09-03 15:22:14 +12:00
Ingo Schommer d607a2bfa9
Merge pull request #100 from sminnee/drop-php5
NEW: Drop PHP 5.6 testing
2019-07-04 08:59:40 +12:00
Sam Minnée f2ec228c72
Merge pull request #99 from sminnee/fix-9097
FIX: Don’t drop first row on repeated iteration
2019-07-03 14:27:21 +12:00
Sam Minnee 82f8a06afa NEW: Drop PHP 5.6 testing
PostgreSQL 2.3+, like Framework 4.5+, is able to be PHP 7.1+. Updated
the test matrix to reflect this.
2019-07-03 13:58:50 +12:00
Sam Minnee 75f4a35f71 FIX: Don’t drop first row on repeated iteration
Fixes https://github.com/silverstripe/silverstripe-framework/issues/9097

Related: https://github.com/silverstripe/silverstripe-framework/issues/9098

Co-authored-by: Guy Marriott <guy@scopey.co.nz>
2019-07-03 13:55:17 +12:00
Guy Marriott 08c8293328
Merge pull request #97 from open-sausages/pulls/2/fix-aliasing
FIX Usage of a bug-feature around aliases
2019-05-09 12:38:33 +12:00
Serge Latyntcev 0ffaf90512 FIX Usage of a bug-feature around aliases
Related https://github.com/silverstripe/silverstripe-postgresql/issues/95
2019-05-06 16:06:58 +12:00
Guy Marriott 04000ad878
Merge remote-tracking branch 'origin/2.2' into 2 2019-04-15 15:36:11 +12:00
Guy Marriott 3d6920c121
Remove branch alias 2019-04-15 15:14:05 +12:00
Guy Marriott b6bab3561f
Bump branch alias for 2.3.x-dev 2019-04-15 11:11:50 +12:00
Sam Minnee fd27c17a80 MINOR: Add comment to explain ‘f’ coercion.
Follow-up to https://github.com/silverstripe/silverstripe-postgresql/pull/93
2019-01-23 22:19:26 +13:00
Robbie Averill f85b46d047
Merge pull request #93 from sminnee/fix-boolean-coersion
FIX: Boolean ’t’/‘f’ strings need to be coerced to int properly.
2019-01-23 11:16:53 +02:00
Sam Minnee 32a0aad720 FIX: Boolean ’t’/‘f’ strings need to be coerced to int properly. 2019-01-23 13:50:32 +13:00
Loz Calver 0d9fcabc80
Merge pull request #91 from sminnee/strict-types
Strict types
2018-11-05 10:14:23 +01:00
Sam Minnee 8f70ac89ca FIX: Removed test that has been moved back to framework
This test has been added for all database types in framework
in https://github.com/silverstripe/silverstripe-framework/pull/8448
2018-11-05 18:13:47 +13:00
Sam Minnee 72787ae83e FIX: Return correct types in PostgreSQLQuery
Fixes https://github.com/silverstripe/silverstripe-postgresql/issues/90
Helps fix https://github.com/silverstripe/silverstripe-framework/issues/7039
2018-11-05 18:13:47 +13:00
Robbie Averill 4c6034f350 Bump branch alias for 2.2.x-dev 2018-09-24 12:49:53 +02:00
Robbie Averill edfa209a3c Merge branch '2.1' into 2 2018-09-24 12:49:36 +02:00
15 changed files with 342 additions and 241 deletions

25
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,25 @@
name: CI
on:
push:
pull_request:
workflow_dispatch:
jobs:
ci:
name: CI
uses: silverstripe/gha-ci/.github/workflows/ci.yml@v1
with:
# set phpunit to false to prevent automatic generation of mysql phpunit jobs
phpunit: false
extra_jobs: |
- php: 7.4
db: pgsql
phpunit: true
composer_args: --prefer-lowest
- php: 8.0
db: pgsql
phpunit: true
- php: 8.1
db: pgsql
phpunit: true

16
.github/workflows/dispatch-ci.yml vendored Normal file
View File

@ -0,0 +1,16 @@
name: Dispatch CI
on:
# At 12:20 PM UTC, only on Thursday and Friday
schedule:
- cron: '20 12 * * 4,5'
jobs:
dispatch-ci:
name: Dispatch CI
# Only run cron on the silverstripe account
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
runs-on: ubuntu-latest
steps:
- name: Dispatch CI
uses: silverstripe/gha-dispatch-ci@v1

17
.github/workflows/keepalive.yml vendored Normal file
View File

@ -0,0 +1,17 @@
name: Keepalive
on:
workflow_dispatch:
# The 4th of every month at 10:50am UTC
schedule:
- cron: '50 10 4 * *'
jobs:
keepalive:
name: Keepalive
# Only run cron on the silverstripe account
if: (github.event_name == 'schedule' && github.repository_owner == 'silverstripe') || (github.event_name != 'schedule')
runs-on: ubuntu-latest
steps:
- name: Keepalive
uses: silverstripe/gha-keepalive@v1

View File

@ -1,15 +0,0 @@
inherit: true
build:
nodes:
analysis:
tests:
override: [php-scrutinizer-run]
checks:
php:
code_rating: true
duplication: true
filter:
paths: [code/*, tests/*]

View File

@ -1,43 +0,0 @@
language: php
dist: trusty
cache:
directories:
- $HOME/.composer/cache/files
php:
- 5.6
env:
global:
- DB="PGSQL"
matrix:
fast_finish: true
include:
- php: 5.6
env:
- PHPUNIT_TEST=framework
- php: 5.6
env:
- PHPUNIT_TEST=postgresql
- PHPCS_TEST=1
before_script:
# Init PHP
- phpenv rehash
- phpenv config-rm xdebug.ini
- export PATH=~/.composer/vendor/bin:$PATH
- echo 'memory_limit = 2048M' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
# Install composer dependencies
- composer validate
- composer require --no-update silverstripe/recipe-cms:4.3.x-dev
- composer install --prefer-source --no-interaction --no-progress --no-suggest --optimize-autoloader --verbose --profile
- if [[ $PHPCS_TEST ]]; then composer global require squizlabs/php_codesniffer:^3 --prefer-dist --no-interaction --no-progress --no-suggest -o; fi
script:
- if [[ $PHPUNIT_TEST == postgresql ]]; then vendor/bin/phpunit ./tests; fi
- if [[ $PHPUNIT_TEST == framework ]]; then vendor/bin/phpunit ./vendor/silverstripe/framework/tests/php; fi
- if [[ $PHPCS_TEST ]]; then composer run-script lint; fi

View File

@ -1,35 +1,54 @@
# PostgreSQL Module Module
[![Build Status](https://travis-ci.org/silverstripe/silverstripe-postgresql.png?branch=master)](https://travis-ci.org/silverstripe/silverstripe-postgresql)
[![SilverStripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
## Maintainer Contact
* Sam Minnee (Nickname: sminnee) <sam@silverstripe.com>
[![CI](https://github.com/silverstripe/silverstripe-postgresql/actions/workflows/ci.yml/badge.svg)](https://github.com/silverstripe/silverstripe-postgresql/actions/workflows/ci.yml)
[![Silverstripe supported module](https://img.shields.io/badge/silverstripe-supported-0071C4.svg)](https://www.silverstripe.org/software/addons/silverstripe-commercially-supported-module-list/)
## Requirements
* SilverStripe 4.0
* PostgreSQL 8.3.x or greater must be installed
* PostgreSQL <8.3.0 may work if T-Search is manually installed
* Known to work on OS X Leopard, Windows Server 2008 R2 and Linux
* Silverstripe 4.0
* PostgreSQL >=9.2
* Note: PostgreSQL 10 has not been tested
## Installation
1. Install via composer `composer require silverstripe/postgresql` or extract the contents
so they reside as a `postgresql` directory inside your SilverStripe project code
2. Open the installer by browsing to install.php, e.g. http://localhost/silverstripe/install.php
3. Select PostgreSQL in the database list and enter your database details
```
composer require silverstripe/postgresql
```
## Configuration
### Environment file
Add the following settings to your `.env` file:
```
SS_DATABASE_CLASS=PostgreSQLDatabase
SS_DATABASE_USERNAME=
SS_DATABASE_PASSWORD=
```
See [environment variables](https://docs.silverstripe.org/en/4/getting_started/environment_management) for more details. Note that a database will automatically be created via `dev/build`.
### Through the installer
Open the installer by browsing to install.php, e.g. http://localhost/install.php
Select PostgreSQL in the database list and enter your database details
## Usage Overview
See docs/en for more information about configuring the module.
See [docs/en](docs/en/README.md) for more information about configuring the module.
## Known issues
All column and table names must be double-quoted. PostgreSQL automatically
lower-cases columns, and your queries will fail if you don't.
Collations have known issues when installed on Alpine, MacOS X and BSD derivatives
(see [PostgreSQL FAQ](https://wiki.postgresql.org/wiki/FAQ#Why_do_my_strings_sort_incorrectly.3F)).
We do not support such installations, although they still may work correctly for you.
As a workaround for PostgreSQL 10+ you could manually switch to ICU collations (e.g. und-x-icu).
There are no known workarounds for PostgreSQL <10.
Ts_vector columns are not automatically detected by the built-in search
filters. That means if you're doing a search through the CMS on a ModelAdmin
object, it will use LIKE queries which are very slow. If you're writing your

View File

@ -448,7 +448,7 @@ class PostgreSQLDatabase extends Database
// Could parameterise this, but convention is only to to so for where conditions
$query->addFrom(array(
'tsearch' => ", to_tsquery('" . self::search_language() . "', $keywords) AS q"
'q' => ", to_tsquery('" . self::search_language() . "', $keywords)"
));
$query->setSelect(array());

View File

@ -18,6 +18,23 @@ class PostgreSQLQuery extends Query
*/
private $handle;
private $columnNames = [];
/**
* Mapping of postgresql types to PHP types
* Note that the bool => int mapping is by design, designed to mimic MySQL's behaviour
* @var array
*/
protected static $typeMapping = [
'bool' => 'int',
'int2' => 'int',
'int4' => 'int',
'int8' => 'int',
'float4' => 'float',
'float8' => 'float',
'numeric' => 'float',
];
/**
* Hook the result-set given into a Query class, suitable for use by sapphire.
* @param resource $handle the internal Postgres handle that is points to the resultset.
@ -25,6 +42,11 @@ class PostgreSQLQuery extends Query
public function __construct($handle)
{
$this->handle = $handle;
$numColumns = pg_num_fields($handle);
for ($i = 0; $i<$numColumns; $i++) {
$this->columnNames[$i] = pg_field_name($handle, $i);
}
}
public function __destruct()
@ -36,8 +58,10 @@ class PostgreSQLQuery extends Query
public function seek($row)
{
pg_result_seek($this->handle, $row);
return pg_fetch_assoc($this->handle);
// Specifying the zero-th record here will reset the pointer
$result = pg_fetch_array($this->handle, $row, PGSQL_NUM);
return $this->parseResult($result);
}
public function numRecords()
@ -47,6 +71,39 @@ class PostgreSQLQuery extends Query
public function nextRecord()
{
return pg_fetch_assoc($this->handle);
$row = pg_fetch_array($this->handle, null, PGSQL_NUM);
// Correct non-string types
if ($row) {
return $this->parseResult($row);
}
return false;
}
/**
* @param array $row
* @return array
*/
protected function parseResult(array $row)
{
$record = [];
foreach ($row as $i => $v) {
$k = $this->columnNames[$i];
$record[$k] = $v;
$type = pg_field_type($this->handle, $i);
if (isset(self::$typeMapping[$type])) {
if ($type === 'bool' && $record[$k] === 't') {
$record[$k] = 1;
// Note that boolean 'f' will be converted to 0 by this
} else {
settype($record[$k], self::$typeMapping[$type]);
}
}
}
return $record;
}
}

View File

@ -494,9 +494,15 @@ class PostgreSQLSchemaManager extends DBSchemaManager
// First, we split the column specifications into parts
// TODO: this returns an empty array for the following string: int(11) not null auto_increment
// on second thoughts, why is an auto_increment field being passed through?
$pattern = '/^([\w(\,)]+)\s?((?:not\s)?null)?\s?(default\s[\w\.\']+)?\s?(check\s[\w()\'",\s]+)?$/i';
$pattern = '/^([\w(\,)]+)\s?((?:not\s)?null)?\s?(default\s[\w\.\'\\\\]+)?\s?(check\s[\w()\'",\s\\\\]+)?$/i';
preg_match($pattern, $colSpec, $matches);
// example value this regex is expected to parse:
// varchar(255) not null default 'SS\Test\Player' check ("ClassName" in ('SS\Test\Player', 'Player', null))
// split into:
// * varchar(255)
// * not null
// * default 'SS\Test\Player'
// * check ("ClassName" in ('SS\Test\Player', 'Player', null))
if (sizeof($matches) == 0) {
return '';
@ -537,8 +543,8 @@ class PostgreSQLSchemaManager extends DBSchemaManager
if ($this->hasTable("{$tableName}_Live")) {
$updateConstraint .= "UPDATE \"{$tableName}_Live\" SET \"$colName\"='$default' WHERE \"$colName\" NOT IN ($constraint_values);";
}
if ($this->hasTable("{$tableName}_versions")) {
$updateConstraint .= "UPDATE \"{$tableName}_versions\" SET \"$colName\"='$default' WHERE \"$colName\" NOT IN ($constraint_values);";
if ($this->hasTable("{$tableName}_Versions")) {
$updateConstraint .= "UPDATE \"{$tableName}_Versions\" SET \"$colName\"='$default' WHERE \"$colName\" NOT IN ($constraint_values);";
}
$this->query($updateConstraint);
@ -560,8 +566,17 @@ class PostgreSQLSchemaManager extends DBSchemaManager
public function renameTable($oldTableName, $newTableName)
{
$constraints = $this->getConstraintForTable($oldTableName);
$this->query("ALTER TABLE \"$oldTableName\" RENAME TO \"$newTableName\"");
if ($constraints) {
foreach ($constraints as $old) {
$new = preg_replace('/^' . $oldTableName . '/', $newTableName, $old);
$this->query("ALTER TABLE \"$newTableName\" RENAME CONSTRAINT \"$old\" TO \"$new\";");
}
}
unset(self::$cached_fieldlists[$oldTableName]);
unset(self::$cached_constraints[$oldTableName]);
}
public function checkAndRepairTable($tableName)
@ -843,7 +858,9 @@ class PostgreSQLSchemaManager extends DBSchemaManager
$argList = array();
$nextArg = "";
foreach ($bytes as $byte) {
if ($byte == "00") {
if ($byte == '\x') {
continue;
} elseif ($byte == "00") {
$argList[] = $nextArg;
$nextArg = "";
} else {
@ -961,6 +978,28 @@ class PostgreSQLSchemaManager extends DBSchemaManager
return self::$cached_constraints[$constraint];
}
/**
* Retrieve a list of constraints for the provided table name.
* @param string $tableName
* @return array
*/
private function getConstraintForTable($tableName)
{
// Note the PostgreSQL `like` operator is case sensitive
$constraints = $this->preparedQuery(
"
SELECT conname
FROM pg_catalog.pg_constraint r
INNER JOIN pg_catalog.pg_namespace n
ON r.connamespace = n.oid
WHERE r.contype = 'c' AND conname like ? AND n.nspname = ?
ORDER BY 1;",
array($tableName . '_%', $this->database->currentSchema())
)->column('conname');
return $constraints;
}
/**
* A function to return the field names and datatypes for the particular table
*

View File

@ -19,9 +19,9 @@
"silverstripe/vendor-plugin": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7"
"phpunit/phpunit": "^9.5",
"squizlabs/php_codesniffer": "^3"
},
"extra": [],
"autoload": {
"psr-4": {
"SilverStripe\\PostgreSQL\\": "code/",

View File

@ -1,86 +1,5 @@
# PostgreSQL Database Module
SilverStripe now has tentative support for PostgreSQL ('Postgres').
## Requirements
SilverStripe 2.4.0 or greater. (PostgreSQL support is NOT available
in 2.3.).
SilverStripe supports Postgres versions 8.3.x, 8.4.x and onwards.
Postgres 8.3.0 launched in February 2008, so SilverStripe has a fairly
modern but not bleeding edge Postgres version requirement.
Support for 8.2.x is theoretically possible if you're willing to manually
install T-search. 8.2.x has not been tested either, so there may be other
compatibility issues. The EnterpriseDB versions of Postgres also work, if
you'd prefer a tuned version.
## Installation
You have three options to install PostgreSQL support with SilverStripe.
### Option 1 - Installer
The first option is to use the installer. However, this is currently only
supported since SilverStripe 2.4.0 beta2 (or using the daily builds).
1. Set up SilverStripe somewhere where you can start the installer - you
should only see one database “MySQL” to install with.
2. Download a copy of the “postgresql” module from here:
http://silverstripe.org/postgresql-module
3. Extract the archive you downloaded. Rename the directory from
“postgresql-trunk-rxxxx” to “postgresql” and copy it into the SilverStripe
directory you just set up
4. Open the installer once again, and a new option “PostgreSQL” should appear.
You can now proceed through the installation without having to change any code.
### Option 2 - Manual
The second option is to setup PostgreSQL support manually. This can be achieved
by following these instructions:
1. Set up a fresh working copy of SilverStripe
2. Download a copy of the “postgresql” module from here: http://silverstripe.org/postgresql-module
3. Extract the archive you downloaded. Rename the directory from
“postgresql-trunk-rxxxx” to “postgresql” and copy it into the SilverStripe
directory you just set up.
4. Open up your mysite/_config.php file and add (or update) the $databaseConfig
array like so:
> $databaseConfig = array(
> 'type' => 'PostgreSQLDatabase',
> 'server' => '[server address e.g. localhost]',
> 'username' => 'postgres',
> 'password' => 'mypassword',
> 'database' => 'SS_mysite'
> );
Finally, visit dev/build so that SilverStripe can build the database schema and
default records.
### Option 3 - Environment file
Finally, the third option is to change your environment to point to
PostgreSQLDatabase as a database class. Do this if you're currently using an
_ss_environment.php file.
1. Download a copy of the “postgresql” module from here: http://silverstripe.org/postgresql-module
2. Extract the archive you downloaded. Rename the directory from
postgresql-trunk-rxxxx” to “postgresql” and copy it into your SS directory
3. Add the following to your existing _ss_environment.php file:
> define('SS_DATABASE_CLASS', 'PostgreSQLDatabase');
Last steps:
1. Ensure your SS_DATABASE_USERNAME and SS_DATABASE_PASSWORD defines in
_ss_environment.php are correct to the PostgreSQL server.
2. Ensure that your mysite/_config.php file has a database name defined, such
as “SS_mysite”.
3. Visit dev/build so that SilverStripe can build the database schema and
default records
## Features
Here is a quick list of what's different in the Postgres module (a full
@ -300,22 +219,4 @@ Otherwise this extension will try to connect to "postgres" Database to check DB
connection, no matter what you entered in the "Database Name" field during
installation.
Make sure you have set the "search_path" correct for your database user.
## Known Issues
All column and table names must be double-quoted. PostgreSQL automatically
lower-cases columns, and your queries will fail if you don't.
Ts_vector columns are not automatically detected by the built-in search filters.
That means if you're doing a search through the CMS on a ModelAdmin object, it
will use LIKE queries which are very slow.
If you're writing your own front-end search system, you can specify the columns
to use for search purposes, and you get the full benefits of T-Search.
If you are using unsupported modules, there may be instances of MySQL-specific
SQL queries which will need to be made database-agnostic where possible.
Make sure you have set the "search_path" correct for your database user.

View File

@ -2,6 +2,9 @@
<ruleset name="SilverStripe">
<description>CodeSniffer ruleset for SilverStripe coding conventions.</description>
<file>code</file>
<file>tests</file>
<!-- base rules are PSR-2 -->
<rule ref="PSR2" >
<!-- Current exclusions -->

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true">
<testsuite name="Default">

View File

@ -1,57 +0,0 @@
<?php
namespace SilverStripe\PostgreSQL\Tests;
use Exception;
use Page;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DB;
use SilverStripe\PostgreSQL\PostgreSQLDatabase;
/**
* @package postgresql
* @subpackage tests
*/
class PostgreSQLDatabaseTest extends SapphireTest
{
protected $usesDatabase = true;
public function testReadOnlyTransaction()
{
if (DB::get_conn()->supportsTransactions() == true
&& DB::get_conn() instanceof PostgreSQLDatabase
) {
$page = new Page();
$page->Title = 'Read only success';
$page->write();
DB::get_conn()->transactionStart('READ ONLY');
try {
$page = new Page();
$page->Title = 'Read only page failed';
$page->write();
} catch (Exception $e) {
//could not write this record
//We need to do a rollback or a commit otherwise we'll get error messages
DB::get_conn()->transactionRollback();
}
DB::get_conn()->transactionEnd();
DataObject::flush_and_destroy_cache();
$success = DataObject::get('Page', "\"Title\"='Read only success'");
$fail = DataObject::get('Page', "\"Title\"='Read only page failed'");
//This page should be in the system
$this->assertTrue(is_object($success) && $success->exists());
//This page should NOT exist, we had 'read only' permissions
$this->assertFalse(is_object($fail) && $fail->exists());
} else {
$this->markTestSkipped('Current database is not PostgreSQL');
}
}
}

View File

@ -0,0 +1,138 @@
<?php
namespace SilverStripe\PostgreSQL\Tests;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\ORM\Connect\Database;
use SilverStripe\ORM\Connect\DatabaseException;
use SilverStripe\ORM\DB;
use SilverStripe\PostgreSQL\PostgreSQLConnector;
use SilverStripe\PostgreSQL\PostgreSQLSchemaManager;
class PostgreSQLSchemaManagerTest extends SapphireTest
{
protected $usesTransactions = false;
public function testAlterTable()
{
try {
/** @var PostgreSQLSchemaManager $dbSchema */
$dbSchema = DB::get_schema();
$dbSchema->quiet();
$this->createSS3Table();
try {
DB::query('INSERT INTO "ClassNamesUpgrade" ("ClassName") VALUES (\'App\MySite\FooBar\')');
$this->assertFalse(true, 'SS3 Constaint should have blocked the previous insert.');
} catch (DatabaseException $ex) {
}
$dbSchema->schemaUpdate(function () use ($dbSchema) {
$dbSchema->requireTable(
'ClassNamesUpgrade',
[
'ID' => 'PrimaryKey',
'ClassName' => 'Enum(array("App\\\\MySite\\\\FooBar"))',
]
);
});
DB::query('INSERT INTO "ClassNamesUpgrade" ("ClassName") VALUES (\'App\MySite\FooBar\')');
$count = DB::query('SELECT count(*) FROM "ClassNamesUpgrade" WHERE "ClassName" = \'App\MySite\FooBar\'')
->value();
$this->assertEquals(1, $count);
} finally {
DB::query('DROP TABLE IF EXISTS "ClassNamesUpgrade"');
DB::query('DROP SEQUENCE IF EXISTS "ClassNamesUpgrade_ID_seq"');
}
}
private function createSS3Table()
{
DB::query(<<<SQL
CREATE SEQUENCE "ClassNamesUpgrade_ID_seq" start 1 increment 1;
CREATE TABLE "ClassNamesUpgrade"
(
"ID" bigint NOT NULL DEFAULT nextval('"ClassNamesUpgrade_ID_seq"'::regclass),
"ClassName" character varying(255) DEFAULT 'ClassNamesUpgrade'::character varying,
CONSTRAINT "ClassNamesUpgrade_pkey" PRIMARY KEY ("ID"),
CONSTRAINT "ClassNamesUpgrade_ClassName_check" CHECK ("ClassName"::text = ANY (ARRAY['FooBar'::character varying::text]))
)
WITH (
OIDS=FALSE
);
SQL
);
}
public function testRenameTable()
{
try {
/** @var PostgreSQLSchemaManager $dbSchema */
$dbSchema = DB::get_schema();
$dbSchema->quiet();
$this->createSS3VersionedTable();
$this->assertConstraintCount(1, 'ClassNamesUpgrade_versioned_ClassName_check');
$dbSchema->schemaUpdate(function () use ($dbSchema) {
$dbSchema->renameTable(
'ClassNamesUpgrade_versioned',
'ClassNamesUpgrade_Versioned'
);
});
$this->assertTableCount(0, 'ClassNamesUpgrade_versioned');
$this->assertTableCount(1, 'ClassNamesUpgrade_Versioned');
$this->assertConstraintCount(0, 'ClassNamesUpgrade_versioned_ClassName_check');
$this->assertConstraintCount(1, 'ClassNamesUpgrade_Versioned_ClassName_check');
} finally {
DB::query('DROP TABLE IF EXISTS "ClassNamesUpgrade_Versioned"');
DB::query('DROP TABLE IF EXISTS "ClassNamesUpgrade_versioned"');
DB::query('DROP SEQUENCE IF EXISTS "ClassNamesUpgrade_versioned_ID_seq"');
}
}
private function assertConstraintCount($expected, $constraintName)
{
$count = DB::prepared_query(
'SELECT count(*) FROM pg_catalog.pg_constraint WHERE conname like ?',
[$constraintName]
)->value();
$this->assertEquals($expected, $count);
}
private function assertTableCount($expected, $tableName)
{
$count = DB::prepared_query(
'SELECT count(*) FROM pg_catalog.pg_tables WHERE "tablename" like ?',
[$tableName]
)->value();
$this->assertEquals($expected, $count);
}
private function createSS3VersionedTable()
{
DB::query(<<<SQL
CREATE SEQUENCE "ClassNamesUpgrade_versioned_ID_seq" start 1 increment 1;
CREATE TABLE "ClassNamesUpgrade_versioned"
(
"ID" bigint NOT NULL DEFAULT nextval('"ClassNamesUpgrade_versioned_ID_seq"'::regclass),
"ClassName" character varying(255) DEFAULT 'ClassNamesUpgrade'::character varying,
CONSTRAINT "ClassNamesUpgrade_pkey" PRIMARY KEY ("ID"),
CONSTRAINT "ClassNamesUpgrade_versioned_ClassName_check" CHECK ("ClassName"::text = ANY (ARRAY['FooBar'::character varying::text]))
)
WITH (
OIDS=FALSE
);
SQL
);
}
}