diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..47bcbe0
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,205 @@
+name: Java CI Combined
+
+on:
+ push:
+ pull_request:
+ workflow_dispatch:
+ workflow_call:
+ inputs:
+ LUCEE_TEST_JAVA_VERSION:
+ required: true
+ type: string
+ default: '21'
+ LUCEE_VERSION_QUERY:
+ required: true
+ type: string
+ default: '["6.2/snapshot/light","7/snapshot/light"]'
+
+jobs:
+ setup:
+ runs-on: ubuntu-latest
+ outputs:
+ version: ${{ steps.extract-version.outputs.VERSION }}
+ lucee-versions: ${{ steps.convert-lucee-versions.outputs.LUCEE_VERSIONS }}
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+
+ - name: Cache Maven packages
+ uses: actions/cache@v4
+ with:
+ path: ~/.m2
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
+
+ - name: Extract version number
+ id: extract-version
+ run: |
+ VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)
+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
+
+ - name: Convert Lucee versions
+ id: convert-lucee-versions
+ env:
+ REPO_VERSIONS: ${{ vars.LUCEE_TEST_VERSIONS_PLUS }}
+ INPUT_VERSIONS: ${{ inputs.LUCEE_VERSION_QUERY }}
+ run: |
+ # Use input versions if provided, otherwise use repo versions
+ SIMPLE_VERSIONS="${INPUT_VERSIONS:-$REPO_VERSIONS}"
+ # Convert simple format to complex format
+ echo "$SIMPLE_VERSIONS" | jq -c 'map({version: ("light-" + split("/")[0] + ".0.0-SNAPSHOT"), query: .})' > lucee_versions.json
+ LUCEE_VERSIONS=$(cat lucee_versions.json)
+ echo "LUCEE_VERSIONS=$LUCEE_VERSIONS" >> $GITHUB_OUTPUT
+
+ - name: Cache Lucee files
+ uses: actions/cache@v4
+ with:
+ path: ~/work/_actions/lucee/script-runner/main/lucee-download-cache
+ key: lucee-downloads
+
+ - name: Import GPG key
+ run: |
+ echo "$GPG_PRIVATE_KEY" | base64 --decode | gpg --batch --import
+ env:
+ GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
+
+ build:
+ runs-on: ubuntu-latest
+ needs: setup
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up JDK 21
+ uses: actions/setup-java@v4
+ with:
+ java-version: ${{ inputs.LUCEE_TEST_JAVA_VERSION || '21' }}
+ distribution: 'temurin'
+
+ - name: Cache Maven packages
+ uses: actions/cache@v4
+ with:
+ path: ~/.m2
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
+
+ - name: Build and Install with Maven
+ run: |
+ echo "------- Maven Install -------";
+ mvn -B -e -f pom.xml clean install
+
+ - name: Upload Artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: cockroachdb-lex
+ path: target/*.lex
+
+ test:
+ runs-on: ubuntu-latest
+ needs: [setup, build]
+ strategy:
+ fail-fast: false
+ matrix:
+ lucee: ${{ fromJSON(needs.setup.outputs.lucee-versions) }}
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Start CockroachDB
+ run: |
+ docker run -d --name cockroachdb \
+ -p 26257:26257 -p 8080:8080 \
+ cockroachdb/cockroach:v23.1.11 start-single-node --insecure
+
+ - name: Wait for CockroachDB and setup database
+ run: |
+ # Download cockroach CLI
+ curl -L https://binaries.cockroachdb.com/cockroach-v23.1.11.linux-amd64.tgz | tar -xz
+ sudo cp cockroach-v23.1.11.linux-amd64/cockroach /usr/local/bin/
+
+ # Wait for CockroachDB to be ready
+ for i in {1..10}; do
+ cockroach sql --insecure --host=localhost:26257 --execute="SELECT 1;" && break || sleep 5;
+ done
+
+ # Create database
+ cockroach sql --insecure --host=localhost:26257 --execute="CREATE DATABASE IF NOT EXISTS testdb;"
+
+ - name: Download built artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: cockroachdb-lex
+ path: target/
+
+ - name: Checkout Lucee
+ uses: actions/checkout@v4
+ with:
+ repository: lucee/lucee
+ path: lucee
+
+ - name: Run Lucee Test Suite
+ uses: lucee/script-runner@main
+ with:
+ webroot: ${{ github.workspace }}/lucee/test
+ execute: /bootstrap-tests.cfm
+ luceeVersionQuery: ${{ matrix.lucee.query }}
+ extensionDir: ${{ github.workspace }}/target
+ env:
+ testLabels: cockroachdb
+ testServices: none # we don't need any services for this test, avoid errors due to bundle download
+ LUCEE_ENABLE_BUNDLE_DOWNLOAD: false # we want to test the extension we just built
+ COCKROACHDB_HOST: localhost
+ COCKROACHDB_USERNAME: root
+ COCKROACHDB_PORT: 26257
+ COCKROACHDB_DATABASE: testdb
+ LUCEE_LOGGING_FORCE_APPENDER: console
+ LUCEE_LOGGING_FORCE_LEVEL: info
+ testAdditional: ${{ github.workspace }}/tests
+
+ deploy:
+ runs-on: ubuntu-latest
+ needs: [test]
+ if: always() && needs.test.result == 'success' && github.ref == 'refs/heads/main'
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v4
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+
+ - name: Cache Maven packages
+ uses: actions/cache@v4
+ with:
+ path: ~/.m2
+ key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
+ restore-keys: |
+ ${{ runner.os }}-maven-
+
+ - name: Import GPG key
+ run: |
+ echo "$GPG_PRIVATE_KEY" | base64 --decode | gpg --batch --import
+ env:
+ GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
+
+ - name: Build and Deploy with Maven
+ env:
+ MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
+ MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
+ GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
+ run: |
+ if [[ "${{ needs.setup.outputs.version }}" == *-SNAPSHOT ]]; then
+ echo "------- Maven Deploy snapshot on ${{ github.event_name }} -------";
+ mvn -B -e -f pom.xml clean deploy --settings maven-settings.xml
+ else
+ echo "------- Maven Deploy release on ${{ github.event_name }} -------";
+ mvn -B -e -f pom.xml clean deploy -DperformRelease=true --settings maven-settings.xml
+ fi
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..28e1415
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,12 @@
+/dist
+/notUsedYet
+**/Test.java
+**/.DS_Store
+**/.svn/
+/*.project
+va specific
+*.class
+target
+target/*
+*.lock
+*.DS_Store
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..c1fb686
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,7 @@
+{
+ "workbench.colorCustomizations": {
+ "activityBar.background": "#023608",
+ "titleBar.activeBackground": "#034B0B",
+ "titleBar.activeForeground": "#ECFEEE"
+ }
+}
\ No newline at end of file
diff --git a/CockroachDB.cfc b/CockroachDB.cfc
new file mode 100644
index 0000000..20cc058
--- /dev/null
+++ b/CockroachDB.cfc
@@ -0,0 +1,86 @@
+component extends="types.Driver" output="no" implements="types.IDatasource" {
+
+ fields = array(
+ field("SSL Mode", "sslmode", "disable,require,verify-ca,verify-full", "disable", "SSL mode to use for the connection.", "radio"),
+ field("Application Name", "application_name", "", false, "Optional application name for the connection."),
+ field("Timezone", "timezone", "", false, "Set the session timezone for the connection."),
+ field("Retry Transient Errors", "retryTransientErrors", "true,false", "false", "Automatically retry serialization failures during transactions.", "radio"),
+ field("Implicit SELECT FOR UPDATE", "implicitSelectForUpdate", "true,false", "false", "Automatically append FOR UPDATE to qualified SELECT statements to reduce contention.", "radio"),
+ field("Rewrite Batched Inserts", "reWriteBatchedInserts", "true,false", "false", "Enable array-based rewrites for bulk INSERT operations.", "radio"),
+ field("Rewrite Batched Updates", "reWriteBatchedUpdates", "true,false", "false", "Enable array-based rewrites for bulk UPDATE operations.", "radio"),
+ field("Rewrite Batched Upserts", "reWriteBatchedUpserts", "true,false", "false", "Enable array-based rewrites for bulk UPSERT operations.", "radio"),
+ field("Retry Max Attempts", "retryMaxAttempts", "", "15", "Maximum number of retry attempts for transient errors (default: 15)."),
+ field("Retry Max Backoff Time", "retryMaxBackoffTime", "", "30s", "Maximum backoff time between retries (default: 30s).")
+ );
+
+ this.type.port = this.TYPE_FREE;
+ this.value.host = "localhost";
+ this.value.port = 26257;
+ this.className = "{class-name}";
+ this.bundleName = "{bundle-name}";
+ this.dsn = "{connString}";
+
+ /**
+ * Custom parameter syntax for CockroachDB JDBC URLs
+ */
+ public struct function customParameterSyntax() {
+ return {leadingdelimiter:'?', delimiter:'&', separator:'='};
+ }
+
+ /**
+ * Validate field combinations before saving
+ */
+ public void function onBeforeUpdate() {
+ // Validate retry settings
+ if (len(form.custom_retryMaxAttempts ?: "")) {
+ var attempts = val(form.custom_retryMaxAttempts);
+ if (attempts < 1 || attempts > 100) {
+ throw message="Retry Max Attempts must be between 1 and 100";
+ }
+ }
+
+ // Validate backoff time format
+ if (len(form.custom_retryMaxBackoffTime ?: "")) {
+ var backoffTime = form.custom_retryMaxBackoffTime;
+ if (!reFindNoCase("^\d+[smh]?$", backoffTime)) {
+ throw message="Retry Max Backoff Time must be in format like '30s', '5m', or '1h'";
+ }
+ }
+ }
+
+ /**
+ * returns display name of the driver
+ */
+ public string function getName() {
+ return "{label}";
+ }
+
+ /**
+ * returns the id of the driver
+ */
+ public string function getId() {
+ return "{id}";
+ }
+
+ /**
+ * returns the description of the driver
+ */
+ public string function getDescription() {
+ return "{description}";
+ }
+
+ /**
+ * returns array of fields
+ */
+ public array function getFields() {
+ return fields;
+ }
+
+ public boolean function literalTimestampWithTSOffset() {
+ return false;
+ }
+
+ public boolean function alwaysSetTimeout() {
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..84d5836
--- /dev/null
+++ b/README.md
@@ -0,0 +1,22 @@
+# Lucee CockroachDB JDBC Extension
+
+
+
+[](https://github.com/lucee/extension-jdbc-cockroachdb/actions/workflows/main.yml)
+
+Issues: https://luceeserver.atlassian.net/issues/?jql=labels%20%3D%20cockroachdb
+
+## Coackroach DB
+
+https://www.cockroachlabs.com/product/overview/
+
+## JDBC client
+
+While you can just use the Postgres JDBC client, this JDBC client adds some extra Cockroachdb specific support (it does bundle the postgres jdbc client and extends it)
+
+https://github.com/cloudneutral/cockroachdb-jdbc
+
+## Requirements
+
+**Java 17 or higher** is required for this extension due to the CockroachDB JDBC driver 2.0.1+ dependency.
+**Lucee 6.2.2.91 or newer**
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..4c28a92
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,286 @@
+
+
+
+ Building Datasource Extension
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Manifest-Version: 1.0
+Built-Date: ${NOW}
+version: "${symbolicVersion}"
+id: "${id}"
+name: "${label}"
+description: "${desc}"
+category: "Datasource"
+lucee-core-version: "6.2.2.91"
+start-bundles: false
+jdbc: "[{'label':'${label}','id':'${jdbcid}','connectionString':'${_connstr}','class':'${className}','bundleName':'${symbolicName}','bundleVersion':'${symbolicVersion}'}]"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/logo.png b/logo.png
new file mode 100644
index 0000000..70c9744
Binary files /dev/null and b/logo.png differ
diff --git a/maven-settings.xml b/maven-settings.xml
new file mode 100644
index 0000000..3647539
--- /dev/null
+++ b/maven-settings.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+ ossrh
+ ${env.MAVEN_USERNAME}
+ ${env.MAVEN_PASSWORD}
+
+
+
+
+
+ ossrh
+
+ true
+
+
+ gpg2
+ ${env.GPG_PASSPHRASE}
+
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..66af6fa
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,362 @@
+
+ 4.0.0
+ org.lucee
+ cockroachdb-jdbc-extension
+ ${cockroachdb.jdbc.version}
+ pom
+ CockroachDB JDBC
+
+
+ UTF-8
+ 17
+ 17
+ C1A2B3C4-D5E6-47F8-9A0BC1D2E3F4A5B6
+ 6.2.2.91
+ server
+ 2.0.1
+ jdbc:cockroachdb://{host}:{port}/{database}
+ cockroachdb
+
+ https://oss.sonatype.org/service/local/staging/deploy/maven2/
+ https://oss.sonatype.org/content/repositories/snapshots/
+
+
+
+ org.openjdk.nashorn
+ nashorn-core
+ 15.4
+ provided
+
+
+ io.github.kai-niemi.cockroachdb.jdbc
+ cockroachdb-jdbc
+ ${cockroachdb.jdbc.version}
+
+
+ org.postgresql
+ postgresql
+ 42.7.7
+
+
+
+ https://github.com/lucee/extension-jdbc-cockroachdb
+ scm:git:git://github.com/lucee/extension-jdbc-cockroachdb.git
+ scm:git:git@github.com:lucee/extension-jdbc-cockroachdb.git
+ ${project.version}
+
+
+
+
+ The GNU Lesser General Public License, Version 2.1
+ http://www.gnu.org/licenses/lgpl-2.1.txt
+ repo
+
+
+
+
+
+ zspitzer
+ Zac Spitzer
+ zac@lucee.org
+ Lucee Association Switzerland
+ http://lucee.org
+
+ Project-Administrator
+ Developer
+
+ +1
+
+
+
+ JDBC Type 4 Driver for CockroachDB.
+ https://github.com/lucee/extension-jdbc-cockroachdb
+
+
+
+ release-sign-artifacts
+
+
+ performRelease
+ true
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 3.0.1
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+ ${project.build.directory}/${project.artifactId}-${project.version}.lex
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ 3.0.0
+
+ true
+ false
+ release
+ deploy
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.2.0
+
+
+ copy-cockroachdb-jar
+ generate-resources
+
+ copy-dependencies
+
+
+ io.github.kai-niemi.cockroachdb.jdbc,org.postgresql
+ cockroachdb-jdbc,postgresql
+ ${project.build.directory}/dependency
+ false
+ true
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 3.0.0
+
+
+ org.openjdk.nashorn
+ nashorn-core
+ 15.4
+
+
+
+
+ package
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: cockroachdb-jdbc
+Bundle-Name: CockroachDB JDBC Driver OSGi Bundle
+Bundle-Version: ${cockroachdb.jdbc.version}
+Bundle-Description: OSGi bundle for CockroachDB JDBC driver
+Bundle-Vendor: Lucee Association Switzerland
+Bundle-RequiredExecutionEnvironment: JavaSE-17
+Export-Package: io.cockroachdb.jdbc;version="${cockroachdb.jdbc.version}",
+ io.github.kai_niemi.cockroachdb.jdbc;version="${cockroachdb.jdbc.version}",
+ org.postgresql;version="42.7.7",
+ org.postgresql.copy;version="42.7.7",
+ org.postgresql.core;version="42.7.7",
+ org.postgresql.ds;version="42.7.7",
+ org.postgresql.ds.common;version="42.7.7",
+ org.postgresql.fastpath;version="42.7.7",
+ org.postgresql.geometric;version="42.7.7",
+ org.postgresql.jdbc;version="42.7.7",
+ org.postgresql.largeobject;version="42.7.7",
+ org.postgresql.ssl;version="42.7.7",
+ org.postgresql.util;version="42.7.7",
+ org.postgresql.xa;version="42.7.7"
+Import-Package: javax.sql,
+ javax.naming;resolution:=optional,
+ javax.net.ssl;resolution:=optional,
+ javax.transaction.xa;resolution:=optional,
+ org.slf4j;resolution:=optional;version="[1.6,3)",
+ javax.xml.parsers;resolution:=optional,
+ javax.xml.transform;resolution:=optional,
+ javax.xml.transform.stream;resolution:=optional
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+ org.codehaus.mojo
+ build-helper-maven-plugin
+ 3.2.0
+
+
+ attach-artifacts
+ package
+
+ attach-artifact
+
+
+
+
+
+ ${project.build.directory}/${project.artifactId}-${project.version}.lex
+ lex
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-clean-plugin
+ 3.1.0
+
+
+ cleanup
+ post-package
+
+ clean
+
+
+
+
+ ${project.build.directory}/antrun
+
+ **/*
+
+
+
+ ${project.build.directory}/archive-tmp
+
+ **/*
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-deploy-plugin
+ 3.0.0-M1
+
+
+ default-deploy
+ deploy
+
+ deploy-file
+
+
+ ${project.build.directory}/${project.artifactId}-${project.version}.lex
+ ${project.groupId}
+ ${project.artifactId}
+ ${project.version}
+ ossrh
+ ${deploy.url}
+ lex
+
+
+
+
+
+
+
+ org.sonatype.central
+ central-publishing-maven-plugin
+ 0.8.0
+ true
+
+ ossrh
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/cockroachdb.cfc b/tests/cockroachdb.cfc
new file mode 100644
index 0000000..664728a
--- /dev/null
+++ b/tests/cockroachdb.cfc
@@ -0,0 +1,88 @@
+component extends="org.lucee.cfml.test.LuceeTestCase" labels="cockroachdb" {
+
+ function beforeAll (){
+ variables.bundleName = "cockroachdb-jdbc";
+ if ( _isConfEmpty() ) {
+ systemOutput( "CockroachDB environment variables not set, skipping tests", true );
+ return;
+ }
+ variables.conf = _getCockroachEnvVars();
+ variables.ds = {
+ class: "io.cockroachdb.jdbc.CockroachDriver"
+ // , bundleName: bundleName
+ // , bundleVersion: bundleVersion
+ , connectionString: "jdbc:cockroachdb://#variables.conf.host#:#variables.conf.port#/#variables.conf.database#?sslmode=disable"
+ , username: variables.conf.username
+ // In insecure mode, omit password to avoid authentication issues
+ };
+ }
+
+ function run(){
+ describe( title="CockroachDB basic connection test", body=function(){
+
+ it("expect config to not be empty", function(){
+ expect( _getCockroachEnvVars() ).notToBeEmpty("cockroachdb environment variables not set");
+ });
+
+ it(title="verify cockroachdb with dbinfo", skip=_isConfEmpty(), body=function(){
+ dbinfo datasource="#ds#" name="local.result" type="version";
+ systemOutput( "", true );
+ systemOutput( ds, true );
+ systemOutput( local.result.toJson(), true );
+ expect( local.result ).notToBeEmpty();
+ });
+
+ });
+
+ describe( title="CockroachDB basic CRUD tests", body=function(){
+ it(title="can create a table", skip=_isConfEmpty(), body=function(){
+ // Clean up any existing test data first
+ QueryExecute( "DROP TABLE IF EXISTS test_table", {}, {datasource=ds} );
+ var sql = "CREATE TABLE test_table (id INT PRIMARY KEY, name VARCHAR(255))";
+ var result = QueryExecute( sql, {}, {datasource=ds} );
+ expect( result ).toBeQuery();
+ });
+ it(title="can insert a row", skip=_isConfEmpty(), body=function(){
+ var sql = "INSERT INTO test_table (id, name) VALUES (?, ?)";
+ var params = [1, "Alice"];
+ var result = QueryExecute( sql, params, {datasource=ds} );
+ expect( result ).toBeQuery();
+ });
+ it(title="can select a row", skip=_isConfEmpty(), body=function(){
+ var sql = "SELECT * FROM test_table WHERE id = ?";
+ var params = [{value=1, cfsqltype="CF_SQL_INTEGER"}];
+ var result = QueryExecute( sql, params, {datasource=ds} );
+ expect( result.recordCount ).toBe( 1 );
+ expect( result.name ).toBe( "Alice" );
+ });
+ it(title="can update a row", skip=_isConfEmpty(), body=function(){
+ var sql = "UPDATE test_table SET name = ? WHERE id = ?";
+ var params = ["Bob", {value=1, cfsqltype="CF_SQL_INTEGER"}];
+ var result = QueryExecute( sql, params, {datasource=ds} );
+ expect( result ).toBeQuery();
+ // Verify update
+ var verify = QueryExecute( "SELECT * FROM test_table WHERE id = ?", [{value=1, cfsqltype="CF_SQL_INTEGER"}], {datasource=ds} );
+ expect( verify.name ).toBe( "Bob" );
+ });
+ it(title="can delete a row", skip=_isConfEmpty(), body=function(){
+ var sql = "DELETE FROM test_table WHERE id = ?";
+ var params = [{value=1, cfsqltype="CF_SQL_INTEGER"}];
+ var result = QueryExecute( sql, params, {datasource=ds} );
+ expect( result ).toBeQuery();
+ // Verify delete
+ var verify = QueryExecute( "SELECT * FROM test_table WHERE id = ?", [{value=1, cfsqltype="CF_SQL_INTEGER"}], {datasource=ds} );
+ expect( verify.recordCount ).toBe( 0 );
+ });
+
+ })
+ }
+
+ private boolean function _isConfEmpty() {
+ return isEmpty(_getCockroachEnvVars());
+ }
+
+ private struct function _getCockroachEnvVars() {
+ return server._getSystemPropOrEnvVars("HOST,USERNAME,PORT,DATABASE", "COCKROACHDB_");
+ }
+
+}