-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit - open source Spruce from MyWorld's private repositories.
- Loading branch information
1 parent
efe6b9a
commit d762d74
Showing
16 changed files
with
993 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# | ||
# https://help.github.com/articles/dealing-with-line-endings/ | ||
# | ||
# These are explicitly windows files and should use crlf | ||
*.bat text eol=crlf | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
name: build_release | ||
|
||
on: | ||
release: | ||
types: [created] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Set up JDK 1.11 | ||
uses: actions/setup-java@v1 | ||
with: | ||
java-version: 1.11 | ||
server-id: github | ||
settings-path: ${{ github.workspace }} | ||
|
||
- name: Get tag | ||
id: tag | ||
uses: dawidd6/action-get-tag@v1 | ||
|
||
- name: Build with Gradle | ||
run: ./gradlew build -Prelease=${{ steps.tag.outputs.tag }} | ||
|
||
- name: Publish to GitHub Packages | ||
run: ./gradlew publish | ||
env: | ||
USERNAME: ${{ github.actor }} | ||
TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,82 @@ | ||
# Spruce | ||
Fresh, trim, & lightweight JDBC wrapper | ||
|
||
## Why use Spruce? | ||
The JDBC API was originally developed in 1997 and has changed | ||
little since then. The Java language has changed a great deal | ||
since then, as have other contemporary database APIs. Spruce | ||
provides a tiny (~300 lines of code), modern API wrapper around | ||
JDBC that greatly simplifies most common access patterns. When | ||
you want to do something that Spruce doesn't support, it's | ||
trivially easy to directly access JDBC directly. | ||
|
||
Note that Spruce is not (and does not aspire to be) an ORM. | ||
It does not have any features for mapping objects to/from | ||
the database, and support for this is not planned. | ||
|
||
## Features | ||
- Modern, clean API | ||
- Concise code | ||
- `ResultSet` unpacking to single/list/map | ||
- Organize related SQL code into modules | ||
- Bring your own connection pool | ||
- Transactions | ||
- Batching | ||
|
||
## Usage | ||
|
||
**Setting up a Database** | ||
```java | ||
var ds = /* Acquire a JDBC DataSource - typically a connection pool */; | ||
var db = new Database(ds); | ||
|
||
// If using modules | ||
db.register(MyModule.class, MyModule.factory()); | ||
db.initFactories(); | ||
|
||
// That's it! Database is now ready for use. | ||
``` | ||
|
||
**Acquiring & using a DBContext** | ||
```java | ||
/* The main point of entry into Spruce is the DBContext, | ||
* which wraps a JDBC connection. Note that the DBContext | ||
* must have close() called immediately after you're done | ||
* using it to prevent resource leaks, hence the Spruce | ||
* idiom of acquiring and using contexts in a try-with-resource | ||
* block. | ||
*/ | ||
try(var ctx = db.getContext()){ | ||
return ctx.prepare("SELECT val1 FROM my_table WHERE id = ?") | ||
.bind(id) | ||
.querySingle(Integer.class); | ||
} | ||
``` | ||
|
||
**Unpack results as a map** | ||
```java | ||
try(var ctx = db.getContext()){ | ||
return ctx.prepare("SELECT key, val1, val2 FROM my_table WHERE id = ?") | ||
.bind(id) | ||
.queryMap(r -> r.getString("key"), this::unpackMapValue); | ||
} | ||
``` | ||
|
||
**Insert/Update/Delete (Queries that don't return results)** | ||
```java | ||
try(var ctx = db.getContext()){ | ||
ctx.execute( | ||
"INSERT INTO my_table (id, val1, val2) VALUES (?, ?, ?)", | ||
id, value1, value2); | ||
} | ||
``` | ||
|
||
## Contributing | ||
Spruce is in active use at [MyWorld](https://myworldvw.com), but our | ||
documentation and tests are lacking in this repository. If you use Spruce | ||
or you're looking to kick off your open source career by writing some | ||
documentation, unit tests, or a new feature, we'd value your contribution! | ||
|
||
Note about features: Our goal with Spruce is to provide a lightweight, clean, | ||
and modern API around JDBC. We welcome all contributions in furtherance of | ||
that goal, but we have no interest in Spruce becoming an ORM. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Copyright 2021 MyWorld, 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. | ||
*/ | ||
|
||
plugins { | ||
id 'groovy' | ||
id 'java-library' | ||
id 'maven-publish' | ||
} | ||
|
||
group = 'myworld' | ||
version = findProperty('release') ? findProperty('release') : '1.0.0-SNAPSHOT' | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
testImplementation 'org.codehaus.groovy:groovy:3.0.8' | ||
testImplementation 'org.spockframework:spock-core:2.0-groovy-3.0' | ||
testImplementation 'junit:junit:4.13.2' | ||
testImplementation 'com.h2database:h2:1.4.200' | ||
} | ||
|
||
tasks.named('test') { | ||
useJUnitPlatform() | ||
} | ||
|
||
publishing { | ||
publications { | ||
gpr(MavenPublication) { | ||
groupId = "${project.group}" | ||
artifactId = 'spruce' | ||
version = "${project.version}" | ||
|
||
from components.java | ||
} | ||
} | ||
|
||
repositories { | ||
mavenLocal() | ||
maven { | ||
name = "GitHubPackages" | ||
url = uri("https://maven.pkg.github.com/MyWorldLLC/Spruce") | ||
credentials { | ||
username = project.findProperty("gpr.user") ?: System.getenv("USERNAME") | ||
password = project.findProperty("gpr.key") ?: System.getenv("TOKEN") | ||
} | ||
} | ||
} | ||
} | ||
sourceCompatibility = JavaVersion.VERSION_16 | ||
targetCompatibility = JavaVersion.VERSION_16 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
#!/usr/bin/env sh | ||
|
||
# | ||
# Copyright 2015 the original author or authors. | ||
# | ||
# 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 | ||
# | ||
# https://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. | ||
# | ||
|
||
############################################################################## | ||
## | ||
## Gradle start up script for UN*X | ||
## | ||
############################################################################## | ||
|
||
# Attempt to set APP_HOME | ||
# Resolve links: $0 may be a link | ||
PRG="$0" | ||
# Need this for relative symlinks. | ||
while [ -h "$PRG" ] ; do | ||
ls=`ls -ld "$PRG"` | ||
link=`expr "$ls" : '.*-> \(.*\)$'` | ||
if expr "$link" : '/.*' > /dev/null; then | ||
PRG="$link" | ||
else | ||
PRG=`dirname "$PRG"`"/$link" | ||
fi | ||
done | ||
SAVED="`pwd`" | ||
cd "`dirname \"$PRG\"`/" >/dev/null | ||
APP_HOME="`pwd -P`" | ||
cd "$SAVED" >/dev/null | ||
|
||
APP_NAME="Gradle" | ||
APP_BASE_NAME=`basename "$0"` | ||
|
||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | ||
|
||
# Use the maximum available, or set MAX_FD != -1 to use that value. | ||
MAX_FD="maximum" | ||
|
||
warn () { | ||
echo "$*" | ||
} | ||
|
||
die () { | ||
echo | ||
echo "$*" | ||
echo | ||
exit 1 | ||
} | ||
|
||
# OS specific support (must be 'true' or 'false'). | ||
cygwin=false | ||
msys=false | ||
darwin=false | ||
nonstop=false | ||
case "`uname`" in | ||
CYGWIN* ) | ||
cygwin=true | ||
;; | ||
Darwin* ) | ||
darwin=true | ||
;; | ||
MSYS* | MINGW* ) | ||
msys=true | ||
;; | ||
NONSTOP* ) | ||
nonstop=true | ||
;; | ||
esac | ||
|
||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||
|
||
|
||
# Determine the Java command to use to start the JVM. | ||
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" | ||
else | ||
JAVACMD="$JAVA_HOME/bin/java" | ||
fi | ||
if [ ! -x "$JAVACMD" ] ; then | ||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||
Please set the JAVA_HOME variable in your environment to match the | ||
location of your Java installation." | ||
fi | ||
else | ||
JAVACMD="java" | ||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
Please set the JAVA_HOME variable in your environment to match the | ||
location of your Java installation." | ||
fi | ||
|
||
# Increase the maximum file descriptors if we can. | ||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then | ||
MAX_FD_LIMIT=`ulimit -H -n` | ||
if [ $? -eq 0 ] ; then | ||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | ||
MAX_FD="$MAX_FD_LIMIT" | ||
fi | ||
ulimit -n $MAX_FD | ||
if [ $? -ne 0 ] ; then | ||
warn "Could not set maximum file descriptor limit: $MAX_FD" | ||
fi | ||
else | ||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | ||
fi | ||
fi | ||
|
||
# For Darwin, add options to specify how the application appears in the dock | ||
if $darwin; then | ||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | ||
fi | ||
|
||
# For Cygwin or MSYS, switch paths to Windows format before running java | ||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then | ||
APP_HOME=`cygpath --path --mixed "$APP_HOME"` | ||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | ||
|
||
JAVACMD=`cygpath --unix "$JAVACMD"` | ||
|
||
# We build the pattern for arguments to be converted via cygpath | ||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | ||
SEP="" | ||
for dir in $ROOTDIRSRAW ; do | ||
ROOTDIRS="$ROOTDIRS$SEP$dir" | ||
SEP="|" | ||
done | ||
OURCYGPATTERN="(^($ROOTDIRS))" | ||
# Add a user-defined pattern to the cygpath arguments | ||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then | ||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | ||
fi | ||
# Now convert the arguments - kludge to limit ourselves to /bin/sh | ||
i=0 | ||
for arg in "$@" ; do | ||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | ||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option | ||
|
||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition | ||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | ||
else | ||
eval `echo args$i`="\"$arg\"" | ||
fi | ||
i=`expr $i + 1` | ||
done | ||
case $i in | ||
0) set -- ;; | ||
1) set -- "$args0" ;; | ||
2) set -- "$args0" "$args1" ;; | ||
3) set -- "$args0" "$args1" "$args2" ;; | ||
4) set -- "$args0" "$args1" "$args2" "$args3" ;; | ||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | ||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | ||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | ||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | ||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | ||
esac | ||
fi | ||
|
||
# Escape application args | ||
save () { | ||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done | ||
echo " " | ||
} | ||
APP_ARGS=`save "$@"` | ||
|
||
# Collect all arguments for the java command, following the shell quoting and substitution rules | ||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" | ||
|
||
exec "$JAVACMD" "$@" |
Oops, something went wrong.