From cbaf7f0c96289abe72a2876a3d1ed5d7da17d856 Mon Sep 17 00:00:00 2001 From: Alexey Kuzin <akudiyar@gmail.com> Date: Wed, 25 Sep 2024 19:12:25 -0400 Subject: [PATCH] Update Picodata JDBC example code and README --- picodata-java-example/README.md | 58 ++++ .../picodata}/PicodataExample.java | 0 .../.mvn/wrapper/maven-wrapper.properties | 19 ++ picodata-jdbc-example/README.md | 77 ++++-- picodata-jdbc-example/before.sql | 10 +- picodata-jdbc-example/mvnw | 259 ++++++++++++++++++ picodata-jdbc-example/mvnw.cmd | 149 ++++++++++ picodata-jdbc-example/picodata_config.yaml | 26 -- picodata-jdbc-example/pom.xml | 111 +++++--- .../java/com/example/PostgresExample.java | 58 ---- .../java/io/picodata/PicodataJDBCExample.java | 73 +++++ .../src/main/resources/docker-compose.yaml | 50 ++++ .../src/main/resources/logback.xml | 13 + .../src/test/java/com/example/AppTest.java | 38 --- 14 files changed, 754 insertions(+), 187 deletions(-) create mode 100644 picodata-java-example/README.md rename picodata-java-example/src/main/java/{com/example => io/picodata}/PicodataExample.java (100%) create mode 100644 picodata-jdbc-example/.mvn/wrapper/maven-wrapper.properties create mode 100755 picodata-jdbc-example/mvnw create mode 100644 picodata-jdbc-example/mvnw.cmd delete mode 100644 picodata-jdbc-example/picodata_config.yaml delete mode 100644 picodata-jdbc-example/src/main/java/com/example/PostgresExample.java create mode 100644 picodata-jdbc-example/src/main/java/io/picodata/PicodataJDBCExample.java create mode 100644 picodata-jdbc-example/src/main/resources/docker-compose.yaml create mode 100644 picodata-jdbc-example/src/main/resources/logback.xml delete mode 100644 picodata-jdbc-example/src/test/java/com/example/AppTest.java diff --git a/picodata-java-example/README.md b/picodata-java-example/README.md new file mode 100644 index 0000000..63d88bc --- /dev/null +++ b/picodata-java-example/README.md @@ -0,0 +1,58 @@ +# Working with Picodata using native Java driver + +## Requirements + +- JDK 8+ (17 and higher is recommended) +- Docker or Podman + +## Running this example + +1. Clone this repo and build it using the Maven wraper script: + +```shell +git clone https://git.picodata.io/picodata/picodata/examples/-/tree/master/picodata-java-example +``` + +```shell +./mvnw install +``` + +2. Go to `src/main/resources` directory and run the Docker containers with example Picodata cluster: + +```shell +docker-compose up -d +``` + +3. Set up driver user authorization for Picodata in the container: + +```shell +docker-compose exec picodata-1 bash -c "echo -ne \"\\set language sql\nALTER USER \\\"admin\\\" WITH PASSWORD 'P@ssw0rd';\" | picodata admin /home/picouser/picodata-1/admin.sock" +``` + +4. Return to the initial directory `picodata-java-example` and launch the example application. + + +For JDK 17 and higher: + +```shell +_JAVA_OPTIONS="--add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=java.base/jdk.internal.misc=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED" ./mvnw exec:java +``` + +For older JDKs: + +```shell +./mvnw exec:java +``` + +In case of successful run you should see logs like the following in your console: + +``` +[nioEventLoopGroup-2-1] INFO i.p.d.c.c.AbstractTarantoolConnectionManager - Connected to Tarantool server at /127.0.0.1:3301 +Insert result: +row_count 1 +Select all characters after insert: +metadata [{name=id, type=integer}, {name=name, type=string}, {name=year, type=integer}] +rows [[2, Vasya, 2000]] +[io.picodata.PicodataExample.main()] INFO i.p.d.c.c.AbstractTarantoolConnectionManager - Disconnected from /127.0.0.1:3301 + +``` diff --git a/picodata-java-example/src/main/java/com/example/PicodataExample.java b/picodata-java-example/src/main/java/io/picodata/PicodataExample.java similarity index 100% rename from picodata-java-example/src/main/java/com/example/PicodataExample.java rename to picodata-java-example/src/main/java/io/picodata/PicodataExample.java diff --git a/picodata-jdbc-example/.mvn/wrapper/maven-wrapper.properties b/picodata-jdbc-example/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..0f7e194 --- /dev/null +++ b/picodata-jdbc-example/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +wrapperVersion=3.3.2 +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip diff --git a/picodata-jdbc-example/README.md b/picodata-jdbc-example/README.md index d84c770..a6e6715 100644 --- a/picodata-jdbc-example/README.md +++ b/picodata-jdbc-example/README.md @@ -1,18 +1,59 @@ -## Requirments -maven -Java > 21 - -## How to run -1. Install picodata -2. Run picodata using provided config with the following command: -```bash -picodata run --config picodata_config.yaml -``` -3. Prepare database schema for example app with: -```bash -cat before.sql | picodata admin ./admin.sock -``` -4. Run example app with -```bash -mvn compile && mvn exec:java -Dexec.mainClass="com.example.PostgresExample" -``` \ No newline at end of file +# Working with Picodata using JDBC driver + +## Requirements + +- JDK 11+ +- Docker or Podman + +## Running this example + +1. Clone this repo and build it using the Maven wraper script: + +```shell +git clone https://git.picodata.io/picodata/picodata/examples/-/tree/master/picodata-jdbc-example +``` + +```shell +./mvnw install +``` + +2. Go to `src/main/resources` directory and run the Docker containers with example Picodata cluster: + +```shell +docker-compose up -d +``` + +3. Create new Picodata user for JDBC driver in the container: + +```shell +docker-compose exec picodata-1 bash -c "echo -ne \"\\set language sql\nCREATE USER \\\"sqluser\\\" WITH PASSWORD 'P@ssw0rd' USING md5;\nGRANT CREATE TABLE TO \\\"sqluser\\\";\" | picodata admin /home/picouser/picodata-1/admin.sock" +``` + +4. Return to the initial directory `picodata-jdbc-example` and launch the example application. + + +For JDK 17 and higher: + +```shell +_JAVA_OPTIONS="--add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=java.base/jdk.internal.misc=ALL-UNNAMED --add-opens=java.base/sun.nio.ch=ALL-UNNAMED" ./mvnw exec:java +``` + +For older JDKs: + +```shell +./mvnw exec:java +``` + +In case of successful run you should see logs like the following in your console: + +``` +19:09:22.473 [io.picodata.PicodataJDBCExample.main()] INFO io.picodata.PicodataJDBCExample - Connected to the Picodata server successfully. +19:09:22.491 [io.picodata.PicodataJDBCExample.main()] INFO io.picodata.PicodataJDBCExample - Executed file before.sql +19:09:22.608 [io.picodata.PicodataJDBCExample.main()] INFO io.picodata.PicodataJDBCExample - 1 rows was deleted +19:09:22.640 [io.picodata.PicodataJDBCExample.main()] INFO io.picodata.PicodataJDBCExample - 1 rows was inserted +19:09:22.674 [io.picodata.PicodataJDBCExample.main()] INFO io.picodata.PicodataJDBCExample - Id is 1, name is Dima +[INFO] ------------------------------------------------------------------------ +[INFO] BUILD SUCCESS +[INFO] ------------------------------------------------------------------------ + +``` diff --git a/picodata-jdbc-example/before.sql b/picodata-jdbc-example/before.sql index 7825f10..045be8f 100644 --- a/picodata-jdbc-example/before.sql +++ b/picodata-jdbc-example/before.sql @@ -1,9 +1 @@ -CREATE TABLE "warehouse" ( - id INTEGER NOT NULL, - item TEXT NOT NULL, - PRIMARY KEY (id)) -USING memtx DISTRIBUTED BY (id) -OPTION (TIMEOUT = 3.0); -CREATE USER "randy" WITH PASSWORD 'P@ssw0rd' USING md5 OPTION (TIMEOUT = 3.0); -GRANT WRITE ON TABLE "warehouse" to "randy"; -GRANT READ ON TABLE "warehouse" to "randy"; \ No newline at end of file +CREATE TABLE "warehouse" (id INTEGER NOT NULL, item TEXT NOT NULL, PRIMARY KEY (id)) USING memtx DISTRIBUTED BY (id) OPTION (TIMEOUT = 3.0); diff --git a/picodata-jdbc-example/mvnw b/picodata-jdbc-example/mvnw new file mode 100755 index 0000000..19529dd --- /dev/null +++ b/picodata-jdbc-example/mvnw @@ -0,0 +1,259 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.2 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"${0%/*}/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in ${0%/*}/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${0##*/mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash> +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/picodata-jdbc-example/mvnw.cmd b/picodata-jdbc-example/mvnw.cmd new file mode 100644 index 0000000..b150b91 --- /dev/null +++ b/picodata-jdbc-example/mvnw.cmd @@ -0,0 +1,149 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.2 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" (%__MVNW_CMD__% %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash> +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace '^.*'+$MVNW_REPO_PATTERN,'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' +$MAVEN_HOME_PARENT = "$HOME/.m2/wrapper/dists/$distributionUrlNameMain" +if ($env:MAVEN_USER_HOME) { + $MAVEN_HOME_PARENT = "$env:MAVEN_USER_HOME/wrapper/dists/$distributionUrlNameMain" +} +$MAVEN_HOME_NAME = ([System.Security.Cryptography.MD5]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/picodata-jdbc-example/picodata_config.yaml b/picodata-jdbc-example/picodata_config.yaml deleted file mode 100644 index 572f868..0000000 --- a/picodata-jdbc-example/picodata_config.yaml +++ /dev/null @@ -1,26 +0,0 @@ -cluster: - cluster_id: demo - tier: - default: - replication_factor: 1 - can_vote: true - default_replication_factor: 1 -instance: - data_dir: . - tier: default - peer: - - 127.0.0.1:3301 - listen: 127.0.0.1:3301 - advertise_address: 127.0.0.1:3301 - http_listen: 127.0.0.1:8081 - admin_socket: ./admin.sock - plugin_dir: null - audit: null - shredding: false - log: - level: info - destination: null - format: plain - pg: - listen: 127.0.0.1:5432 - ssl: false diff --git a/picodata-jdbc-example/pom.xml b/picodata-jdbc-example/pom.xml index e55cc48..2fc6e1a 100644 --- a/picodata-jdbc-example/pom.xml +++ b/picodata-jdbc-example/pom.xml @@ -1,40 +1,75 @@ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - <groupId>com.example</groupId> - <artifactId>postgres-java-example</artifactId> - <packaging>jar</packaging> - <version>1.0-SNAPSHOT</version> - <name>postgres-java-example</name> - <url>http://maven.apache.org</url> - <dependencies> - <dependency> - <groupId>org.postgresql</groupId> - <artifactId>postgresql</artifactId> - <version>42.5.3</version> - </dependency> - </dependencies> - <build> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-compiler-plugin</artifactId> - <version>3.8.0</version> - <configuration> - <release>21</release> - <compilerArgs> - --enable-preview - </compilerArgs> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-surefire-plugin</artifactId> - <version>3.0.0-M3</version> - <configuration> - <argLine>--enable-preview</argLine> - </configuration> - </plugin> - </plugins> - </build> + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>io.picodata</groupId> + <artifactId>picodata-jdbc-example</artifactId> + <version>1.0.0-SNAPSHOT</version> + + <dependencies> + <dependency> + <groupId>io.picodata</groupId> + <artifactId>picodata-jdbc</artifactId> + <version>1.0.0</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>2.0.16</version> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + <version>1.3.4</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <version>3.2.0</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.11.0</version> + <configuration> + <fork>true</fork> + <debug>true</debug> + <optimize>true</optimize> + <showDeprecation>true</showDeprecation> + <showWarnings>true</showWarnings> + <source>17</source> + <target>17</target> + <excludes> + <exclude>**/package-info.java</exclude> + </excludes> + </configuration> + </plugin> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <version>3.4.0</version> + <executions> + <execution> + <goals> + <goal>java</goal> + </goals> + </execution> + </executions> + <configuration> + <mainClass>io.picodata.PicodataJDBCExample</mainClass> + </configuration> + </plugin> + </plugins> + </build> + + <repositories> + <repository> + <id>binary.picodata.io</id> + <url>https://binary.picodata.io/repository/maven-releases/</url> + </repository> + </repositories> </project> diff --git a/picodata-jdbc-example/src/main/java/com/example/PostgresExample.java b/picodata-jdbc-example/src/main/java/com/example/PostgresExample.java deleted file mode 100644 index 406cb92..0000000 --- a/picodata-jdbc-example/src/main/java/com/example/PostgresExample.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.example; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Properties; - -public class PostgresExample { - public static void main(String[] args) { - var props = new Properties(); - props.setProperty("user", "randy"); - props.setProperty("password", "P@ssw0rd"); - // props.setProperty("dbname", "postgres"); - - var connstr = "jdbc:postgresql://localhost:5432/"; - try (Connection conn = DriverManager.getConnection(connstr, props)) { - System.out.println("Connected to the PostgreSQL server successfully."); - - var DELETE_QUERY = """ - DELETE FROM "warehouse"; - """; - var stmt = conn.prepareStatement(DELETE_QUERY); - var deleteRows = stmt.executeUpdate(); - System.out.println(String.format("%d rows was deleted", deleteRows)); - - - var INSERT_QUERY = """ - INSERT INTO \"warehouse\" VALUES (?, ?) - """; - stmt = conn.prepareStatement(INSERT_QUERY); - stmt.setInt(1, 1); - stmt.setString(2, "Dima"); - var insertedRows = stmt.executeUpdate(); - System.out.println(String.format("%d rows was inserted", insertedRows)); - - var SELECT_QUERY = """ - SELECT * FROM "warehouse" WHERE id = ?; - """; - stmt = conn.prepareStatement(SELECT_QUERY); - stmt.setInt(1, 1); - var res = stmt.executeQuery(); - while (res.next()) { - System.out.println( - String.format( - "Id is %d, name is %s", - res.getInt(1), - res.getString(2) - ) - ); - } - - - } catch (SQLException e) { - e.printStackTrace(); - } - } -} - diff --git a/picodata-jdbc-example/src/main/java/io/picodata/PicodataJDBCExample.java b/picodata-jdbc-example/src/main/java/io/picodata/PicodataJDBCExample.java new file mode 100644 index 0000000..bc60751 --- /dev/null +++ b/picodata-jdbc-example/src/main/java/io/picodata/PicodataJDBCExample.java @@ -0,0 +1,73 @@ +package io.picodata; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PicodataJDBCExample { + private static Logger logger = LoggerFactory.getLogger(PicodataJDBCExample.class); + + public static void main(String[] args) { + var props = new Properties(); + props.setProperty("user", "sqluser"); + props.setProperty("password", "P@ssw0rd"); + props.setProperty("sslmode", "disable"); + + var connstr = "jdbc:picodata://localhost:5432/"; + try (Connection conn = DriverManager.getConnection(connstr, props)) { + logger.info("Connected to the Picodata server successfully."); + + var stmt = conn.createStatement(); + + try { + Files.readAllLines(Paths.get("before.sql")).stream().forEach(statement -> { + try { + stmt.execute(statement); + } catch (SQLException e) { + throw new RuntimeException(e); + } + }); + logger.info("Executed file before.sql"); + } catch (RuntimeException e) { + logger.error("Failed to execute before.sql", e); + System.exit(1); + } catch (IOException e) { + logger.error("Failed to open file before.sql", e); + System.exit(1); + } + + var deleteQuery = "DELETE FROM \"warehouse\";"; + var preparedStmt = conn.prepareStatement(deleteQuery); + var deleteRows = preparedStmt.executeUpdate(); + logger.info("{} rows were deleted", deleteRows); + + + var insertQuery = "INSERT INTO \"warehouse\" VALUES (?, ?);"; + preparedStmt = conn.prepareStatement(insertQuery); + preparedStmt.setInt(1, 1); + preparedStmt.setString(2, "Dima"); + var insertedRows = preparedStmt.executeUpdate(); + logger.info("{} rows were inserted", insertedRows); + + var selectQuery = "SELECT * FROM \"warehouse\" WHERE id = ?;"; + preparedStmt = conn.prepareStatement(selectQuery); + preparedStmt.setInt(1, 1); + var res = preparedStmt.executeQuery(); + while (res.next()) { + logger.info("Id is {}, name is {}", res.getInt(1), res.getString(2)); + } + + } catch (SQLException e) { + logger.error("Unexpected error: ", e); + System.exit(1); + } + } +} + diff --git a/picodata-jdbc-example/src/main/resources/docker-compose.yaml b/picodata-jdbc-example/src/main/resources/docker-compose.yaml new file mode 100644 index 0000000..dad0992 --- /dev/null +++ b/picodata-jdbc-example/src/main/resources/docker-compose.yaml @@ -0,0 +1,50 @@ +--- +version: '3' + +services: + picodata-1: + image: docker-public.binary.picodata.io/picodata:24.4.1 + container_name: picodata-1 + hostname: picodata-1 + environment: + PICODATA_INSTANCE_ID: picodata-1 + PICODATA_DATA_DIR: picodata-1 + PICODATA_LISTEN: picodata-1:3301 + PICODATA_ADVERTISE: picodata-1:3301 + PICODATA_PEER: picodata-1:3301 + PICODATA_PG_LISTEN: picodata-1:5432 + PICODATA_PG_SSL: "false" + ports: + - "3301:3301" + - "5432:5432" + + picodata-2: + image: docker-public.binary.picodata.io/picodata:24.4.1 + container_name: picodata-2 + hostname: picodata-2 + depends_on: + - picodata-1 + environment: + PICODATA_INSTANCE_ID: picodata-2 + PICODATA_DATA_DIR: picodata-2 + PICODATA_LISTEN: picodata-2:3302 + PICODATA_ADVERTISE: picodata-2:3302 + PICODATA_PEER: picodata-1:3301 + ports: + - "3302:3302" + + + picodata-3: + image: docker-public.binary.picodata.io/picodata:24.4.1 + container_name: picodata-3 + hostname: picodata-3 + depends_on: + - picodata-1 + environment: + PICODATA_INSTANCE_ID: picodata-3 + PICODATA_DATA_DIR: picodata-3 + PICODATA_LISTEN: picodata-3:3303 + PICODATA_ADVERTISE: picodata-3:3303 + PICODATA_PEER: picodata-1:3301 + ports: + - "3303:3303" diff --git a/picodata-jdbc-example/src/main/resources/logback.xml b/picodata-jdbc-example/src/main/resources/logback.xml new file mode 100644 index 0000000..9b096aa --- /dev/null +++ b/picodata-jdbc-example/src/main/resources/logback.xml @@ -0,0 +1,13 @@ +<configuration debug="true"> + <variable name="logLevel" value="${logging.logLevel}"/> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> + </encoder> + </appender> + + <root level="${logLevel:-INFO}"> + <appender-ref ref="STDOUT"/> + </root> +</configuration> diff --git a/picodata-jdbc-example/src/test/java/com/example/AppTest.java b/picodata-jdbc-example/src/test/java/com/example/AppTest.java deleted file mode 100644 index 474710c..0000000 --- a/picodata-jdbc-example/src/test/java/com/example/AppTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.example; - -import junit.framework.Test; -import junit.framework.TestCase; -import junit.framework.TestSuite; - -/** - * Unit test for simple App. - */ -public class AppTest - extends TestCase -{ - /** - * Create the test case - * - * @param testName name of the test case - */ - public AppTest( String testName ) - { - super( testName ); - } - - /** - * @return the suite of tests being tested - */ - public static Test suite() - { - return new TestSuite( AppTest.class ); - } - - /** - * Rigourous Test :-) - */ - public void testApp() - { - assertTrue( true ); - } -} -- GitLab