Skip to content

build: graalvm build #2717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 14 commits into
base: postgresql-dialect
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions build/native-image/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
mvn clean package -P assembly -DskipTests
cd target/pgadapter
native-image \
--initialize-at-build-time=com.google.protobuf,com.google.gson,com.google.cloud.spanner.pgadapter.Server \
-J-Xmx14g \
-H:IncludeResources=".*" \
-H:ReflectionConfigurationFiles=../../build/native-image/reflectconfig.json \
-jar pgadapter.jar \
--no-fallback

./pgadapter -p appdev-soda-spanner-staging -i knut-test-ycsb -s 5433
79 changes: 79 additions & 0 deletions build/native-image/reflectconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
[
{
"name" : "java.lang.Class",
"queryAllDeclaredConstructors" : true,
"queryAllPublicConstructors" : true,
"queryAllDeclaredMethods" : true,
"queryAllPublicMethods" : true,
"allDeclaredClasses" : true,
"allPublicClasses" : true
},
{
"name" : "sun.misc.Signal",
"queryAllDeclaredConstructors" : true,
"queryAllPublicConstructors" : true,
"queryAllDeclaredMethods" : true,
"queryAllPublicMethods" : true,
"allDeclaredClasses" : true,
"allPublicClasses" : true,
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true
},
{
"name" : "sun.misc.SignalHandler",
"queryAllDeclaredConstructors" : true,
"queryAllPublicConstructors" : true,
"queryAllDeclaredMethods" : true,
"queryAllPublicMethods" : true,
"allDeclaredClasses" : true,
"allPublicClasses" : true,
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true
},
{
"name" : "com.google.cloud.spanner.pgadapter.Server",
"methods" : [
{ "name" : "handleTerm" },
{ "name" : "handleInt" },
{ "name" : "handleQuit" }
]
},
{
"name" : "com.google.cloud.spanner.pgadapter.logging.StdoutHandler",
"queryAllDeclaredConstructors" : true,
"queryAllPublicConstructors" : true,
"queryAllDeclaredMethods" : true,
"queryAllPublicMethods" : true,
"allDeclaredClasses" : true,
"allPublicClasses" : true,
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true
},
{
"name" : "com.google.cloud.spanner.pgadapter.logging.StderrHandler",
"queryAllDeclaredConstructors" : true,
"queryAllPublicConstructors" : true,
"queryAllDeclaredMethods" : true,
"queryAllPublicMethods" : true,
"allDeclaredClasses" : true,
"allPublicClasses" : true,
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true
},
{
"name" : "java.time.Instant",
"methods" : [
{ "name" : "now" },
{ "name" : "getNano" },
{ "name" : "getEpochSecond" }
]
}
]
4 changes: 4 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.graalvm.sdk</groupId>
<artifactId>graal-sdk</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-spanner</artifactId>
Expand Down
21 changes: 21 additions & 0 deletions samples/nodejs/pgadapter-childprocess/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "pgadapter-childprocess-sample",
"version": "0.0.1",
"description": "PGAdapter Child Process Sample",
"type": "commonjs",
"devDependencies": {
"@types/node": "^22.1.0",
"@types/pg": "^8.11.4",
"ts-node": "10.9.2",
"typescript": "5.8.2"
},
"dependencies": {
"pg": "^8.11.3",
"test-wrapped-binary": "/Users/loite/IdeaProjects/pgadapter/wrappers/nodejs",
"umzug": "^3.6.1",
"yargs": "^17.5.1"
},
"scripts": {
"start": "ts-node src/index.ts"
}
}
62 changes: 62 additions & 0 deletions samples/nodejs/pgadapter-childprocess/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {startPGAdapter} from 'test-wrapped-binary'
import { Client } from 'pg';

function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}

async function main() {
const pgAdapter = await startPGAdapter({
project: "appdev-soda-spanner-staging",
instance: "knut-test-ycsb",
port: 5433,
});
try {
//await sleep(500);

console.log('Started PGAdapter');

// Execute a simple query.
const connection = new Client({
host: "localhost",
port: 5433,
database: "knut-test-db",
});
await connection.connect();

const result = await connection.query("SELECT * " +
"FROM all_types " +
"LIMIT 10");
for (const row of result.rows) {
console.log(JSON.stringify(row));
}

// Close the connection.
await connection.end();
} finally {
pgAdapter.kill();
}
}

(async () => {
await main();
})().catch(e => {
console.error(e);
process.exit(1);
});
117 changes: 117 additions & 0 deletions samples/nodejs/pgadapter-childprocess/src/init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {QueryTypes, Sequelize} from 'sequelize';
import {GenericContainer, PullPolicy, StartedTestContainer, TestContainer} from "testcontainers";

/**
* Creates the data model that is needed for this sample application.
*
* The Cloud Spanner PostgreSQL dialect does not support all system tables (pg_catalog tables) that
* are present in open-source PostgreSQL databases. Those tables are used by Sequelize migrations.
* Migrations are therefore not supported.
*/
export async function createDataModel(sequelize: Sequelize) {
console.log("Checking whether tables already exists");
const result: any = await sequelize.query(
`SELECT COUNT(1) AS c
FROM information_schema.tables
WHERE table_schema='public'
AND table_name IN ('Singers', 'Albums', 'Tracks', 'Venues', 'Concerts', 'TicketSales')`,
{ type: QueryTypes.SELECT, raw: true, plain: true });
if (result.c == '6') {
return;
}
console.log("Creating tables");
// Create the data model.
await sequelize.query(
`
alter database db set spanner.default_sequence_kind='bit_reversed_positive';
create table "Singers" (
id serial primary key,
"firstName" varchar,
"lastName" varchar,
"fullName" varchar generated always as (
CASE WHEN "firstName" IS NULL THEN "lastName"
WHEN "lastName" IS NULL THEN "firstName"
ELSE "firstName" || ' ' || "lastName"
END) stored,
"active" boolean,
"createdAt" timestamptz,
"updatedAt" timestamptz
);

create table "Albums" (
id serial primary key,
title varchar,
"marketingBudget" numeric,
"SingerId" bigint,
"createdAt" timestamptz default current_timestamp,
"updatedAt" timestamptz,
constraint fk_albums_singers foreign key ("SingerId") references "Singers" (id)
);

create table if not exists "Tracks" (
id bigint not null,
"trackNumber" bigint not null,
title varchar not null,
"sampleRate" float8 not null,
"createdAt" timestamptz default current_timestamp,
"updatedAt" timestamptz,
primary key (id, "trackNumber")
) interleave in parent "Albums" on delete cascade;

create table if not exists "Venues" (
id serial primary key,
name varchar not null,
description varchar not null,
"createdAt" timestamptz default current_timestamp,
"updatedAt" timestamptz
);

create table if not exists "Concerts" (
id serial primary key,
"VenueId" bigint not null,
"SingerId" bigint not null,
name varchar not null,
"startTime" timestamptz not null,
"endTime" timestamptz not null,
"createdAt" timestamptz default current_timestamp,
"updatedAt" timestamptz,
constraint fk_concerts_venues foreign key ("VenueId") references "Venues" (id),
constraint fk_concerts_singers foreign key ("SingerId") references "Singers" (id),
constraint chk_end_time_after_start_time check ("endTime" > "startTime")
);

create table if not exists "TicketSales" (
id serial primary key,
"ConcertId" bigint not null,
"customerName" varchar not null,
price decimal not null,
seats text[],
"createdAt" timestamptz default current_timestamp,
"updatedAt" timestamptz,
constraint fk_ticket_sales_concerts foreign key ("ConcertId") references "Concerts" (id)
);`,
{type: QueryTypes.RAW})
}

export async function startPGAdapter(): Promise<StartedTestContainer> {
console.log("Pulling PGAdapter and Spanner emulator");
const container: TestContainer = new GenericContainer("gcr.io/cloud-spanner-pg-adapter/pgadapter-emulator")
.withPullPolicy(PullPolicy.alwaysPull())
.withExposedPorts(5432);
console.log("Starting PGAdapter and Spanner emulator");
return await container.start();
}
Loading
Loading