Skip to content

Commit 7db24c4

Browse files
authored
Add devcontainer (#246)
* Add devcontainer * Update settings.gradle.kts * Update CD.yml * Update CI.yml * Update CD.yml * Update CI.yml * wip * wip * asdf * Add devcontainer * Fix error message * Fix error message * Update PostgresNativeDriverTest.kt * Fix tests * a * jhjgh * hbjh * Update libpq.def * Use env in test * Use env in test * add vscode extensions * Remove docker in docker * Support macOS 14 * Support macOS 14 * Support macOS 14 * Support macOS 14 * Support macOS latest * Support macOS latest * Support macOS latest * Support macOS latest * Support macOS latest * test * test * test * test * test * test --------- Co-authored-by: hfhbd <[email protected]>
1 parent 2135fc3 commit 7db24c4

File tree

17 files changed

+323
-90
lines changed

17 files changed

+323
-90
lines changed

.devcontainer/Dockerfile

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM mcr.microsoft.com/devcontainers/java:21
2+
3+
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
4+
&& apt-get -y install --no-install-recommends libpq-dev

.devcontainer/devcontainer.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"dockerComposeFile": "docker-compose.yml",
3+
"service": "app",
4+
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
5+
"features": {
6+
"ghcr.io/devcontainers/features/sshd:1": {}
7+
},
8+
9+
"forwardPorts": [
10+
5432
11+
]
12+
}

.devcontainer/docker-compose.yml

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
version: '3.8'
2+
3+
services:
4+
app:
5+
container_name: javadev
6+
# https://youtrack.jetbrains.com/issue/KT-36871/Support-Aarch64-Linux-as-a-host-for-the-Kotlin-Native
7+
platform: "linux/amd64"
8+
build:
9+
context: .
10+
dockerfile: Dockerfile
11+
environment:
12+
POSTGRES_HOSTNAME: postgresdb
13+
POSTGRES_DB: postgres
14+
POSTGRES_USER: postgres
15+
POSTGRES_PASSWORD: password
16+
17+
volumes:
18+
- ../..:/workspaces:cached
19+
20+
command: sleep infinity
21+
22+
network_mode: service:db
23+
24+
db:
25+
container_name: postgresdb
26+
image: postgres:latest
27+
restart: unless-stopped
28+
healthcheck:
29+
test: [ "CMD-SHELL", "pg_isready" ]
30+
interval: 1s
31+
timeout: 5s
32+
retries: 10
33+
environment:
34+
POSTGRES_DB: postgres
35+
POSTGRES_USER: postgres
36+
POSTGRES_PASSWORD: password
37+
ports:
38+
- "5432:5432"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
name: Setup PostgreSQL for Linux/macOS/Windows
2+
author: Ihor Kalnytskyi
3+
description: Setup a preinstalled PostgreSQL server.
4+
branding:
5+
icon: database
6+
color: purple
7+
inputs:
8+
username:
9+
description: The username of the user to setup.
10+
default: postgres
11+
required: false
12+
password:
13+
description: The password of the user to setup.
14+
default: postgres
15+
required: false
16+
database:
17+
description: The database name to setup and grant permissions to created user.
18+
default: postgres
19+
required: false
20+
port:
21+
description: The server port to listen on.
22+
default: "5432"
23+
required: false
24+
outputs:
25+
connection-uri:
26+
description: The connection URI to connect to PostgreSQL.
27+
value: ${{ steps.set-outputs.outputs.connection-uri }}
28+
service-name:
29+
description: The service name with connection parameters.
30+
value: ${{ steps.set-outputs.outputs.service-name }}
31+
runs:
32+
using: composite
33+
steps:
34+
- name: Prerequisites
35+
run: |
36+
if [ "$RUNNER_OS" == "Linux" ]; then
37+
echo "$(pg_config --bindir)" >> $GITHUB_PATH
38+
elif [ "$RUNNER_OS" == "Windows" ]; then
39+
echo "$PGBIN" >> $GITHUB_PATH
40+
echo "PQ_LIB_DIR=$PGROOT\lib" >> $GITHUB_ENV
41+
42+
# The Windows runner has some PostgreSQL environment variables set
43+
# that may confuse users since they may be irrelevant to the
44+
# PostgreSQL server we're using.
45+
for name in "PGROOT" "PGDATA" "PGBIN" "PGUSER" "PGPASSWORD"; do
46+
echo "$name=" >> $GITHUB_ENV
47+
done
48+
elif [ "$RUNNER_OS" == "macOS" ]; then
49+
case "$(sw_vers -productVersion)" in
50+
12.*|13.*)
51+
brew install postgresql@14
52+
echo "/usr/local/opt/postgresql@14/bin" >> $GITHUB_PATH
53+
;;
54+
14.*)
55+
brew install postgresql@16
56+
echo "/opt/homebrew/opt/postgresql@16/bin" >> $GITHUB_PATH
57+
;;
58+
esac
59+
fi
60+
shell: bash
61+
62+
- name: Setup and start PostgreSQL
63+
run: |
64+
export PGDATA="$RUNNER_TEMP/pgdata"
65+
export PWFILE="$RUNNER_TEMP/pwfile"
66+
67+
# Unfortunately 'initdb' could only receive a password via file on disk
68+
# or prompt to enter on. Prompting is not an option since we're running
69+
# in non-interactive mode.
70+
echo '${{ inputs.password }}' > $PWFILE
71+
72+
# There are couple of reasons why we need to create a new PostgreSQL
73+
# database cluster. First and foremost, we have to create a superuser
74+
# with provided credentials. Second, we want the PostgreSQL client
75+
# applications [1] to be available for execution without
76+
# run-from-another-user dances. Third, we want to make sure that
77+
# settings are the same between operating systems and aren't changed by
78+
# package vendors.
79+
#
80+
# [1] https://www.postgresql.org/docs/15/reference-client.html
81+
initdb \
82+
--username="${{ inputs.username }}" \
83+
--pwfile="$PWFILE" \
84+
--auth="scram-sha-256" \
85+
--encoding="UTF-8" \
86+
--locale="en_US.UTF-8" \
87+
--no-instructions
88+
89+
# Do not create unix sockets since they are created by default in the
90+
# directory we have no permissions to (owned by system postgres user).
91+
echo "unix_socket_directories = ''" >> "$PGDATA/postgresql.conf"
92+
echo "port = ${{ inputs.port }}" >> "$PGDATA/postgresql.conf"
93+
pg_ctl start
94+
95+
# Save required connection parameters for created superuser to the
96+
# connection service file [1]. This allows using these connection
97+
# parameters by setting 'PGSERVICE' environment variable or by
98+
# requesting them via connection string.
99+
#
100+
# HOST is required for Linux/macOS because these OS-es default to unix
101+
# sockets but we turned them off.
102+
#
103+
# PORT, USER, PASSWORD and DBNAME are required because they could be
104+
# parametrized via action input parameters.
105+
#
106+
# [1] https://www.postgresql.org/docs/15/libpq-pgservice.html
107+
cat <<EOF > "$PGDATA/pg_service.conf"
108+
[${{ inputs.username }}]
109+
host=localhost
110+
port=${{ inputs.port }}
111+
user=${{ inputs.username }}
112+
password=${{ inputs.password }}
113+
dbname=${{ inputs.database }}
114+
EOF
115+
echo "PGSERVICEFILE=$PGDATA/pg_service.conf" >> $GITHUB_ENV
116+
shell: bash
117+
118+
- name: Setup PostgreSQL database
119+
run: |
120+
# The 'postgres' database is a pre-created database meant for use by
121+
# users, utilities and third party applications. There's no way to
122+
# parametrize the name, so all we can do is to avoid creating a
123+
# database if provided name is 'postgres'.
124+
if [ "${{ inputs.database }}" != "postgres" ]; then
125+
createdb -O "${{ inputs.username }}" "${{ inputs.database }}"
126+
fi
127+
env:
128+
PGSERVICE: ${{ inputs.username }}
129+
shell: bash
130+
131+
- name: Set action outputs
132+
run: |
133+
CONNECTION_URI="postgresql://${{ inputs.username }}:${{ inputs.password }}@localhost:${{ inputs.port }}/${{ inputs.database }}"
134+
135+
echo "connection-uri=$CONNECTION_URI" >> $GITHUB_OUTPUT
136+
echo "service-name=${{ inputs.username }}" >> $GITHUB_OUTPUT
137+
shell: bash
138+
id: set-outputs

.github/dependabot.yml

+6
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,9 @@ updates:
1313
assignees:
1414
- "hfhbd"
1515
rebase-strategy: "disabled"
16+
- package-ecosystem: "devcontainers"
17+
directory: "/"
18+
schedule:
19+
interval: "daily"
20+
assignees:
21+
- "hfhbd"

.github/workflows/CD.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66

77
jobs:
88
build:
9-
runs-on: macos-latest
9+
runs-on: macos-14
1010

1111
steps:
1212
- name: Set environment for version
@@ -18,10 +18,10 @@ jobs:
1818
with:
1919
distribution: 'adopt'
2020
java-version: 17
21-
- uses: gradle/gradle-build-action@v2
21+
- uses: gradle/actions/setup-gradle@v3
2222
- run: brew install libpq
23-
- name: Build with Gradle
24-
run: ./gradlew assemble
23+
env:
24+
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: true
2525
- name: Publish
2626
run: ./gradlew -Pversion=$version -Dorg.gradle.parallel=false --no-configuration-cache publish closeAndReleaseStagingRepository
2727
env:

.github/workflows/CI.yml

+8-6
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,25 @@ jobs:
1313
contents: write
1414
strategy:
1515
matrix:
16-
os: [ 'ubuntu-latest', 'macos-latest' ]
16+
os: [ 'ubuntu-latest', 'macos-14', 'macos-latest' ]
17+
18+
env:
19+
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: true
1720

1821
steps:
1922
- uses: actions/checkout@v4
2023
- uses: Homebrew/actions/setup-homebrew@master
2124
id: set-up-homebrew
2225
- run: brew install libpq
26+
- uses: ./.github/actions/action-setup-postgres
27+
with:
28+
password: password
2329
- uses: actions/setup-java@v4
2430
with:
2531
distribution: 'adopt'
2632
java-version: 17
27-
- uses: gradle/gradle-build-action@v2
33+
- uses: gradle/actions/setup-gradle@v3
2834
with:
29-
dependency-graph: generate-and-submit
3035
gradle-home-cache-cleanup: true
3136
- run: ./gradlew assemble
32-
- uses: ikalnytskyi/action-setup-postgres@v5
33-
with:
34-
password: password
3537
- run: ./gradlew build

.github/workflows/Docs.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
with:
3535
distribution: 'adopt'
3636
java-version: 17
37-
- uses: gradle/gradle-build-action@v2
37+
- uses: gradle/actions/setup-gradle@v3
3838
- name: Generate Docs
3939
run: ./gradlew :dokkaHtmlMultiModule
4040
- uses: actions/upload-pages-artifact@v3

README.md

+28-11
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
# Module postgres-native-sqldelight-driver
1+
# PostgreSQL native SQLDelight driver
22

33
A native Postgres driver using libpq.
44

55
You can use the driver with [SQLDelight](https://github.com/cashapp/sqldelight), but this is not required.
66

77
- [Source code](https://github.com/hfhbd/postgres-native-sqldelight)
88

9-
> Keep in mind, until now, this is only a single-threaded wrapper over libpq using 1 connection only. There is no connection pool nor multithread support (like JDBC or R2DBC).
9+
> Keep in mind, until now, this is only a single-threaded wrapper over libpq using 1 connection only. There is no
10+
> connection pool nor multithread support (like JDBC or R2DBC).
1011
1112
## Install
1213

@@ -51,7 +52,8 @@ val driver = PostgresNativeDriver(
5152

5253
This driver supports local and remote listeners.
5354
Local listeners only notify this client, ideally for testing or using the database with only one client at a time.
54-
Remote listener support uses `NOTIFY` and `LISTEN`, so you can use this to sync multiple clients or with existing database
55+
Remote listener support uses `NOTIFY` and `LISTEN`, so you can use this to sync multiple clients or with existing
56+
database
5557
triggers.
5658
SQLDelight uses and expects the table name as payload, but you can provide a mapper function.
5759

@@ -68,7 +70,8 @@ The identifier is used to reuse prepared statements.
6870
driver.execute(identifier = null, sql = "INSERT INTO foo VALUES (42)", parameters = 0, binders = null)
6971
```
7072

71-
It also supports a real lazy cursor by using a `Flow`. The `fetchSize` parameter defines how many rows are fetched at once:
73+
It also supports a real lazy cursor by using a `Flow`. The `fetchSize` parameter defines how many rows are fetched at
74+
once:
7275

7376
```kotlin
7477
val namesFlow: Flow<Simple> = driver.executeQueryAsFlow(
@@ -100,26 +103,40 @@ Apache 2
100103

101104
## Contributing
102105

103-
You need libpq installed: https://formulae.brew.sh/formula/libpq#default
106+
### Devcontainers
104107

105-
You have to add the compiler flags to the [libpq.def](postgres-native-sqldelight-driver/src/nativeInterop/cinterop/libpq.def).
106-
The exact flags depend on your config, but you will get them during installing libpq with homebrew.
108+
Start the devcontainer, that's it.
109+
110+
### Local
111+
112+
#### docker compose
113+
114+
This is the preferred local option. The `app` service contains the JVM as well as libpq.
115+
116+
#### Manual
117+
118+
You need to install `libpq`, eg using Homebrew: https://formulae.brew.sh/formula/libpq#default
119+
120+
For installation using homebrew, the default path is already added.
121+
122+
Otherwise, you have to add the compiler flags to
123+
the [libpq.def](postgres-native-sqldelight-driver/src/nativeInterop/cinterop/libpq.def).
124+
The exact flags depend on your config, for example:
107125

108126
```
109127
For compilers to find libpq you may need to set:
110128
export LDFLAGS="-L/home/linuxbrew/.linuxbrew/opt/libpq/lib"
111129
export CPPFLAGS="-I/home/linuxbrew/.linuxbrew/opt/libpq/include"
112130
```
113131

114-
For installation using homebrew, the default path is already added.
132+
##### Testing
115133

116-
### Testing
117-
118-
If you install libpq with homebrew, it will install the platform-specific artifact.
134+
If you installed libpq with homebrew, it will install the platform-specific artifact.
119135

120136
To test other platforms, eg. linux x64 on macOS, you need to install the platform-specific libpq of linux x64 too.
121137

122138
To start the postgres instance, you can use docker:
139+
123140
```sh
124141
docker run -e POSTGRES_PASSWORD=password -p 5432:5432 postgres
125142
```

gradle/build-logic/settings.gradle.kts

+4
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@ dependencyResolutionManagement {
99
}
1010
}
1111

12+
plugins {
13+
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
14+
}
15+
1216
rootProject.name = "build-logic"

gradle/wrapper/gradle-wrapper.jar

-9 Bytes
Binary file not shown.

gradle/wrapper/gradle-wrapper.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-rc-2-bin.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

0 commit comments

Comments
 (0)