From 3d1147c353d96c1d735509db9382d49de84d770e Mon Sep 17 00:00:00 2001 From: Ali Ok Date: Fri, 20 Jul 2018 10:39:30 +0300 Subject: [PATCH 1/5] Postgres data source - set up scripts --- README.md | 47 +++++++++-- docker-compose.yml | 9 +++ examples/memeolist.tables.sql | 6 ++ package.json | 6 +- ...-example.js => memeolist-example-inmem.js} | 0 .../seeders/memeolist-example-postgres.js | 79 +++++++++++++++++++ server/lib/resolvers/builders/postgres.js | 2 - 7 files changed, 140 insertions(+), 9 deletions(-) create mode 100644 examples/memeolist.tables.sql rename sequelize/seeders/{20180711143600-memeolist-example.js => memeolist-example-inmem.js} (100%) create mode 100644 sequelize/seeders/memeolist-example-postgres.js diff --git a/README.md b/README.md index 28ae1c8..1c248df 100644 --- a/README.md +++ b/README.md @@ -14,20 +14,37 @@ npm install ### Start and Initialize the Database -Use docker compose to start the database. +Use docker compose to start the database(s). ``` docker-compose up ``` +There are 2 Postgres instances defined in docker-compose configuration: +1. For storing the configuration of the sync server itself +2. For storing the [Memeolist](#whats-memeolist) data. + +Since docker-compose is only used with development, starting up the Postgres instance for [Memeolist](#whats-memeolist) +will not cause any harm. + Initialize the database in another terminal. ``` +# no sample schema/resolvers npm run db:init + +# sample schema/resolvers for memeolist - in-memory data source +npm run db:init:memeo:inmem + +# sample schema/resolvers for memeolist - Postgres data source +npm run db:init:memeo:postgres ``` -`npm run db:init` sets up the necessary tables and seeds the database with data useful for local development. **It is a destructive action.** It drops and recreates the tables every time. +`npm run db:init*` commands set up the necessary tables. **Those are destructive actions.** +They drop and recreate the tables every time. +`npm run db:init:memeo:*` commands are useful for local development which and seed the database with config and tables +for [Memeolist](#whats-memeolist) sample application. ### Start the Server @@ -165,8 +182,28 @@ The baseline architecture is shown below: ## Memeolist -To start the application with MemeoList schema and queries run +### What's Memeolist? + +Memeolist is an application where AeroGear team targets testing AeroGear mobile services and SDKs on it. + +You can see the specification for it here: https://github.com/aerogear/proposals/blob/master/dogfood.md + +There is some tooling adjusted to create Memeolist app's backend within the project. + +### Memeolist - In memory + +To start the application with MemeoList schema and queries with an in-memory data source, run these commands: +``` +docker-compose up +npm run db:init:memeo:inmem +npm run dev:memeo ``` -npm run db:init:memeo + +### Memeolist - Postgres + +To start the application with MemeoList schema and queries with an Postgres source, run these commands: +``` +docker-compose up +npm run db:init:memeo:postgres npm run dev:memeo -``` \ No newline at end of file +``` \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index ae69b28..2db665a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,5 +9,14 @@ services: POSTGRES_PASSWORD: postgres POSTGRES_USER: postgresql POSTGRES_DB: aerogear_data_sync_db + + postgres_memeo: + image: postgres:9.6 + ports: + - "15432:5432" + environment: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgresql + POSTGRES_DB: memeolist_db volumes: - ./examples:/tmp/examples \ No newline at end of file diff --git a/examples/memeolist.tables.sql b/examples/memeolist.tables.sql new file mode 100644 index 0000000..23fc400 --- /dev/null +++ b/examples/memeolist.tables.sql @@ -0,0 +1,6 @@ +DROP TABLE IF EXISTS "Meme"; + +CREATE TABLE "Meme" ( + "id" SERIAL NOT NULL, + "photoUrl" CHARACTER VARYING(500) NOT NULL +); diff --git a/package.json b/package.json index dd3353b..314daa7 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,10 @@ "docker:push:release": "./scripts/docker_push_release.sh", "release:validate": "./scripts/validateRelease.sh", "db:init": "FORCE_DROP=true node ./scripts/sync_models", - "db:init:memeo": "FORCE_DROP=true node ./scripts/sync_models && sequelize db:seed --seed 20180711143600-memeolist-example.js", - "db:shell": "docker exec -it aerogeardatasyncserver_postgres_1 psql -U postgresql -d aerogear_data_sync_db" + "db:init:memeo:inmem": "FORCE_DROP=true node ./scripts/sync_models && sequelize db:seed --seed memeolist-example-inmem.js", + "db:init:memeo:postgres": "FORCE_DROP=true node ./scripts/sync_models && sequelize db:seed --seed memeolist-example-postgres.js && docker exec aerogeardatasyncserver_postgres_memeo_1 psql -U postgres -d memeolist_db -f /tmp/examples/memeolist.tables.sql", + "db:shell": "docker exec -it aerogeardatasyncserver_postgres_1 psql -U postgresql -d aerogear_data_sync_db", + "db:shell:memeo": "docker exec -it aerogeardatasyncserver_postgres_memeo_1 psql -U postgresql -d memeolist_db" }, "devDependencies": { "apollo-fetch": "^0.7.0", diff --git a/sequelize/seeders/20180711143600-memeolist-example.js b/sequelize/seeders/memeolist-example-inmem.js similarity index 100% rename from sequelize/seeders/20180711143600-memeolist-example.js rename to sequelize/seeders/memeolist-example-inmem.js diff --git a/sequelize/seeders/memeolist-example-postgres.js b/sequelize/seeders/memeolist-example-postgres.js new file mode 100644 index 0000000..8673fa7 --- /dev/null +++ b/sequelize/seeders/memeolist-example-postgres.js @@ -0,0 +1,79 @@ +'use strict' + +const time = new Date() + +const datasources = [ + { + id: 2, + name: 'nedb_postgres', + type: 'Postgres', + config: `{"options":{ + "user": "postgresql", + "password": "postgres", + "database": "memeolist_db", + "host": "127.0.0.1", + "port": "15432", + "dialect": "postgres" + }}`, + createdAt: time, + updatedAt: time + } +] + +const notesSchema = { + id: 2, + name: 'default', + schema: ` + + type Meme { + id: ID! @isUnique + photoUrl: String! + } + + type Query { + allMemes:[Meme!]! + } + + type Mutation { + createMeme(photoUrl: String!):Meme! + } + + type Subscription { + _: Boolean + } + + `, + createdAt: time, + updatedAt: time +} + +const resolvers = [ + { + type: 'Query', + field: 'allMemes', + DataSourceId: 2, + GraphQLSchemaId: 2, + requestMapping: 'SELECT "id", "photoUrl" FROM "Meme"', + responseMapping: '{{ toJSON context.result }}', + createdAt: time, + updatedAt: time + }, + { + type: 'Mutation', + field: 'createMeme', + DataSourceId: 2, + GraphQLSchemaId: 2, + requestMapping: `INSERT INTO "Meme" ("photoUrl") VALUES ('{{context.arguments.photoUrl}}') RETURNING *;`, + responseMapping: '{{ toJSON context.result.[0] }}', + createdAt: time, + updatedAt: time + } +] + +module.exports = { + up: async (queryInterface, Sequelize) => { + await queryInterface.bulkInsert('DataSources', datasources, {}) + await queryInterface.bulkInsert('GraphQLSchemas', [notesSchema], {}) + return queryInterface.bulkInsert('Resolvers', resolvers, {}) + } +} diff --git a/server/lib/resolvers/builders/postgres.js b/server/lib/resolvers/builders/postgres.js index 3513c77..e2427b1 100644 --- a/server/lib/resolvers/builders/postgres.js +++ b/server/lib/resolvers/builders/postgres.js @@ -11,8 +11,6 @@ function buildPostgresResolver (dataSourceClient, compiledRequestMapping, compil dataSourceClient.query(queryString, [], (err, res) => { if (err) return reject(err) - // TODO: should we end the connection with each request? - // dataSourceClient.end() const responseString = compiledResponseMapping({ context: { From 9cdb7c31adff6eb399fa8ebd3f728b8dd52462da Mon Sep 17 00:00:00 2001 From: Ali Ok Date: Fri, 20 Jul 2018 10:43:00 +0300 Subject: [PATCH 2/5] Rename notesSchema in sample data to memeoListSchema --- sequelize/seeders/memeolist-example-inmem.js | 4 ++-- sequelize/seeders/memeolist-example-postgres.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sequelize/seeders/memeolist-example-inmem.js b/sequelize/seeders/memeolist-example-inmem.js index 5fb704e..57348a0 100644 --- a/sequelize/seeders/memeolist-example-inmem.js +++ b/sequelize/seeders/memeolist-example-inmem.js @@ -13,7 +13,7 @@ const datasources = [ } ] -const notesSchema = { +const memeoListSchema = { id: 2, name: 'default', schema: ` @@ -72,7 +72,7 @@ const resolvers = [ module.exports = { up: async (queryInterface, Sequelize) => { await queryInterface.bulkInsert('DataSources', datasources, {}) - await queryInterface.bulkInsert('GraphQLSchemas', [notesSchema], {}) + await queryInterface.bulkInsert('GraphQLSchemas', [memeoListSchema], {}) return queryInterface.bulkInsert('Resolvers', resolvers, {}) } } diff --git a/sequelize/seeders/memeolist-example-postgres.js b/sequelize/seeders/memeolist-example-postgres.js index 8673fa7..e322a9b 100644 --- a/sequelize/seeders/memeolist-example-postgres.js +++ b/sequelize/seeders/memeolist-example-postgres.js @@ -20,7 +20,7 @@ const datasources = [ } ] -const notesSchema = { +const memeoListSchema = { id: 2, name: 'default', schema: ` @@ -73,7 +73,7 @@ const resolvers = [ module.exports = { up: async (queryInterface, Sequelize) => { await queryInterface.bulkInsert('DataSources', datasources, {}) - await queryInterface.bulkInsert('GraphQLSchemas', [notesSchema], {}) + await queryInterface.bulkInsert('GraphQLSchemas', [memeoListSchema], {}) return queryInterface.bulkInsert('Resolvers', resolvers, {}) } } From 0bdf5944fb0241b287786cee5dc2fdb7e46123c0 Mon Sep 17 00:00:00 2001 From: Ali Ok Date: Fri, 20 Jul 2018 10:47:22 +0300 Subject: [PATCH 3/5] Extract memeolist schema to reuse it in multiple configs --- sequelize/seeders/memeolist-example-inmem.js | 39 ++++--------------- .../seeders/memeolist-example-postgres.js | 39 ++++--------------- sequelize/seeders/memeolist-example-shared.js | 34 ++++++++++++++++ 3 files changed, 48 insertions(+), 64 deletions(-) create mode 100644 sequelize/seeders/memeolist-example-shared.js diff --git a/sequelize/seeders/memeolist-example-inmem.js b/sequelize/seeders/memeolist-example-inmem.js index 57348a0..22fbecc 100644 --- a/sequelize/seeders/memeolist-example-inmem.js +++ b/sequelize/seeders/memeolist-example-inmem.js @@ -1,10 +1,12 @@ 'use strict' +const {memeoListSchema} = require('./memeolist-example-shared') + const time = new Date() const datasources = [ { - id: 2, + id: 1, name: 'nedb_memeolist', type: 'InMemory', config: '{"options":{"timestampData":true}}', @@ -13,39 +15,12 @@ const datasources = [ } ] -const memeoListSchema = { - id: 2, - name: 'default', - schema: ` - - type Meme { - id: ID! @isUnique - photoUrl: String! - } - - type Query { - allMemes:[Meme!]! - } - - type Mutation { - createMeme(photoUrl: String!):Meme! - } - - type Subscription { - _: Boolean - } - - `, - createdAt: time, - updatedAt: time -} - const resolvers = [ { type: 'Query', field: 'allMemes', - DataSourceId: 2, - GraphQLSchemaId: 2, + DataSourceId: 1, + GraphQLSchemaId: 1, requestMapping: '{"operation": "find", "query": {"_type":"meme"}}', responseMapping: '{{ toJSON (convertNeDBIds context.result) }}', createdAt: time, @@ -54,8 +29,8 @@ const resolvers = [ { type: 'Mutation', field: 'createMeme', - DataSourceId: 2, - GraphQLSchemaId: 2, + DataSourceId: 1, + GraphQLSchemaId: 1, requestMapping: `{ "operation": "insert", "doc": { diff --git a/sequelize/seeders/memeolist-example-postgres.js b/sequelize/seeders/memeolist-example-postgres.js index e322a9b..4f188e5 100644 --- a/sequelize/seeders/memeolist-example-postgres.js +++ b/sequelize/seeders/memeolist-example-postgres.js @@ -1,10 +1,12 @@ 'use strict' +const {memeoListSchema} = require('./memeolist-example-shared') + const time = new Date() const datasources = [ { - id: 2, + id: 1, name: 'nedb_postgres', type: 'Postgres', config: `{"options":{ @@ -20,39 +22,12 @@ const datasources = [ } ] -const memeoListSchema = { - id: 2, - name: 'default', - schema: ` - - type Meme { - id: ID! @isUnique - photoUrl: String! - } - - type Query { - allMemes:[Meme!]! - } - - type Mutation { - createMeme(photoUrl: String!):Meme! - } - - type Subscription { - _: Boolean - } - - `, - createdAt: time, - updatedAt: time -} - const resolvers = [ { type: 'Query', field: 'allMemes', - DataSourceId: 2, - GraphQLSchemaId: 2, + DataSourceId: 1, + GraphQLSchemaId: 1, requestMapping: 'SELECT "id", "photoUrl" FROM "Meme"', responseMapping: '{{ toJSON context.result }}', createdAt: time, @@ -61,8 +36,8 @@ const resolvers = [ { type: 'Mutation', field: 'createMeme', - DataSourceId: 2, - GraphQLSchemaId: 2, + DataSourceId: 1, + GraphQLSchemaId: 1, requestMapping: `INSERT INTO "Meme" ("photoUrl") VALUES ('{{context.arguments.photoUrl}}') RETURNING *;`, responseMapping: '{{ toJSON context.result.[0] }}', createdAt: time, diff --git a/sequelize/seeders/memeolist-example-shared.js b/sequelize/seeders/memeolist-example-shared.js new file mode 100644 index 0000000..1612ab3 --- /dev/null +++ b/sequelize/seeders/memeolist-example-shared.js @@ -0,0 +1,34 @@ +'use strict' + +const time = new Date() + +const memeoListSchema = { + id: 1, + name: 'default', + schema: ` + + type Meme { + id: ID! @isUnique + photoUrl: String! + } + + type Query { + allMemes:[Meme!]! + } + + type Mutation { + createMeme(photoUrl: String!):Meme! + } + + type Subscription { + _: Boolean + } + + `, + createdAt: time, + updatedAt: time +} + +module.exports = { + schema: memeoListSchema +} From db42c63874f02b3991f543702aa8c06d00871b21 Mon Sep 17 00:00:00 2001 From: Ali Ok Date: Fri, 20 Jul 2018 11:28:53 +0300 Subject: [PATCH 4/5] Extract memeolist schema to reuse it in multiple configs --- sequelize/seeders/memeolist-example-inmem.js | 4 ++-- sequelize/seeders/memeolist-example-postgres.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sequelize/seeders/memeolist-example-inmem.js b/sequelize/seeders/memeolist-example-inmem.js index 22fbecc..a96f7ea 100644 --- a/sequelize/seeders/memeolist-example-inmem.js +++ b/sequelize/seeders/memeolist-example-inmem.js @@ -1,6 +1,6 @@ 'use strict' -const {memeoListSchema} = require('./memeolist-example-shared') +const {schema} = require('./memeolist-example-shared') const time = new Date() @@ -47,7 +47,7 @@ const resolvers = [ module.exports = { up: async (queryInterface, Sequelize) => { await queryInterface.bulkInsert('DataSources', datasources, {}) - await queryInterface.bulkInsert('GraphQLSchemas', [memeoListSchema], {}) + await queryInterface.bulkInsert('GraphQLSchemas', [schema], {}) return queryInterface.bulkInsert('Resolvers', resolvers, {}) } } diff --git a/sequelize/seeders/memeolist-example-postgres.js b/sequelize/seeders/memeolist-example-postgres.js index 4f188e5..4171096 100644 --- a/sequelize/seeders/memeolist-example-postgres.js +++ b/sequelize/seeders/memeolist-example-postgres.js @@ -1,6 +1,6 @@ 'use strict' -const {memeoListSchema} = require('./memeolist-example-shared') +const {schema} = require('./memeolist-example-shared') const time = new Date() @@ -48,7 +48,7 @@ const resolvers = [ module.exports = { up: async (queryInterface, Sequelize) => { await queryInterface.bulkInsert('DataSources', datasources, {}) - await queryInterface.bulkInsert('GraphQLSchemas', [memeoListSchema], {}) + await queryInterface.bulkInsert('GraphQLSchemas', [schema], {}) return queryInterface.bulkInsert('Resolvers', resolvers, {}) } } From 21c97a200878ba5a8ba0c508925a90fb102712f4 Mon Sep 17 00:00:00 2001 From: Ali Ok Date: Fri, 20 Jul 2018 17:19:44 +0300 Subject: [PATCH 5/5] Add project namespace to docker-compose commands in the documentation --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1c248df..2cde7b5 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ npm install Use docker compose to start the database(s). ``` -docker-compose up +docker-compose -p aerogeardatasyncserver up ``` There are 2 Postgres instances defined in docker-compose configuration: @@ -67,7 +67,7 @@ npm run db:shell The Postgres container started by `docker-compose` can be stopped with `Ctrl + C`. To remove it fully: ``` -docker-compose rm +docker-compose -p aerogeardatasyncserver rm Going to remove aerogeardatasyncserver_postgres_1 Are you sure? [yN] y @@ -83,7 +83,7 @@ npm run test:unit Start the database first: ``` -docker-compose up +docker-compose -p aerogeardatasyncserver up ``` Then, in a separate session, init the database (blank) and start the application: @@ -194,7 +194,7 @@ There is some tooling adjusted to create Memeolist app's backend within the proj To start the application with MemeoList schema and queries with an in-memory data source, run these commands: ``` -docker-compose up +docker-compose -p aerogeardatasyncserver up npm run db:init:memeo:inmem npm run dev:memeo ``` @@ -203,7 +203,7 @@ npm run dev:memeo To start the application with MemeoList schema and queries with an Postgres source, run these commands: ``` -docker-compose up +docker-compose -p aerogeardatasyncserver up npm run db:init:memeo:postgres npm run dev:memeo ``` \ No newline at end of file