diff --git a/examples/ionic-demo/README.md b/examples/ionic-demo/README.md index b83c4214b3..a959dd312b 100644 --- a/examples/ionic-demo/README.md +++ b/examples/ionic-demo/README.md @@ -14,11 +14,11 @@ # Electric Appointments: An ElectricSQL & Ionic Example -This is an example showing how to build an Ionic Framework app using ElectricSQL, including packaging if for iOS and Android using Capacitor. +This is an example showing how to build an Ionic Framework app using ElectricSQL, including packaging it for iOS and Android using Capacitor. The app is a simple appointment scheduling app, the type a company would use to schedule appointments with clients. It's split into two workflows, one for the customer to schedule an appointment, and one for an employee to view and administer their calendar. -When built for the web it uses the wa-sqlite driver, for iOS and android it uses the capacitor-sqlite driver. +When built for the web it uses the wa-sqlite driver. For iOS and Android it uses the capacitor-sqlite driver. ## Prereqs @@ -56,7 +56,7 @@ Note that, if useful, you can connect to Postgres using: npm run db:psql ``` -The [database schema](https://electric-sql.com/docs/usage/data-modelling) for this example is in `db/migrations/create_tables.sql`. +The [database schema](https://electric-sql.com/docs/usage/data-modelling) for this example is in `db/migrations/01-create_tables.sql`. You can apply it with: ```shell diff --git a/examples/ionic-demo/backend/compose/docker-compose.yaml b/examples/ionic-demo/backend/compose/docker-compose.yaml index 9c2a92c9ac..a00a3b917b 100644 --- a/examples/ionic-demo/backend/compose/docker-compose.yaml +++ b/examples/ionic-demo/backend/compose/docker-compose.yaml @@ -7,7 +7,6 @@ configs: volumes: pg_data: - electric_data: services: postgres: @@ -15,7 +14,7 @@ services: environment: POSTGRES_DB: ${APP_NAME:-electric} POSTGRES_USER: postgres - POSTGRES_PASSWORD: password + POSTGRES_PASSWORD: pg_password command: - -c - config_file=/etc/postgresql.conf @@ -35,8 +34,8 @@ services: image: "${ELECTRIC_IMAGE:-electricsql/electric:latest}" init: true environment: - DATABASE_URL: postgresql://postgres:password@postgres:5432/${APP_NAME:-electric} - PG_PROXY_PASSWORD: "password" + DATABASE_URL: postgresql://postgres:pg_password@postgres:5432/${APP_NAME:-electric} + PG_PROXY_PASSWORD: proxy_password LOGICAL_PUBLISHER_HOST: electric AUTH_MODE: insecure ports: diff --git a/examples/ionic-demo/change-ports.cjs b/examples/ionic-demo/change-ports.cjs index 03ccc57b30..03cc189ff5 100644 --- a/examples/ionic-demo/change-ports.cjs +++ b/examples/ionic-demo/change-ports.cjs @@ -61,13 +61,13 @@ async function init() { // Update port in package.json file await findAndReplaceInFile(`http://localhost:${oldElectricPort}`, `http://localhost:${electricPort}`, packageJsonFile) await findAndReplaceInFile( - `postgresql://prisma:password@localhost:${oldElectricProxyPort}/electric`, - `postgresql://prisma:password@localhost:${electricProxyPort}/electric`, packageJsonFile + `postgresql://prisma:proxy_password@localhost:${oldElectricProxyPort}/electric`, + `postgresql://prisma:proxy_password@localhost:${electricProxyPort}/electric`, packageJsonFile ) - + // Update the port on which Electric runs in the builder.js file await findAndReplaceInFile(`ws://localhost:${oldElectricPort}`, `ws://localhost:${electricPort}`, builderFile) - + // Update the port on which Electric and its proxy run in startElectric.js file const startElectricFile = path.join(__dirname, 'backend', 'startElectric.js') await findAndReplaceInFile(oldElectricPort, `${electricPort}`, startElectricFile) @@ -132,4 +132,4 @@ async function checkPort(port, process, defaultPort) { // user changed port, check that it is free return checkPort(newPort, process, defaultPort) } -} \ No newline at end of file +} diff --git a/examples/ionic-demo/db/connect.cjs b/examples/ionic-demo/db/connect.cjs index c8daa00c37..7df33fa1db 100644 --- a/examples/ionic-demo/db/connect.cjs +++ b/examples/ionic-demo/db/connect.cjs @@ -1,6 +1,6 @@ const { dockerCompose } = require('../util/util.cjs') -const { DATABASE_NAME, PUBLIC_DATABASE_URL } = require('./util.cjs') +const { CONTAINER_DATABASE_URL, PUBLIC_DATABASE_URL } = require('./util.cjs') -console.info(`Connecting to postgres at ${PUBLIC_DATABASE_URL}`) +console.info(`Connecting to proxy at ${PUBLIC_DATABASE_URL}`) -dockerCompose('exec', ['-it', 'postgres', 'psql', '-U', 'postgres', DATABASE_NAME]) +dockerCompose('exec', ['-it', 'postgres', 'psql', CONTAINER_DATABASE_URL]) diff --git a/examples/ionic-demo/db/migrate.cjs b/examples/ionic-demo/db/migrate.cjs index df4760e89e..17070cdb61 100644 --- a/examples/ionic-demo/db/migrate.cjs +++ b/examples/ionic-demo/db/migrate.cjs @@ -2,7 +2,7 @@ const { DATABASE_URL, PUBLIC_DATABASE_URL } = require('./util.cjs') const { spawn } = require('child_process') const process = require('process') -console.info(`Connecting to postgres at ${PUBLIC_DATABASE_URL}`) +console.info(`Connecting to proxy at ${PUBLIC_DATABASE_URL}`) const args = ["run", "-s", "pg-migrations", "apply", "--database", DATABASE_URL, "--directory", "./db/migrations"] const proc = spawn("yarn", args, { cwd: __dirname, stdio: ['inherit', 'pipe', 'inherit'] }) diff --git a/examples/ionic-demo/db/util.cjs b/examples/ionic-demo/db/util.cjs index bc0ed4a39e..2ab48d5550 100644 --- a/examples/ionic-demo/db/util.cjs +++ b/examples/ionic-demo/db/util.cjs @@ -3,19 +3,34 @@ const path = require('path') const shell = require('shelljs') shell.config.silent = true // don't log output of child processes -// If we are running the docker compose file -// there will be an electric container running -// which binds the container's 65432 port used by the proxy -// to some port on the host machine. -// So we fetch this host port and use it in the default url. +// If we are running the docker compose file, +// the container running `electric` service will be exposing +// the proxy port which should be used for all DB connections +// that intend to use the DDLX syntax extension of SQL. const appName = fetchAppName() ?? 'electric' const proxyPort = fetchHostProxyPortElectric() ?? 65432 -const DEFAULT_URL = `postgresql://electric:password@localhost:${proxyPort}/${appName}` -const DATABASE_URL = process.env.DATABASE_URL || DEFAULT_URL -const PUBLIC_DATABASE_URL = DATABASE_URL.split('@')[1] +const dbUser = 'postgres' +const proxyPassword = 'proxy_password' -const urlComponents = DATABASE_URL.split('/') -const DATABASE_NAME = urlComponents[urlComponents.length-1] +// URL to use when connecting to the proxy from the host OS +const DATABASE_URL = buildDatabaseURL(dbUser, proxyPassword, 'localhost', proxyPort, appName) + +// URL to use when connecting to the proxy from a Docker container. This is used when `psql` is exec'd inside the +// `postgres` service's container to connect to the poxy running in the `electric` service's container. +const CONTAINER_DATABASE_URL = buildDatabaseURL(dbUser, proxyPassword, 'electric', 65432, appName) + +// URL to display in the terminal for informational purposes. It omits the password but is still a valid URL that can be +// passed to `psql` running on the host OS. +const PUBLIC_DATABASE_URL = buildDatabaseURL(dbUser, null, 'localhost', proxyPort, appName) + +function buildDatabaseURL(user, password, host, port, dbName) { + let url = 'postgresql://' + user + if (password) { + url += ':' + password + } + url += '@' + host + ':' + port + '/' + dbName + return url +} function error(err) { console.error('\x1b[31m', err, '\x1b[0m') @@ -67,7 +82,7 @@ function fetchAppName() { } exports.DATABASE_URL = DATABASE_URL +exports.CONTAINER_DATABASE_URL = CONTAINER_DATABASE_URL exports.PUBLIC_DATABASE_URL = PUBLIC_DATABASE_URL -exports.DATABASE_NAME = DATABASE_NAME exports.fetchHostPortElectric = fetchHostPortElectric exports.fetchHostProxyPortElectric = fetchHostProxyPortElectric diff --git a/examples/ionic-demo/package-lock.json b/examples/ionic-demo/package-lock.json index 937b516dd3..019be6c717 100644 --- a/examples/ionic-demo/package-lock.json +++ b/examples/ionic-demo/package-lock.json @@ -1,12 +1,12 @@ { "name": "electric-appointments", - "version": "0.0.1", + "version": "0.7.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "electric-appointments", - "version": "0.0.1", + "version": "0.7.0", "dependencies": { "@capacitor-community/sqlite": "^5.4.1", "@capacitor/android": "^5.4.1", diff --git a/examples/ionic-demo/package.json b/examples/ionic-demo/package.json index dc1f52ccf3..061747e8ab 100644 --- a/examples/ionic-demo/package.json +++ b/examples/ionic-demo/package.json @@ -1,14 +1,14 @@ { "name": "electric-appointments", "private": true, - "version": "0.0.1", + "version": "0.7.0", "type": "module", "scripts": { "backend:start": "node ./backend/startCompose.cjs", "backend:stop": "docker compose --env-file backend/compose/.envrc -f backend/compose/docker-compose.yaml stop", "backend:up": "node ./backend/startCompose.cjs --detach", "backend:down": "docker compose --env-file backend/compose/.envrc -f backend/compose/docker-compose.yaml down --volumes", - "client:generate": "yarn electric:check && npx electric-sql generate --service http://localhost:5133 --proxy postgresql://prisma:password@localhost:65432/electric", + "client:generate": "npm run electric:check && npx electric-sql generate --service http://localhost:5133 --proxy postgresql://prisma:proxy_password@localhost:65432/electric", "client:watch": "npm run client:generate --watch", "db:migrate": "node ./db/migrate.cjs", "db:psql": "node ./db/connect.cjs", @@ -74,7 +74,9 @@ "jsdom": "^22.1.0", "prettier": "3.0.3", "prisma": "4.8.1", + "prompt": "^1.3.0", "shelljs": "^0.8.5", + "tcp-port-used": "^1.0.2", "typescript": "^5.1.6", "vite": "^4.3.9", "vitest": "^0.32.2"