In the beginning there was darkness

This commit is contained in:
Daniel Ziltener 2020-03-09 04:10:41 +01:00
commit 51d9305ad4
5 changed files with 202 additions and 0 deletions

34
deps.edn Normal file
View File

@ -0,0 +1,34 @@
{:deps
{org.clojure/clojure {:mvn/version "1.10.1"}
org.clojure/core.async {:mvn/version "1.0.567"}
org.postgresql/postgresql {:mvn/version "42.2.10"}
seancorfield/next.jdbc {:mvn/version "1.0.395"}
cljfx {:mvn/version "1.6.5"}
org.openjfx/javafx-base {:mvn/version "13.0.2"}
org.openjfx/javafx-controls {:mvn/version "13.0.2"}
org.openjfx/javafx-graphics {:mvn/version "13.0.2"}
org.openjfx/javafx-web {:mvn/version "13.0.2"}
org.openjfx/javafx-swing {:mvn/version "13.0.2"}
org.controlsfx/controlsfx {:mvn/version "11.0.1"}
metosin/malli {:git/url "https://github.com/metosin/malli.git"
:sha "9db4ff998b641d4a0cff4eb6d772fd0cb5d3b56c"}}
:paths ["src" "resources"]
:aliases
{:outdated {:extra-deps {olical/depot {:mvn/version "0.2.30"}}
:main-opts ["-m" "depot.outdated.main" "-a" "outdated"]}
:graph {:extra-deps {org.clojure/tools.deps.graph {:mvn/version "0.2.30"}}
:main-opts ["-m" "clojure.tools.deps.graph"]}
:dev {:extra-paths ["test"]}
:test {:extra-deps {lambdaisland/kaocha {:mvn/version "0.0-590"}}
:main-opts ["-m" "kaocha.runner"]}
:uberjar {:main-opts ["-m" "hf.depstar.uberjar"
"pgwiz.jar"
"-C" "-m" "ch.lyrion.pgwiz"]
:jvm-opts ["-Dclojure.compiler.direct-linking=true"
"-Dclojure.spec.skip-macros=true"]
:extra-paths ["classes"]
:extra-deps {seancorfield/depstar {:mvn/version "0.5.2"}}}}
:mvn/repos
{"gluon-releases" {:url "https://nexus.gluonhq.com/nexus/content/repositories/releases/"}
"gluon-snapshots" {:url "https://nexus.gluonhq.com/nexus/content/repositories/public-snapshots/"}
"snapshot" {:url "https://oss.sonatype.org/content/repositories/snapshots/"}}}

52
src/ch/lyrion/pgwiz.clj Normal file
View File

@ -0,0 +1,52 @@
(ns ch.lyrion.pgwiz
(:gen-class)
(:require [cljfx.api :as fx]
[next.jdbc :as jdbc]
[ch.lyrion.pgwiz.gui :as gui]
[ch.lyrion.pgwiz.inspect :as inspect]
[ch.lyrion.pgwiz.db-table-editor :refer [db-table-editor]]))
(def value-conversion-types
{"serial" :long
"citext" :string
"text" :string
"timestamp" :string
"uuid" :string
"bool" :string
"interval" :string})
(def *context
(atom
(fx/create-context
{})))
(defn mainwindow [{:keys [fx/context]}]
{:fx/type :stage
:showing true
:title "PgWiz"
:scene {:fx/type :scene
:root {:fx/type :v-box
:children [{:fx/type db-table-editor
:schema "company"
:table "vc"
:offset 0
:limit 20}]}}
})
(def app
(fx/create-app *context
:event-handler gui/event-handler
:desc-fn (fn [_] {:fx/type mainwindow})))
#_(defonce renderer
(fx/create-renderer
:middleware (comp
fx/wrap-context-desc
(fx/wrap-map-desc (fn [_] {:fx/type sampletable})))
:opts {:fx.opt/type->lifecycle #(or (fx/keyword->lifecycle %)
(fx/fn->lifecycle-with-context %))
:fx.opt/map-event-handler event-handler}))
(when *compile-files*
(Thread/sleep 1500)
(javafx.application.Platform/exit))

View File

@ -0,0 +1,68 @@
(ns ch.lyrion.pgwiz.db-table-editor
(:require [ch.lyrion.pgwiz.gui :as gui]
[ch.lyrion.pgwiz.inspect :as inspect]
[next.jdbc :as jdbc]
[cljfx.api :as fx]))
(defmethod gui/event-handler ::on-edit-start [{:keys [fx/context fx/event attr]}]
(when (instance? javafx.scene.control.TableColumn$CellEditEvent event)
{:context (fx/swap-context context assoc :edit [attr (:lyrion/index (.getRowValue event))])}))
(defn editable-cell [{:keys [fx/context data attr id value-converter]}]
(let [value (:values data)
value (nth value id)
value (get value attr)
value (str value)]
(if (= (fx/sub context :edit) [attr id])
{:fx/type :text-field
:text-formatter {:fx/type :text-formatter
:value-converter value-converter
:value value}}
{:fx/type :label
:text (str value)})))
(defn editable-cell-factory [view data attr value-converter]
(fn [id]
{:text ""
:graphic {:fx/type view
:data data
:attr attr
:id id
:value-converter value-converter}}))
(defn generate-columns [data]
(reduce #(let [attr (keyword (:TABLE_NAME %2) (:COLUMN_NAME %2))]
(cons {:fx/type :table-column
:cell-value-factory (fn [x] (get x :lyrion/index))
:cell-factory (editable-cell-factory editable-cell
data
attr
:default)
:on-edit-start {:event/type ::on-edit-start :attr attr}
:on-edit-cancel {:event/type ::on-edit-cancel :attr attr}
:on-edit-commit {:event/type ::on-edit-commit :attr attr}
:text (:COLUMN_NAME %2)}
%1))
(list)
(:columns data)))
(defn generate-table-data [schema table offset limit]
(let [table-meta (inspect/get-columns schema table)]
{:schema schema
:table table
:columns table-meta
:values (map #(-> %1
(assoc :lyrion/meta table-meta)
(assoc :lyrion/index %2))
(jdbc/execute!
(jdbc/prepare @inspect/conn
[(str "select * from " schema "." table " limit ? offset ?") limit offset]))
(range))}))
(defn db-table-editor [{:keys [fx/context schema table offset limit]}]
(let [data (generate-table-data schema table offset limit)]
; (let [context (fx/swap-context context assoc :table (generate-table-data schema table offset limit))])
{:fx/type :table-view
:editable true
:items (:values data)
:columns (generate-columns data)}))

View File

@ -0,0 +1,4 @@
(ns ch.lyrion.pgwiz.gui
(:require [cljfx.api :as fx]))
(defmulti event-handler :event/type)

View File

@ -0,0 +1,44 @@
(ns ch.lyrion.pgwiz.inspect
(:require [next.jdbc :as jdbc]))
(def db {:dbtype "postgresql"
:dbname "sompani-dev"
:host "127.0.0.1"
:port 5432
:user "sompani_dev"
:password "sompani-dev"})
(def conn (atom (jdbc/get-connection db)))
(defn get-named-rows [pg-result-set]
(.next pg-result-set)
(loop [pg-meta (.getMetaData pg-result-set)
result (list)]
(let [result (cons (reduce #(assoc %1 (keyword (.getColumnName pg-meta %2))
(.getString pg-result-set %2))
{} (range 1 (inc (.getColumnCount pg-meta))))
result)]
(if (.next pg-result-set)
(recur (.getMetaData pg-result-set) result)
result))))
(defn get-exported-keys [schema table]
(get-named-rows (.getExportedKeys (.getMetaData @conn) nil schema table)))
(defn get-imported-keys [schema table]
(get-named-rows (.getImportedKeys (.getMetaData @conn) nil schema table)))
(defn get-primary-keys [schema table]
(get-named-rows (.getPrimaryKeys (.getMetaData @conn) nil schema table)))
(defn get-version-columns [schema table]
(get-named-rows (.getVersionColumns (.getMetaData @conn) nil schema table)))
(defn get-index-info [schema table unique approximate]
(get-named-rows (.getIndexInfo (.getMetaData @conn) nil schema table unique approximate)))
(defn get-table-privileges [schema table]
(get-named-rows (.getTablePrivileges (.getMetaData @conn) nil schema table)))
(defn get-columns [schema table]
(get-named-rows (.getColumns (.getMetaData @conn) nil schema table nil)))