From c0eef4724ee7bb3be713bddf3b337b760066403e Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 18 Oct 2021 12:49:30 -0400 Subject: [PATCH 01/16] Build CI with Postgres 14 --- .github/workflows/ci.yml | 12 ++++- CONTRIBUTING.md | 6 ++- README.md | 3 +- scripts/before_script_postgres.sh | 1 + scripts/before_script_postgres_conf.sh | 30 +++++++++++ spec/.eslintrc.json | 2 + spec/InstallationsRouter.spec.js | 72 +++++++++++++------------- spec/ParseQuery.Aggregate.spec.js | 4 +- spec/helper.js | 18 +++++++ 9 files changed, 107 insertions(+), 41 deletions(-) create mode 100755 scripts/before_script_postgres_conf.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a26410a803..12e020234b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -182,15 +182,23 @@ jobs: include: - name: PostgreSQL 11, PostGIS 3.0 POSTGRES_IMAGE: postgis/postgis:11-3.0 + POSTGRES_VERSION: 11.13.0 NODE_VERSION: 14.18.1 - name: PostgreSQL 11, PostGIS 3.1 POSTGRES_IMAGE: postgis/postgis:11-3.1 + POSTGRES_VERSION: 11.13.0 NODE_VERSION: 14.18.1 - name: PostgreSQL 12, PostGIS 3.1 POSTGRES_IMAGE: postgis/postgis:12-3.1 + POSTGRES_VERSION: 12.8.0 NODE_VERSION: 14.18.1 - name: PostgreSQL 13, PostGIS 3.1 POSTGRES_IMAGE: postgis/postgis:13-3.1 + POSTGRES_VERSION: 13.4.0 + NODE_VERSION: 14.18.1 + - name: PostgreSQL 14, PostGIS 3.1 + POSTGRES_IMAGE: postgis/postgis:14-3.1 + POSTGRES_VERSION: 14.0.0 NODE_VERSION: 14.18.1 fail-fast: false name: ${{ matrix.name }} @@ -231,7 +239,9 @@ jobs: ${{ runner.os }}-node-${{ matrix.NODE_VERSION }}- - name: Install dependencies run: npm ci - - run: bash scripts/before_script_postgres.sh + - run: | + bash scripts/before_script_postgres_conf.sh + bash scripts/before_script_postgres.sh - run: npm run coverage env: CI: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fb444414b4..eaf4b648d0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -145,13 +145,15 @@ If your pull request introduces a change that may affect the storage or retrieva - `it_only_mongodb_version('>=4.4')` // will test with any version of Postgres but only with version >=4.4 of MongoDB; accepts semver notation to specify a version range - `it_exclude_mongodb_version('<4.4')` // will test with any version of Postgres and MongoDB, excluding version <4.4 of MongoDB; accepts semver notation to specify a version range + - `it_only_postgres_version('>=13')` // will test with any version of Mongo but only with version >=13 of Postgres; accepts semver notation to specify a version range + - `it_exclude_postgres_version('<13')` // will test with any version of Postgres and MongoDB, excluding version <13 of Postgres; accepts semver notation to specify a version range #### Postgres with Docker [PostGIS images (select one with v2.2 or higher) on docker dashboard](https://hub.docker.com/r/postgis/postgis) is based off of the official [postgres](https://registry.hub.docker.com/_/postgres/) image and will work out-of-the-box (as long as you create a user with the necessary extensions for each of your Parse databases; see below). To launch the compatible Postgres instance, copy and paste the following line into your shell: ``` -docker run -d --name parse-postgres -p 5432:5432 -e POSTGRES_PASSWORD=password --rm postgis/postgis:11-3.0-alpine && sleep 20 && docker exec -it parse-postgres psql -U postgres -c 'CREATE DATABASE parse_server_postgres_adapter_test_database;' && docker exec -it parse-postgres psql -U postgres -c 'CREATE EXTENSION pgcrypto; CREATE EXTENSION postgis;' -d parse_server_postgres_adapter_test_database && docker exec -it parse-postgres psql -U postgres -c 'CREATE EXTENSION postgis_topology;' -d parse_server_postgres_adapter_test_database +docker run -d --name parse-postgres -p 5432:5432 -e POSTGRES_PASSWORD=password --rm postgis/postgis:13-3.1-alpine && sleep 20 && docker exec -it parse-postgres psql -U postgres -c 'CREATE DATABASE parse_server_postgres_adapter_test_database;' && docker exec -it parse-postgres psql -U postgres -c 'CREATE EXTENSION pgcrypto; CREATE EXTENSION postgis;' -d parse_server_postgres_adapter_test_database && docker exec -it parse-postgres psql -U postgres -c 'CREATE EXTENSION postgis_topology;' -d parse_server_postgres_adapter_test_database ``` To stop the Postgres instance: @@ -159,7 +161,7 @@ To stop the Postgres instance: docker stop parse-postgres ``` -You can also use the [postgis/postgis:11-2.5-alpine](https://hub.docker.com/r/postgis/postgis) image in a Dockerfile and copy this [script](https://github.com/parse-community/parse-server/blob/master/scripts/before_script_postgres.sh) to the image by adding the following lines: +You can also use the [postgis/postgis:13-3.1-alpine](https://hub.docker.com/r/postgis/postgis) image in a Dockerfile and copy this [script](https://github.com/parse-community/parse-server/blob/master/scripts/before_script_postgres.sh) to the image by adding the following lines: ``` #Install additional scripts. These are run in abc order during initial start diff --git a/README.md b/README.md index 4de7400bdd..7a4ceed8cd 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Snyk badge Node.js 12,14,15 MongoDB 4.0,4.2,4.4,5.0 - PostgreSQL 11,12,13 + PostgreSQL 11,12,13,14

Our Sponsors

@@ -136,6 +136,7 @@ Parse Server is continuously tested with the most recent releases of PostgreSQL | Postgres 11 | 3.0, 3.1 | November 2023 | April 2022 | ✅ Fully compatible | | Postgres 12 | 3.1 | November 2024 | April 2023 | ✅ Fully compatible | | Postgres 13 | 3.1 | November 2025 | April 2024 | ✅ Fully compatible | +| Postgres 14 | 3.1 | November 2026 | April 2025 | ✅ Fully compatible | ### Locally ```bash diff --git a/scripts/before_script_postgres.sh b/scripts/before_script_postgres.sh index 5c445c4df1..3d2c9157ca 100755 --- a/scripts/before_script_postgres.sh +++ b/scripts/before_script_postgres.sh @@ -5,6 +5,7 @@ set -e echo "[SCRIPT] Before Script :: Setup Parse DB for Postgres" PGPASSWORD=postgres psql -v ON_ERROR_STOP=1 -h localhost -U postgres <<-EOSQL + SELECT pg_reload_conf(); CREATE DATABASE parse_server_postgres_adapter_test_database; \c parse_server_postgres_adapter_test_database; CREATE EXTENSION pgcrypto; diff --git a/scripts/before_script_postgres_conf.sh b/scripts/before_script_postgres_conf.sh new file mode 100755 index 0000000000..6d0d5e2a9a --- /dev/null +++ b/scripts/before_script_postgres_conf.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +set -e + +echo "[SCRIPT] Before Script :: Setup Parse Postgres configuration file" + +cat >> ${PGDATA}/postgresql.conf < { }); }); - it_only_db('postgres')('query installations with count = 1', async () => { + it_exclude_dbs(['postgres'])('query installations with limit = 0 and count = 1', done => { const config = Config.get('test'); const androidDeviceRequest = { installationId: '12345678-abcd-abcd-abcd-123456789abc', @@ -181,29 +181,36 @@ describe('InstallationsRouter', () => { auth: auth.master(config), body: {}, query: { + limit: 0, count: 1, }, info: {}, }; const router = new InstallationsRouter(); - await rest.create(config, auth.nobody(config), '_Installation', androidDeviceRequest); - await rest.create(config, auth.nobody(config), '_Installation', iosDeviceRequest); - let res = await router.handleFind(request); - let response = res.response; - expect(response.results.length).toEqual(2); - expect(response.count).toEqual(0); // estimate count is zero - - const pgAdapter = config.database.adapter; - await pgAdapter.updateEstimatedCount('_Installation'); - - res = await router.handleFind(request); - response = res.response; - expect(response.results.length).toEqual(2); - expect(response.count).toEqual(2); + rest + .create(config, auth.nobody(config), '_Installation', androidDeviceRequest) + .then(() => { + return rest.create(config, auth.nobody(config), '_Installation', iosDeviceRequest); + }) + .then(() => { + return router.handleFind(request); + }) + .then(res => { + const response = res.response; + expect(response.results.length).toEqual(0); + expect(response.count).toEqual(2); + done(); + }) + .catch(err => { + fail(JSON.stringify(err)); + done(); + }); }); +}); - it_exclude_dbs(['postgres'])('query installations with limit = 0 and count = 1', done => { +describe_only_db('postgres')('InstallationsRouter', () => { + it_only_postgres_version('<14.0')('query installations with count = 1', async () => { const config = Config.get('test'); const androidDeviceRequest = { installationId: '12345678-abcd-abcd-abcd-123456789abc', @@ -218,30 +225,25 @@ describe('InstallationsRouter', () => { auth: auth.master(config), body: {}, query: { - limit: 0, count: 1, }, info: {}, }; const router = new InstallationsRouter(); - rest - .create(config, auth.nobody(config), '_Installation', androidDeviceRequest) - .then(() => { - return rest.create(config, auth.nobody(config), '_Installation', iosDeviceRequest); - }) - .then(() => { - return router.handleFind(request); - }) - .then(res => { - const response = res.response; - expect(response.results.length).toEqual(0); - expect(response.count).toEqual(2); - done(); - }) - .catch(err => { - fail(JSON.stringify(err)); - done(); - }); + await rest.create(config, auth.nobody(config), '_Installation', androidDeviceRequest); + await rest.create(config, auth.nobody(config), '_Installation', iosDeviceRequest); + let res = await router.handleFind(request); + let response = res.response; + expect(response.results.length).toEqual(2); + expect(response.count).toEqual(0); // estimate count is zero + + const pgAdapter = config.database.adapter; + await pgAdapter.updateEstimatedCount('_Installation'); + + res = await router.handleFind(request); + response = res.response; + expect(response.results.length).toEqual(2); + expect(response.count).toEqual(2); }); }); diff --git a/spec/ParseQuery.Aggregate.spec.js b/spec/ParseQuery.Aggregate.spec.js index 4d6ab59c40..c2232c501e 100644 --- a/spec/ParseQuery.Aggregate.spec.js +++ b/spec/ParseQuery.Aggregate.spec.js @@ -217,7 +217,7 @@ describe('Parse.Query Aggregate testing', () => { }); }); - it('group by date object', done => { + it_only_postgres_version('<14.0')('group by date object', done => { const obj1 = new TestObject(); const obj2 = new TestObject(); const obj3 = new TestObject(); @@ -248,7 +248,7 @@ describe('Parse.Query Aggregate testing', () => { }); }); - it('group by date object transform', done => { + it_only_postgres_version('<14.0')('group by date object transform', done => { const obj1 = new TestObject(); const obj2 = new TestObject(); const obj3 = new TestObject(); diff --git a/spec/helper.js b/spec/helper.js index 49de5c453f..612c716202 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -446,6 +446,15 @@ global.it_only_mongodb_version = version => { } }; +global.it_only_postgres_version = version => { + const envVersion = process.env.POSTGRES_VERSION; + if (!envVersion || semver.satisfies(envVersion, version)) { + return it; + } else { + return xit; + } +}; + global.fit_only_mongodb_version = version => { const envVersion = process.env.MONGODB_VERSION; if (!envVersion || semver.satisfies(envVersion, version)) { @@ -464,6 +473,15 @@ global.it_exclude_mongodb_version = version => { } }; +global.it_exclude_postgres_version = version => { + const envVersion = process.env.POSTGRES_VERSION; + if (!envVersion || !semver.satisfies(envVersion, version)) { + return it; + } else { + return xit; + } +}; + global.fit_exclude_mongodb_version = version => { const envVersion = process.env.MONGODB_VERSION; if (!envVersion || !semver.satisfies(envVersion, version)) { From 3708b3d0e86c32423af44e5703b3b676eed035ab Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 18 Oct 2021 13:05:30 -0400 Subject: [PATCH 02/16] Switch users when editing file --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12e020234b..11a0d80afe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -240,6 +240,7 @@ jobs: - name: Install dependencies run: npm ci - run: | + su - postgres bash scripts/before_script_postgres_conf.sh bash scripts/before_script_postgres.sh - run: npm run coverage From f2e61753472c516fc6d2bf3483640170efd7e2b8 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 18 Oct 2021 13:12:31 -0400 Subject: [PATCH 03/16] attempt switching users --- .github/workflows/ci.yml | 1 - scripts/before_script_postgres_conf.sh | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 11a0d80afe..12e020234b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -240,7 +240,6 @@ jobs: - name: Install dependencies run: npm ci - run: | - su - postgres bash scripts/before_script_postgres_conf.sh bash scripts/before_script_postgres.sh - run: npm run coverage diff --git a/scripts/before_script_postgres_conf.sh b/scripts/before_script_postgres_conf.sh index 6d0d5e2a9a..cc34db4442 100755 --- a/scripts/before_script_postgres_conf.sh +++ b/scripts/before_script_postgres_conf.sh @@ -4,6 +4,8 @@ set -e echo "[SCRIPT] Before Script :: Setup Parse Postgres configuration file" +su - postgres + cat >> ${PGDATA}/postgresql.conf < Date: Mon, 18 Oct 2021 13:53:03 -0400 Subject: [PATCH 04/16] don't run config script for now --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 12e020234b..9ce9e852af 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -240,7 +240,6 @@ jobs: - name: Install dependencies run: npm ci - run: | - bash scripts/before_script_postgres_conf.sh bash scripts/before_script_postgres.sh - run: npm run coverage env: From c8eab3a95246df6fab99bab12310617da8ca5f29 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 18 Oct 2021 14:51:33 -0400 Subject: [PATCH 05/16] fix postgres env var --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ce9e852af..e3f53084ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -223,6 +223,7 @@ jobs: env: PARSE_SERVER_TEST_DB: postgres PARSE_SERVER_TEST_DATABASE_URI: postgres://postgres:postgres@localhost:5432/parse_server_postgres_adapter_test_database + POSTGRES_VERSION: ${{ matrix.POSTGRES_VERSION }} NODE_VERSION: ${{ matrix.NODE_VERSION }} steps: - uses: actions/checkout@v2 From b7b6b1d61b5d51134c11fcd3117d742e779fe9e2 Mon Sep 17 00:00:00 2001 From: Corey Date: Mon, 18 Oct 2021 15:20:39 -0400 Subject: [PATCH 06/16] try config script --- .github/workflows/ci.yml | 1 + README.md | 2 +- scripts/before_script_postgres.sh | 1 - scripts/before_script_postgres_conf.sh | 30 ++++++++++++-------------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e3f53084ac..ce60c7354a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -241,6 +241,7 @@ jobs: - name: Install dependencies run: npm ci - run: | + bash scripts/before_script_postgres_conf.sh bash scripts/before_script_postgres.sh - run: npm run coverage env: diff --git a/README.md b/README.md index 7a4ceed8cd..a96dfb840a 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Snyk badge Node.js 12,14,15 MongoDB 4.0,4.2,4.4,5.0 - PostgreSQL 11,12,13,14 + PostgreSQL 11,12,13,14

Our Sponsors

diff --git a/scripts/before_script_postgres.sh b/scripts/before_script_postgres.sh index 3d2c9157ca..5c445c4df1 100755 --- a/scripts/before_script_postgres.sh +++ b/scripts/before_script_postgres.sh @@ -5,7 +5,6 @@ set -e echo "[SCRIPT] Before Script :: Setup Parse DB for Postgres" PGPASSWORD=postgres psql -v ON_ERROR_STOP=1 -h localhost -U postgres <<-EOSQL - SELECT pg_reload_conf(); CREATE DATABASE parse_server_postgres_adapter_test_database; \c parse_server_postgres_adapter_test_database; CREATE EXTENSION pgcrypto; diff --git a/scripts/before_script_postgres_conf.sh b/scripts/before_script_postgres_conf.sh index cc34db4442..ee0533302f 100755 --- a/scripts/before_script_postgres_conf.sh +++ b/scripts/before_script_postgres_conf.sh @@ -4,10 +4,6 @@ set -e echo "[SCRIPT] Before Script :: Setup Parse Postgres configuration file" -su - postgres - -cat >> ${PGDATA}/postgresql.conf <> ${PGDATA}/postgresql.conf < Date: Mon, 18 Oct 2021 15:25:00 -0400 Subject: [PATCH 07/16] fix config script --- scripts/before_script_postgres_conf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/before_script_postgres_conf.sh b/scripts/before_script_postgres_conf.sh index ee0533302f..ec471d9c3f 100755 --- a/scripts/before_script_postgres_conf.sh +++ b/scripts/before_script_postgres_conf.sh @@ -13,7 +13,7 @@ echo "[SCRIPT] Before Script :: Setup Parse Postgres configuration file" PGPASSWORD=postgres psql -v ON_ERROR_STOP=1 -h localhost -U postgres <<-EOSQL ALTER SYSTEM SET max_connections TO '200'; - ALTER SYSTEM SET shared_buffer TO '1536MB'; + ALTER SYSTEM SET shared_buffers TO '1536MB'; ALTER SYSTEM SET effective_cache_size TO '4608MB'; ALTER SYSTEM SET maintenance_work_mem TO '384MB'; ALTER SYSTEM SET checkpoint_completion_target TO '0.9'; From 33a41051e1143c23e5e0db025dcf3b6784ffa7f8 Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 30 Oct 2021 18:19:04 -0400 Subject: [PATCH 08/16] Postgres 14 adapter fixes --- README.md | 4 +- spec/InstallationsRouter.spec.js | 72 +++++++++---------- spec/ParseQuery.Aggregate.spec.js | 14 ++-- .../Postgres/PostgresStorageAdapter.js | 7 +- 4 files changed, 47 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 3ac242a7ea..397cec8029 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![Node Version](https://img.shields.io/badge/nodejs-12,_14,_15-green.svg?logo=node.js&style=flat)](https://nodejs.org) [![MongoDB Version](https://img.shields.io/badge/mongodb-4.0,_4.2,_4.4,_5.0-green.svg?logo=mongodb&style=flat)](https://www.mongodb.com) -[![Postgres Version](https://img.shields.io/badge/postgresql-11,_12,_13-green.svg?logo=postgresql&style=flat)](https://www.postgresql.org) +[![Postgres Version](https://img.shields.io/badge/postgresql-11,_12,_13,_14-green.svg?logo=postgresql&style=flat)](https://www.postgresql.org) [![auto-release](https://img.shields.io/badge/%F0%9F%9A%80-auto--release-9e34eb.svg)](https://github.com/parse-community/parse-dashboard/releases) [![npm latest version](https://img.shields.io/npm/v/parse-server/latest.svg)](https://www.npmjs.com/package/parse-server) @@ -121,7 +121,7 @@ Parse Server is continuously tested with the most recent releases of MongoDB to |-------------|----------------|------------------|--------------------| | MongoDB 4.0 | 4.0.27 | April 2022 | ✅ Fully compatible | | MongoDB 4.2 | 4.2.17 | TBD | ✅ Fully compatible | -| MongoDB 4.4 | 4.4.10 | TBD | ✅ Fully compatible | +| MongoDB 4.4 | 4.4.10 | TBD | ✅ Fully compatible | | MongoDB 5.0 | 5.0.3 | January 2024 | ✅ Fully compatible | #### PostgreSQL diff --git a/spec/InstallationsRouter.spec.js b/spec/InstallationsRouter.spec.js index 4448f08db9..8e5a80c135 100644 --- a/spec/InstallationsRouter.spec.js +++ b/spec/InstallationsRouter.spec.js @@ -166,7 +166,7 @@ describe('InstallationsRouter', () => { }); }); - it_exclude_dbs(['postgres'])('query installations with limit = 0 and count = 1', done => { + it_only_db('postgres')('query installations with count = 1', async () => { const config = Config.get('test'); const androidDeviceRequest = { installationId: '12345678-abcd-abcd-abcd-123456789abc', @@ -181,36 +181,29 @@ describe('InstallationsRouter', () => { auth: auth.master(config), body: {}, query: { - limit: 0, count: 1, }, info: {}, }; const router = new InstallationsRouter(); - rest - .create(config, auth.nobody(config), '_Installation', androidDeviceRequest) - .then(() => { - return rest.create(config, auth.nobody(config), '_Installation', iosDeviceRequest); - }) - .then(() => { - return router.handleFind(request); - }) - .then(res => { - const response = res.response; - expect(response.results.length).toEqual(0); - expect(response.count).toEqual(2); - done(); - }) - .catch(err => { - fail(JSON.stringify(err)); - done(); - }); + await rest.create(config, auth.nobody(config), '_Installation', androidDeviceRequest); + await rest.create(config, auth.nobody(config), '_Installation', iosDeviceRequest); + let res = await router.handleFind(request); + let response = res.response; + expect(response.results.length).toEqual(2); + expect(response.count).toEqual(0); // estimate count is zero + + const pgAdapter = config.database.adapter; + await pgAdapter.updateEstimatedCount('_Installation'); + + res = await router.handleFind(request); + response = res.response; + expect(response.results.length).toEqual(2); + expect(response.count).toEqual(2); }); -}); -describe_only_db('postgres')('InstallationsRouter', () => { - it_only_postgres_version('<14.0')('query installations with count = 1', async () => { + it_exclude_dbs(['postgres'])('query installations with limit = 0 and count = 1', done => { const config = Config.get('test'); const androidDeviceRequest = { installationId: '12345678-abcd-abcd-abcd-123456789abc', @@ -225,25 +218,30 @@ describe_only_db('postgres')('InstallationsRouter', () => { auth: auth.master(config), body: {}, query: { + limit: 0, count: 1, }, info: {}, }; const router = new InstallationsRouter(); - await rest.create(config, auth.nobody(config), '_Installation', androidDeviceRequest); - await rest.create(config, auth.nobody(config), '_Installation', iosDeviceRequest); - let res = await router.handleFind(request); - let response = res.response; - expect(response.results.length).toEqual(2); - expect(response.count).toEqual(0); // estimate count is zero - - const pgAdapter = config.database.adapter; - await pgAdapter.updateEstimatedCount('_Installation'); - - res = await router.handleFind(request); - response = res.response; - expect(response.results.length).toEqual(2); - expect(response.count).toEqual(2); + rest + .create(config, auth.nobody(config), '_Installation', androidDeviceRequest) + .then(() => { + return rest.create(config, auth.nobody(config), '_Installation', iosDeviceRequest); + }) + .then(() => { + return router.handleFind(request); + }) + .then(res => { + const response = res.response; + expect(response.results.length).toEqual(0); + expect(response.count).toEqual(2); + done(); + }) + .catch(err => { + fail(JSON.stringify(err)); + done(); + }); }); }); diff --git a/spec/ParseQuery.Aggregate.spec.js b/spec/ParseQuery.Aggregate.spec.js index c2232c501e..0462895ce1 100644 --- a/spec/ParseQuery.Aggregate.spec.js +++ b/spec/ParseQuery.Aggregate.spec.js @@ -217,15 +217,14 @@ describe('Parse.Query Aggregate testing', () => { }); }); - it_only_postgres_version('<14.0')('group by date object', done => { + it_only_db('postgres')('group by date object', done => { const obj1 = new TestObject(); const obj2 = new TestObject(); const obj3 = new TestObject(); const pipeline = [ { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { - objectId: { + $group: { + _id: { day: { $dayOfMonth: '$_updated_at' }, month: { $month: '$_created_at' }, year: { $year: '$_created_at' }, @@ -248,15 +247,14 @@ describe('Parse.Query Aggregate testing', () => { }); }); - it_only_postgres_version('<14.0')('group by date object transform', done => { + it_only_db('postgres')('group by date object transform', done => { const obj1 = new TestObject(); const obj2 = new TestObject(); const obj3 = new TestObject(); const pipeline = [ { - // TODO: update to new syntax. See [#7339](https://bit.ly/3incnWx) - group: { - objectId: { + $group: { + _id: { day: { $dayOfMonth: '$updatedAt' }, month: { $month: '$createdAt' }, year: { $year: '$createdAt' }, diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index 5d0e211ab4..916922295e 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -1980,10 +1980,11 @@ export class PostgresStorageAdapter implements StorageAdapter { } else { qs = 'SELECT reltuples AS approximate_row_count FROM pg_class WHERE relname = $1'; } - return this._client .one(qs, values, a => { - if (a.approximate_row_count != null) { + if (a.approximate_row_count == -1) { + return 0; + } else if (a.approximate_row_count != null) { return +a.approximate_row_count; } else { return +a.count; @@ -2111,7 +2112,7 @@ export class PostgresStorageAdapter implements StorageAdapter { columns.push( `EXTRACT(${ mongoAggregateToPostgres[operation] - } FROM $${index}:name AT TIME ZONE 'UTC') AS $${index + 1}:name` + } FROM $${index}:name AT TIME ZONE 'UTC')::integer AS $${index + 1}:name` ); values.push(source, alias); index += 2; From 38063976e505524406e4d6679b92b0ed3addfc66 Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 30 Oct 2021 18:30:13 -0400 Subject: [PATCH 09/16] test aggregate on Postgres --- spec/ParseQuery.Aggregate.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/ParseQuery.Aggregate.spec.js b/spec/ParseQuery.Aggregate.spec.js index 0462895ce1..04fa6068ed 100644 --- a/spec/ParseQuery.Aggregate.spec.js +++ b/spec/ParseQuery.Aggregate.spec.js @@ -217,7 +217,7 @@ describe('Parse.Query Aggregate testing', () => { }); }); - it_only_db('postgres')('group by date object', done => { + it('group by date object', done => { const obj1 = new TestObject(); const obj2 = new TestObject(); const obj3 = new TestObject(); @@ -247,7 +247,7 @@ describe('Parse.Query Aggregate testing', () => { }); }); - it_only_db('postgres')('group by date object transform', done => { + it('group by date object transform', done => { const obj1 = new TestObject(); const obj2 = new TestObject(); const obj3 = new TestObject(); From 1a0e4a35f861fd2faeb2266a077d5527c5c7eb6a Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 30 Oct 2021 18:50:28 -0400 Subject: [PATCH 10/16] remove postgres env var from CI --- .github/workflows/ci.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96b3de4745..628903944d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -183,23 +183,18 @@ jobs: include: - name: PostgreSQL 11, PostGIS 3.0 POSTGRES_IMAGE: postgis/postgis:11-3.0 - POSTGRES_VERSION: 11.13.0 NODE_VERSION: 14.18.1 - name: PostgreSQL 11, PostGIS 3.1 POSTGRES_IMAGE: postgis/postgis:11-3.1 - POSTGRES_VERSION: 11.13.0 NODE_VERSION: 14.18.1 - name: PostgreSQL 12, PostGIS 3.1 POSTGRES_IMAGE: postgis/postgis:12-3.1 - POSTGRES_VERSION: 12.8.0 NODE_VERSION: 14.18.1 - name: PostgreSQL 13, PostGIS 3.1 POSTGRES_IMAGE: postgis/postgis:13-3.1 - POSTGRES_VERSION: 13.4.0 NODE_VERSION: 14.18.1 - name: PostgreSQL 14, PostGIS 3.1 POSTGRES_IMAGE: postgis/postgis:14-3.1 - POSTGRES_VERSION: 14.0.0 NODE_VERSION: 14.18.1 fail-fast: false name: ${{ matrix.name }} @@ -224,7 +219,6 @@ jobs: env: PARSE_SERVER_TEST_DB: postgres PARSE_SERVER_TEST_DATABASE_URI: postgres://postgres:postgres@localhost:5432/parse_server_postgres_adapter_test_database - POSTGRES_VERSION: ${{ matrix.POSTGRES_VERSION }} NODE_VERSION: ${{ matrix.NODE_VERSION }} steps: - uses: actions/checkout@v2 From 6958d77fd7fb49e0d397349ea1ae60421f1a49ae Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 30 Oct 2021 19:22:00 -0400 Subject: [PATCH 11/16] improve postgres count change --- src/Adapters/Storage/Postgres/PostgresStorageAdapter.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index 916922295e..c3802bc2bd 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -1982,12 +1982,10 @@ export class PostgresStorageAdapter implements StorageAdapter { } return this._client .one(qs, values, a => { - if (a.approximate_row_count == -1) { - return 0; - } else if (a.approximate_row_count != null) { - return +a.approximate_row_count; - } else { + if (a.approximate_row_count == null || a.approximate_row_count == -1) { return +a.count; + } else { + return +a.approximate_row_count; } }) .catch(error => { From a126e15a6446040dd61b2bc0af7099bf8f3f19a5 Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 30 Oct 2021 19:46:29 -0400 Subject: [PATCH 12/16] revert last change --- README.md | 12 ++++++------ .../Storage/Postgres/PostgresStorageAdapter.js | 8 +++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 397cec8029..8b6b989930 100644 --- a/README.md +++ b/README.md @@ -127,12 +127,12 @@ Parse Server is continuously tested with the most recent releases of MongoDB to #### PostgreSQL Parse Server is continuously tested with the most recent releases of PostgreSQL and PostGIS to ensure compatibility, using [PostGIS docker images](https://registry.hub.docker.com/r/postgis/postgis/tags?page=1&ordering=last_updated). We follow the [PostgreSQL support schedule](https://www.postgresql.org/support/versioning) and [PostGIS support schedule](https://www.postgis.net/eol_policy/) and only test against versions that are officially supported and have not reached their end-of-life date. Due to the extensive PostgreSQL support duration of 5 years, Parse Server drops support if a version is older than 3.5 years and a newer version has been available for at least 2.5 years. -| Version | PostGIS Version | End-of-Life Date | Parse Server Support End | Compatibility | -|-------------|-----------------|------------------|--------------------------|--------------------| -| Postgres 11 | 3.0, 3.1 | November 2023 | April 2022 | ✅ Fully compatible | -| Postgres 12 | 3.1 | November 2024 | April 2023 | ✅ Fully compatible | -| Postgres 13 | 3.1 | November 2025 | April 2024 | ✅ Fully compatible | -| Postgres 14 | 3.1 | November 2026 | April 2025 | ✅ Fully compatible | +| Version | PostGIS Version | End-of-Life Date | Parse Server Support End | Compatibility | +|--------------|-----------------|------------------|--------------------------|--------------------| +| Postgres 11 | 3.0, 3.1 | November 2023 | April 2022 | ✅ Fully compatible | +| Postgres 12 | 3.1 | November 2024 | April 2023 | ✅ Fully compatible | +| Postgres 13 | 3.1 | November 2025 | April 2024 | ✅ Fully compatible | +| Postgres 14 | 3.1 | November 2026 | April 2025 | ✅ Fully compatible | ### Locally ```bash diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index c3802bc2bd..916922295e 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -1982,10 +1982,12 @@ export class PostgresStorageAdapter implements StorageAdapter { } return this._client .one(qs, values, a => { - if (a.approximate_row_count == null || a.approximate_row_count == -1) { - return +a.count; - } else { + if (a.approximate_row_count == -1) { + return 0; + } else if (a.approximate_row_count != null) { return +a.approximate_row_count; + } else { + return +a.count; } }) .catch(error => { From b363d819046642047b4d3f9660e4bf9bcb66290c Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 30 Oct 2021 19:56:37 -0400 Subject: [PATCH 13/16] reduce lines --- src/Adapters/Storage/Postgres/PostgresStorageAdapter.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index 916922295e..ec4d1019e8 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -1982,12 +1982,10 @@ export class PostgresStorageAdapter implements StorageAdapter { } return this._client .one(qs, values, a => { - if (a.approximate_row_count == -1) { - return 0; - } else if (a.approximate_row_count != null) { - return +a.approximate_row_count; + if (a.approximate_row_count == null || a.approximate_row_count == -1) { + return !isNaN(a.count) ? +a.count : 0; } else { - return +a.count; + return +a.approximate_row_count; } }) .catch(error => { From dcd7de06d5daaef0f2de98fb05d3dfa2175b88d6 Mon Sep 17 00:00:00 2001 From: Corey Date: Sat, 30 Oct 2021 20:15:14 -0400 Subject: [PATCH 14/16] nits --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8b6b989930..397cec8029 100644 --- a/README.md +++ b/README.md @@ -127,12 +127,12 @@ Parse Server is continuously tested with the most recent releases of MongoDB to #### PostgreSQL Parse Server is continuously tested with the most recent releases of PostgreSQL and PostGIS to ensure compatibility, using [PostGIS docker images](https://registry.hub.docker.com/r/postgis/postgis/tags?page=1&ordering=last_updated). We follow the [PostgreSQL support schedule](https://www.postgresql.org/support/versioning) and [PostGIS support schedule](https://www.postgis.net/eol_policy/) and only test against versions that are officially supported and have not reached their end-of-life date. Due to the extensive PostgreSQL support duration of 5 years, Parse Server drops support if a version is older than 3.5 years and a newer version has been available for at least 2.5 years. -| Version | PostGIS Version | End-of-Life Date | Parse Server Support End | Compatibility | -|--------------|-----------------|------------------|--------------------------|--------------------| -| Postgres 11 | 3.0, 3.1 | November 2023 | April 2022 | ✅ Fully compatible | -| Postgres 12 | 3.1 | November 2024 | April 2023 | ✅ Fully compatible | -| Postgres 13 | 3.1 | November 2025 | April 2024 | ✅ Fully compatible | -| Postgres 14 | 3.1 | November 2026 | April 2025 | ✅ Fully compatible | +| Version | PostGIS Version | End-of-Life Date | Parse Server Support End | Compatibility | +|-------------|-----------------|------------------|--------------------------|--------------------| +| Postgres 11 | 3.0, 3.1 | November 2023 | April 2022 | ✅ Fully compatible | +| Postgres 12 | 3.1 | November 2024 | April 2023 | ✅ Fully compatible | +| Postgres 13 | 3.1 | November 2025 | April 2024 | ✅ Fully compatible | +| Postgres 14 | 3.1 | November 2026 | April 2025 | ✅ Fully compatible | ### Locally ```bash From d14d5606c386fe3c4f190c18742a8fdf977b2203 Mon Sep 17 00:00:00 2001 From: Corey Date: Sun, 31 Oct 2021 10:16:53 -0400 Subject: [PATCH 15/16] nit --- src/Adapters/Storage/Postgres/PostgresStorageAdapter.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index ec4d1019e8..065d5c93a3 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -1980,10 +1980,11 @@ export class PostgresStorageAdapter implements StorageAdapter { } else { qs = 'SELECT reltuples AS approximate_row_count FROM pg_class WHERE relname = $1'; } + return this._client .one(qs, values, a => { if (a.approximate_row_count == null || a.approximate_row_count == -1) { - return !isNaN(a.count) ? +a.count : 0; + return !isNaN(+a.count) ? +a.count : 0; } else { return +a.approximate_row_count; } From 70864ee6147235ee82d999a46d77748e5a89b3e5 Mon Sep 17 00:00:00 2001 From: Corey Date: Sun, 31 Oct 2021 12:20:03 -0400 Subject: [PATCH 16/16] Point badges to alpha branch --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 397cec8029..7e4e0dce8b 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ --- -[![Build Status](https://github.com/parse-community/parse-server/workflows/ci/badge.svg?branch=master)](https://github.com/parse-community/parse-server/actions?query=workflow%3Aci+branch%3Amaster) +[![Build Status](https://github.com/parse-community/parse-server/workflows/ci/badge.svg?branch=alpha)](https://github.com/parse-community/parse-server/actions?query=workflow%3Aci+branch%3Aalpha) [![Snyk Badge](https://snyk.io/test/github/parse-community/parse-server/badge.svg)](https://snyk.io/test/github/parse-community/parse-server) -[![Coverage](https://img.shields.io/codecov/c/github/parse-community/parse-server/master.svg)](https://codecov.io/github/parse-community/parse-server?branch=master) +[![Coverage](https://img.shields.io/codecov/c/github/parse-community/parse-server/alpha.svg)](https://codecov.io/github/parse-community/parse-server?branch=alpha) [![Node Version](https://img.shields.io/badge/nodejs-12,_14,_15-green.svg?logo=node.js&style=flat)](https://nodejs.org) [![MongoDB Version](https://img.shields.io/badge/mongodb-4.0,_4.2,_4.4,_5.0-green.svg?logo=mongodb&style=flat)](https://www.mongodb.com)