[#382] add optional support for hsqldb
This commit is contained in:
parent
9b631a2427
commit
ac24abbbfb
12 changed files with 297 additions and 85 deletions
|
|
@ -771,6 +771,8 @@ handling of the SIGPIPE. This can be done by setting
|
|||
- [Clojure in the Shell](https://lambdaisland.com/blog/2019-12-05-advent-of-parens-5-clojure-in-the-shell) by Arne Brasseur
|
||||
- [Clojure Tool](https://purelyfunctional.tv/issues/purelyfunctional-tv-newsletter-351-clojure-tool-babashka/) by Eric Normand
|
||||
|
||||
## [Building babashka](doc/build.md)
|
||||
|
||||
## [Developing Babashka](doc/dev.md)
|
||||
|
||||
## Related projects
|
||||
|
|
|
|||
3
deps.edn
3
deps.edn
|
|
@ -13,7 +13,8 @@
|
|||
clj-commons/clj-yaml {:mvn/version "0.7.1"}
|
||||
com.cognitect/transit-clj {:mvn/version "1.0.324"}
|
||||
seancorfield/next.jdbc {:mvn/version "1.0.424"}
|
||||
org.postgresql/postgresql {:mvn/version "42.2.12"}}
|
||||
org.postgresql/postgresql {:mvn/version "42.2.12"}
|
||||
org.hsqldb/hsqldb {:mvn/version "2.4.0"}}
|
||||
:aliases {:main
|
||||
{:main-opts ["-m" "babashka.main"]}
|
||||
:profile
|
||||
|
|
|
|||
77
doc/build.md
Normal file
77
doc/build.md
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# Building babashka
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Install [lein](https://leiningen.org/) for producing uberjars
|
||||
- Download [GraalVM](https://www.graalvm.org/downloads/). Currently we use *java8-19.3.1*.
|
||||
- Set `$GRAALVM_HOME` to the GraalVM distribution directory. On macOS this can look like:
|
||||
|
||||
``` shell
|
||||
export GRAALVM_HOME=~/Downloads/graalvm-ce-java8-19.3.1/Contents/Home
|
||||
```
|
||||
|
||||
On linux:
|
||||
|
||||
``` shell
|
||||
export GRAALVM_HOME=~/Downloads/graalvm-ce-java8-19.3.1
|
||||
```
|
||||
|
||||
On Windows:
|
||||
```
|
||||
set GRAALVM_HOME=C:\Users\IEUser\Downloads\graalvm-ce-java8-19.3.1
|
||||
```
|
||||
|
||||
## Clone repository
|
||||
|
||||
NOTE: the babashka repository contains submodules. You need to use the
|
||||
`--recursive` flag to clone these submodules along with the main repo.
|
||||
|
||||
``` shellsession
|
||||
$ git clone https://github.com/borkdude/babashka --recursive
|
||||
```
|
||||
|
||||
To update later on:
|
||||
|
||||
``` shellsession
|
||||
$ git submodule update --recursive
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
Run the `compile` script:
|
||||
|
||||
``` shell
|
||||
$ script/compile
|
||||
```
|
||||
|
||||
To configure maximum heap size you can use:
|
||||
|
||||
```
|
||||
$ BABASHKA_XMX="-J-Xmx4g" script/compile
|
||||
```
|
||||
|
||||
## Windows
|
||||
|
||||
To compile on Windows you need to check out the `windows` branch:
|
||||
|
||||
``` shell
|
||||
$ git checkout windows
|
||||
```
|
||||
|
||||
The compile script for Windows is `script/compile.bat`.
|
||||
|
||||
## Optional features
|
||||
|
||||
### HyperSQL
|
||||
|
||||
To compile babashka with `HyperSQL`/`hsqldb` support, set
|
||||
`BABASHKA_FEATURE_HSQLDB` to `true`:
|
||||
|
||||
|
||||
``` shell
|
||||
$ BABASHKA_FEATURE_HSQLDB=true script/compile
|
||||
```
|
||||
|
||||
If you think this feature should be enabled in the distributed version of `bb`,
|
||||
vote with a thumbs up on [this](https://github.com/borkdude/babashka/issues/382)
|
||||
issue.
|
||||
12
doc/dev.md
12
doc/dev.md
|
|
@ -45,17 +45,7 @@ Test the native version:
|
|||
|
||||
## Build
|
||||
|
||||
To build this project, set `$GRAALVM_HOME` to the GraalVM distribution directory. Currently we are using GraalVM JDK8.
|
||||
|
||||
Then run:
|
||||
|
||||
$ script/compile
|
||||
|
||||
To tweak maximum heap size:
|
||||
|
||||
```
|
||||
$ BABASHKA_XMX="-J-Xmx4g" script/compile
|
||||
```
|
||||
See [build.md](build.md).
|
||||
|
||||
## Binary size
|
||||
|
||||
|
|
|
|||
|
|
@ -272,3 +272,25 @@ A script to retrieve the version from a `pom.xml` file. See
|
|||
|
||||
Show frequencies of messages by user in Whatsapp group chats.
|
||||
See [examples/whatsapp_frequencies.clj](examples/whatsapp_frequencies.clj)
|
||||
|
||||
### Find unused vars
|
||||
|
||||
[This](../examples/hsqldb_unused_vars.clj) script invokes clj-kondo, stores
|
||||
returned data in an in memory HSQLDB database and prints the result of a query
|
||||
which finds unused vars.
|
||||
|
||||
``` shell
|
||||
$ bb examples/hsqldb_unused_vars.clj src
|
||||
|
||||
| :VARS/NS | :VARS/NAME | :VARS/FILENAME | :VARS/ROW | :VARS/COL |
|
||||
|----------------------------+--------------------------+------------------------------------+-----------+-----------|
|
||||
| babashka.impl.bencode.core | read-netstring | src/babashka/impl/bencode/core.clj | 162 | 1 |
|
||||
| babashka.impl.bencode.core | write-netstring | src/babashka/impl/bencode/core.clj | 201 | 1 |
|
||||
| babashka.impl.classes | generate-reflection-file | src/babashka/impl/classes.clj | 230 | 1 |
|
||||
| babashka.impl.classpath | ->DirectoryResolver | src/babashka/impl/classpath.clj | 12 | 1 |
|
||||
| babashka.impl.classpath | ->JarFileResolver | src/babashka/impl/classpath.clj | 37 | 1 |
|
||||
| babashka.impl.classpath | ->Loader | src/babashka/impl/classpath.clj | 47 | 1 |
|
||||
| babashka.impl.clojure.test | file-position | src/babashka/impl/clojure/test.clj | 286 | 1 |
|
||||
| babashka.impl.nrepl-server | stop-server! | src/babashka/impl/nrepl_server.clj | 179 | 1 |
|
||||
| babashka.main | -main | src/babashka/main.clj | 485 | 1 |
|
||||
```
|
||||
|
|
|
|||
85
examples/hsqldb_unused_vars.clj
Executable file
85
examples/hsqldb_unused_vars.clj
Executable file
|
|
@ -0,0 +1,85 @@
|
|||
#!/usr/bin/env bb
|
||||
|
||||
;; $ examples/hsqldb_unused_vars.clj src
|
||||
|
||||
;; | :VARS/NS | :VARS/NAME | :VARS/FILENAME | :VARS/ROW | :VARS/COL |
|
||||
;; |----------------------------+--------------------------+------------------------------------+-----------+-----------|
|
||||
;; | babashka.impl.bencode.core | read-netstring | src/babashka/impl/bencode/core.clj | 162 | 1 |
|
||||
;; | babashka.impl.bencode.core | write-netstring | src/babashka/impl/bencode/core.clj | 201 | 1 |
|
||||
;; | babashka.impl.classes | generate-reflection-file | src/babashka/impl/classes.clj | 230 | 1 |
|
||||
;; | babashka.impl.classpath | ->DirectoryResolver | src/babashka/impl/classpath.clj | 12 | 1 |
|
||||
;; | babashka.impl.classpath | ->JarFileResolver | src/babashka/impl/classpath.clj | 37 | 1 |
|
||||
;; | babashka.impl.classpath | ->Loader | src/babashka/impl/classpath.clj | 47 | 1 |
|
||||
;; | babashka.impl.clojure.test | file-position | src/babashka/impl/clojure/test.clj | 286 | 1 |
|
||||
;; | babashka.impl.nrepl-server | stop-server! | src/babashka/impl/nrepl_server.clj | 179 | 1 |
|
||||
;; | babashka.main | -main | src/babashka/main.clj | 485 | 1 |
|
||||
|
||||
(ns hsqldb-unused-vars
|
||||
(:require
|
||||
[clojure.edn :as edn]
|
||||
[clojure.java.shell :refer [sh]]
|
||||
[clojure.pprint :refer [print-table]]
|
||||
[next.jdbc :as jdbc]
|
||||
[next.jdbc.sql :as sql]))
|
||||
|
||||
(def db "jdbc:hsqldb:mem:testdb;sql.syntax_mys=true")
|
||||
|
||||
(defn query [q]
|
||||
(jdbc/execute! db [q]))
|
||||
|
||||
(defn create-db! []
|
||||
(query "create table vars (
|
||||
ns text
|
||||
, name text
|
||||
, filename text
|
||||
, row int
|
||||
, col int )")
|
||||
(query "create table var_usages (
|
||||
\"from\" text
|
||||
, \"to\" text
|
||||
, name text
|
||||
, filename text
|
||||
, row int
|
||||
, col int )"))
|
||||
|
||||
(defn parse-int [^String x]
|
||||
(when x
|
||||
(Integer. x)))
|
||||
|
||||
(defn insert-vars! [var-definitions]
|
||||
(sql/insert-multi! db :vars [:ns :name :filename :row :col]
|
||||
(map (juxt (comp str :ns)
|
||||
(comp str :name)
|
||||
:filename
|
||||
(comp parse-int :row)
|
||||
(comp parse-int :col))
|
||||
var-definitions)))
|
||||
|
||||
(defn insert-var-usages! [var-usages]
|
||||
(sql/insert-multi! db :var_usages ["\"from\"" "\"to\"" :name :filename :row :col]
|
||||
(map (juxt (comp str :from)
|
||||
(comp str :to)
|
||||
(comp str :name)
|
||||
:filename
|
||||
(comp parse-int :row)
|
||||
(comp parse-int :col))
|
||||
var-usages)))
|
||||
|
||||
(defn analysis->db [paths]
|
||||
(let [out (:out (apply sh "clj-kondo"
|
||||
"--config" "{:output {:analysis true :format :edn}}"
|
||||
"--lint" paths))
|
||||
analysis (:analysis (edn/read-string out))
|
||||
{:keys [:var-definitions :var-usages]} analysis]
|
||||
(insert-vars! var-definitions)
|
||||
(insert-var-usages! var-usages)))
|
||||
|
||||
(create-db!)
|
||||
(analysis->db *command-line-args*)
|
||||
|
||||
(def unused-vars "
|
||||
select distinct * from vars v
|
||||
where (v.ns, v.name) not in
|
||||
(select vu.\"to\", vu.name from var_usages vu)")
|
||||
|
||||
(print-table (query unused-vars))
|
||||
|
|
@ -26,7 +26,8 @@
|
|||
[com.cognitect/transit-clj "1.0.324"]
|
||||
[seancorfield/next.jdbc "1.0.424"]
|
||||
[org.postgresql/postgresql "42.2.12"]]
|
||||
:profiles {:test {:dependencies [[clj-commons/conch "0.9.2"]
|
||||
:profiles {:feature/hsqldb {:dependencies [[org.hsqldb/hsqldb "2.4.0"]]}
|
||||
:test {:dependencies [[clj-commons/conch "0.9.2"]
|
||||
[com.clojure-goes-fast/clj-async-profiler "0.4.1"]]}
|
||||
:uberjar {:global-vars {*assert* false}
|
||||
:jvm-opts ["-Dclojure.compiler.direct-linking=true"
|
||||
|
|
|
|||
|
|
@ -20,9 +20,17 @@ export JAVA_HOME=$GRAALVM_HOME
|
|||
SVM_JAR=$(find "$GRAALVM_HOME" | grep svm.jar)
|
||||
$GRAALVM_HOME/bin/javac -cp "$SVM_JAR" resources/CutOffCoreServicesDependencies.java
|
||||
|
||||
|
||||
BABASHKA_LEIN_PROFILES=""
|
||||
|
||||
if [ "$BABASHKA_FEATURE_HSQLDB" = "true" ]
|
||||
then
|
||||
BABASHKA_LEIN_PROFILES="+feature/hsqldb"
|
||||
fi
|
||||
|
||||
if [ -z "$BABASHKA_JAR" ]; then
|
||||
lein with-profiles +reflection do run
|
||||
lein do clean, uberjar
|
||||
lein with-profiles "+reflection,$BABASHKA_LEIN_PROFILES" do run
|
||||
lein with-profiles "$BABASHKA_LEIN_PROFILES" do clean, uberjar
|
||||
BABASHKA_JAR=${BABASHKA_JAR:-"target/babashka-$BABASHKA_VERSION-standalone.jar"}
|
||||
fi
|
||||
|
||||
|
|
@ -53,6 +61,10 @@ if [ "$BABASHKA_STATIC" = "true" ]; then
|
|||
args+=("--static")
|
||||
fi
|
||||
|
||||
if [ "$BABASHKA_FEATURE_HSQLDB" = "true" ]; then
|
||||
args+=("-H:IncludeResources=org/hsqldb/.*\.properties", "-H:IncludeResources=org/hsqldb/.*\.sql")
|
||||
fi
|
||||
|
||||
$GRAALVM_HOME/bin/native-image "${args[@]}"
|
||||
|
||||
if [ ! -z "$(command -v lein)" ]; then
|
||||
|
|
|
|||
|
|
@ -1,8 +1,86 @@
|
|||
(ns babashka.impl.classes
|
||||
{:no-doc true}
|
||||
(:require
|
||||
[babashka.impl.features :as features]
|
||||
[cheshire.core :as json]))
|
||||
|
||||
(def custom-map
|
||||
(cond->
|
||||
`{clojure.lang.LineNumberingPushbackReader {:allPublicConstructors true
|
||||
:allPublicMethods true}
|
||||
java.lang.Thread
|
||||
{:allPublicConstructors true
|
||||
;; generated with `public-declared-method-names`, see in
|
||||
;; `comment` below
|
||||
:methods [{:name "activeCount"}
|
||||
{:name "checkAccess"}
|
||||
{:name "currentThread"}
|
||||
{:name "dumpStack"}
|
||||
{:name "enumerate"}
|
||||
{:name "getAllStackTraces"}
|
||||
{:name "getContextClassLoader"}
|
||||
{:name "getDefaultUncaughtExceptionHandler"}
|
||||
{:name "getId"}
|
||||
{:name "getName"}
|
||||
{:name "getPriority"}
|
||||
{:name "getStackTrace"}
|
||||
{:name "getState"}
|
||||
{:name "getThreadGroup"}
|
||||
{:name "getUncaughtExceptionHandler"}
|
||||
{:name "holdsLock"}
|
||||
{:name "interrupt"}
|
||||
{:name "interrupted"}
|
||||
{:name "isAlive"}
|
||||
{:name "isDaemon"}
|
||||
{:name "isInterrupted"}
|
||||
{:name "join"}
|
||||
{:name "run"}
|
||||
{:name "setContextClassLoader"}
|
||||
{:name "setDaemon"}
|
||||
{:name "setDefaultUncaughtExceptionHandler"}
|
||||
{:name "setName"}
|
||||
{:name "setPriority"}
|
||||
{:name "setUncaughtExceptionHandler"}
|
||||
{:name "sleep"}
|
||||
{:name "start"}
|
||||
{:name "toString"}
|
||||
{:name "yield"}]}
|
||||
java.net.URL
|
||||
{:allPublicConstructors true
|
||||
:allPublicFields true
|
||||
;; generated with `public-declared-method-names`, see in
|
||||
;; `comment` below
|
||||
:methods [{:name "equals"}
|
||||
{:name "getAuthority"}
|
||||
{:name "getContent"}
|
||||
{:name "getDefaultPort"}
|
||||
{:name "getFile"}
|
||||
{:name "getHost"}
|
||||
{:name "getPath"}
|
||||
{:name "getPort"}
|
||||
{:name "getProtocol"}
|
||||
{:name "getQuery"}
|
||||
{:name "getRef"}
|
||||
{:name "getUserInfo"}
|
||||
{:name "hashCode"}
|
||||
{:name "openConnection"}
|
||||
{:name "openStream"}
|
||||
{:name "sameFile"}
|
||||
;; not supported: {:name "setURLStreamHandlerFactory"}
|
||||
{:name "toExternalForm"}
|
||||
{:name "toString"}
|
||||
{:name "toURI"}]}
|
||||
com.sun.xml.internal.stream.XMLInputFactoryImpl
|
||||
{:methods [{:name "<init>" :parameterTypes []}]}
|
||||
com.sun.xml.internal.stream.XMLOutputFactoryImpl
|
||||
{:methods [{:name "<init>" :parameterTypes []}]}}
|
||||
features/hsqldb? (assoc `org.hsqldb.dbinfo.DatabaseInformationFull
|
||||
{:methods [{:name "<init>"
|
||||
:parameterTypes ["org.hsqldb.Database"]}]}
|
||||
`java.util.ResourceBundle
|
||||
{:methods [{:name "getBundle"
|
||||
:parameterTypes ["java.lang.String","java.util.Locale","java.lang.ClassLoader"]}]})))
|
||||
|
||||
(def classes
|
||||
`{:all [clojure.lang.ExceptionInfo
|
||||
java.io.BufferedReader
|
||||
|
|
@ -108,7 +186,7 @@
|
|||
java.util.zip.GZIPOutputStream
|
||||
org.yaml.snakeyaml.error.YAMLException
|
||||
~(symbol "[B")
|
||||
]
|
||||
~@(when features/hsqldb? [`org.hsqldb.jdbcDriver])]
|
||||
:constructors [clojure.lang.Delay
|
||||
clojure.lang.MapEntry
|
||||
clojure.lang.LineNumberingPushbackReader
|
||||
|
|
@ -120,74 +198,7 @@
|
|||
:fields [clojure.lang.PersistentQueue]
|
||||
:instance-checks [clojure.lang.IObj
|
||||
clojure.lang.IEditableCollection]
|
||||
:custom {clojure.lang.LineNumberingPushbackReader {:allPublicConstructors true
|
||||
:allPublicMethods true}
|
||||
java.lang.Thread
|
||||
{:allPublicConstructors true
|
||||
;; generated with `public-declared-method-names`, see in
|
||||
;; `comment` below
|
||||
:methods [{:name "activeCount"}
|
||||
{:name "checkAccess"}
|
||||
{:name "currentThread"}
|
||||
{:name "dumpStack"}
|
||||
{:name "enumerate"}
|
||||
{:name "getAllStackTraces"}
|
||||
{:name "getContextClassLoader"}
|
||||
{:name "getDefaultUncaughtExceptionHandler"}
|
||||
{:name "getId"}
|
||||
{:name "getName"}
|
||||
{:name "getPriority"}
|
||||
{:name "getStackTrace"}
|
||||
{:name "getState"}
|
||||
{:name "getThreadGroup"}
|
||||
{:name "getUncaughtExceptionHandler"}
|
||||
{:name "holdsLock"}
|
||||
{:name "interrupt"}
|
||||
{:name "interrupted"}
|
||||
{:name "isAlive"}
|
||||
{:name "isDaemon"}
|
||||
{:name "isInterrupted"}
|
||||
{:name "join"}
|
||||
{:name "run"}
|
||||
{:name "setContextClassLoader"}
|
||||
{:name "setDaemon"}
|
||||
{:name "setDefaultUncaughtExceptionHandler"}
|
||||
{:name "setName"}
|
||||
{:name "setPriority"}
|
||||
{:name "setUncaughtExceptionHandler"}
|
||||
{:name "sleep"}
|
||||
{:name "start"}
|
||||
{:name "toString"}
|
||||
{:name "yield"}]}
|
||||
java.net.URL
|
||||
{:allPublicConstructors true
|
||||
:allPublicFields true
|
||||
;; generated with `public-declared-method-names`, see in
|
||||
;; `comment` below
|
||||
:methods [{:name "equals"}
|
||||
{:name "getAuthority"}
|
||||
{:name "getContent"}
|
||||
{:name "getDefaultPort"}
|
||||
{:name "getFile"}
|
||||
{:name "getHost"}
|
||||
{:name "getPath"}
|
||||
{:name "getPort"}
|
||||
{:name "getProtocol"}
|
||||
{:name "getQuery"}
|
||||
{:name "getRef"}
|
||||
{:name "getUserInfo"}
|
||||
{:name "hashCode"}
|
||||
{:name "openConnection"}
|
||||
{:name "openStream"}
|
||||
{:name "sameFile"}
|
||||
;; not supported: {:name "setURLStreamHandlerFactory"}
|
||||
{:name "toExternalForm"}
|
||||
{:name "toString"}
|
||||
{:name "toURI"}]}
|
||||
com.sun.xml.internal.stream.XMLInputFactoryImpl
|
||||
{:methods [{:name "<init>" :parameterTypes []}]}
|
||||
com.sun.xml.internal.stream.XMLOutputFactoryImpl
|
||||
{:methods [{:name "<init>" :parameterTypes []}]}}})
|
||||
:custom ~custom-map})
|
||||
|
||||
(defmacro gen-class-map []
|
||||
(let [classes (concat (:all classes)
|
||||
|
|
|
|||
4
src/babashka/impl/features.clj
Normal file
4
src/babashka/impl/features.clj
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
(ns babashka.impl.features
|
||||
{:no-doc true})
|
||||
|
||||
(def hsqldb? (= "true" (System/getenv "BABASHKA_FEATURE_HSQLDB")))
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
(ns babashka.impl.jdbc
|
||||
{:no-doc true}
|
||||
(:require [next.jdbc :as njdbc]
|
||||
[next.jdbc.sql :as sql]
|
||||
[sci.impl.namespaces :refer [copy-var]]
|
||||
[sci.impl.vars :as vars]))
|
||||
|
||||
|
|
@ -29,3 +30,8 @@
|
|||
'transact (copy-var njdbc/transact next-ns)
|
||||
'with-transaction (with-meta with-transaction
|
||||
{:sci/macro true})})
|
||||
|
||||
(def sns (vars/->SciNamespace 'next.jdbc.sql nil))
|
||||
|
||||
(def next-sql-namespace
|
||||
{'insert-multi! (copy-var sql/insert-multi! sns)})
|
||||
|
|
|
|||
|
|
@ -295,7 +295,8 @@ Everything after that is bound to *command-line-args*."))
|
|||
'babashka.curl curl-namespace
|
||||
'cognitect.transit transit-namespace
|
||||
'bencode.core bencode-namespace
|
||||
'next.jdbc jdbc/njdbc-namespace})
|
||||
'next.jdbc jdbc/njdbc-namespace
|
||||
'next.jdbc.sql jdbc/next-sql-namespace})
|
||||
|
||||
(def bindings
|
||||
{'java.lang.System/exit exit ;; override exit, so we have more control
|
||||
|
|
|
|||
Loading…
Reference in a new issue