Module postgres-native-sqldelight

A native Postgres driver using libpq.

You can use the driver with SQLDelight, but this is not required.

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).

Install

You need libpq installed and available in your $PATH.

This package is uploaded to MavenCentral and supports macOS and linuxX64. Windows is currently not supported.

Supported SQLDelight version: 2.0.0-alpha05.

repositories {
mavenCentral()
}

dependencies {
implementation("app.softwork:postgres-native-sqldelight-driver:LATEST")
}

// optional SQLDelight setup: requires 2.0.0-alpha05
sqldelight {
databases.register("NativePostgres") {
dialect("app.softwork:postgres-native-sqldelight-dialect:LATEST")
}
linkSqlite.set(false)
}

Usage

val driver = PostgresNativeDriver(
host = "localhost",
port = 5432,
user = "postgres",
database = "postgres",
password = "password",
options = null,
listenerSupport = ListenerSupport.Remote(coroutineScope)
)

This driver supports local and remote listeners. Local listeners only notify this client, ideally for testing or using the database with only one client at a time with SQLDelight only. Remote listener support uses NOTIFY and LISTEN, so you can use this with multiple clients or with existing database triggers. SQLDelight uses and expects the table name as payload, but you can provide a mapper function.

SQLDelight Support

Just create the driver and use your database instances in the usual way.

Raw usage

Beside SQLDelight you could also use this driver with raw queries. The identifier is used to reuse prepared statements.

driver.execute(identifier = null, sql = "INSERT INTO foo VALUES (42)", parameters = 0, binders = null)

It also supports a real lazy cursor or a Flow. The fetchSize parameter defines how many rows are fetched at once:

val names: List<Simple> = driver.executeQueryWithNativeCursor(
identifier = null,
sql = "SELECT index, name, bytes FROM foo",
mapper = { cursor ->
// You need to call `next` and use the cursor to return your type, here it is a list.

// Important, don't leak this cursor, eg by returning a Sequence,
// otherwise the cursor will be closed before fetching rows.
// If you need to use an async iterator, use the `Flow` overload, `executeQueryAsFlow`.
buildList {
while (cursor.next()) {
add(
Simple(
index = cursor.getLong(0)!!.toInt(),
name = cursor.getString(1),
byteArray = cursor.getBytes(2)
)
)
}
}
},
parameters = 0,
fetchSize = 100,
binders = null
)

val namesFlow: Flow<Simple> = driver.executeQueryAsFlow(
identifier = null,
sql = "SELECT index, name, bytes FROM foo",
mapper = { cursor ->
Simple(
index = cursor.getLong(0)!!.toInt(),
name = cursor.getString(1),
byteArray = cursor.getBytes(2)
)
},
parameters = 0,
fetchSize = 100,
binders = null
)

And for bulk imports, use the copy method. You need to enable COPY first:

driver.execute(514394779, "COPY foo FROM STDIN (FORMAT CSV)", 0)
val rows = driver.copy("1,2,3\n4,5,6\n")

License

Apache 2

Contributing

You need libpq installed: https://formulae.brew.sh/formula/libpq#default

You have to add the compiler flags to your path too. The exact commands depend on your config, but you will get them during installing libpq with homebrew.

Sample commands:

If you need to have libpq first in your PATH, run:
echo 'export PATH="/home/linuxbrew/.linuxbrew/opt/libpq/bin:$PATH"' /home/runner/.bash_profile
For compilers to find libpq you may need to set:
export LDFLAGS="-L/home/linuxbrew/.linuxbrew/opt/libpq/lib"
export CPPFLAGS="-I/home/linuxbrew/.linuxbrew/opt/libpq/include"

Testing

If you install libpq with homebrew, it will install the platform-specific artifact.

Host Supported test targets
linux x64 linux x64
macOS x64 macOS x64
macOS arm64 macOS arm64

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

To start the postgres instance, you can use docker:

docker run -e POSTGRES_PASSWORD=password -p 5432:5432 postgres

All modules:

Link copied to clipboard