Skip to content

Commit

Permalink
[FEAT] Multiple databases for postgres (#551)
Browse files Browse the repository at this point in the history
* feat(database schema): allow multiple databases in the schema

* refactor(database schema): add loading inside the databases when is postgres

* chore(version): update to version 1.33.0
  • Loading branch information
rogefm authored Nov 14, 2024
1 parent 65288f0 commit 86acf6d
Show file tree
Hide file tree
Showing 6 changed files with 363 additions and 186 deletions.
2 changes: 1 addition & 1 deletion webapp/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "webapp",
"version": "1.32.1",
"version": "1.33.0",
"scripts": {
"ancient": "clojure -Sdeps '{:deps {com.github.liquidz/antq {:mvn/version \"RELEASE\"}}}' -m antq.core",
"genversion": "npx genversion src/webapp/version.js",
Expand Down
107 changes: 104 additions & 3 deletions webapp/src/webapp/events/editor_plugin.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@
(let [connection-list-cached (read-string (.getItem js/localStorage "run-connection-list-selected"))
is-cached? (fn [current-connection-name]
(not-empty (filter #(= (:name %) current-connection-name) connection-list-cached)))
connections-parsed (mapv (fn [{:keys [name type subtype status access_schema]}]
connections-parsed (mapv (fn [{:keys [name type subtype status access_schema secret]}]
{:name name
:type type
:subtype subtype
:status status
:access_schema access_schema
:database_name (when (and (= type "database")
(= subtype "postgres"))
(js/atob (:envvar:DB secret)))
:selected (if (is-cached? name)
true
false)})
Expand All @@ -52,12 +55,15 @@
(let [connection-list-cached (read-string (.getItem js/localStorage "run-connection-list-selected"))
is-cached? (fn [current-connection-name]
(not-empty (filter #(= (:name %) current-connection-name) connection-list-cached)))
connections-parsed (mapv (fn [{:keys [name type subtype status selected access_schema]}]
connections-parsed (mapv (fn [{:keys [name type subtype status selected access_schema secret]}]
{:name name
:type type
:subtype subtype
:status status
:access_schema access_schema
:database_name (when (and (= type "database")
(= subtype "postgres"))
(js/atob (:envvar:DB secret)))
:selected (if (is-cached? name)
true
selected)})
Expand Down Expand Up @@ -298,7 +304,8 @@
[{:keys [db]} [_ data script]]
{:db (assoc db :editor-plugin->script (take 10
(assoc (:editor-plugin->script db) 0
{:status :success :data (merge data {:script script})})))}))
{:status :success :data (merge data
{:script script})})))}))

(rf/reg-event-fx
::editor-plugin->set-script-failure
Expand Down Expand Up @@ -376,6 +383,12 @@
:status :success
:connection connection}])}]]]}))

(defn- parse-databases-list [raw]
(if (vector? raw)
raw
(let [lines (drop 1 (string/split (str raw) #"\n"))]
(vec (remove empty? lines)))))

(defn- parse-sql-to-tree
"This functions gets a TAB separated DB response string and convert to a hashmap
Input Example (raw):
Expand Down Expand Up @@ -414,6 +427,94 @@
_ (mapv #(reducers/fold mount-tree (inner-split %)) outer-trimmed)]
@tree-atom))

(rf/reg-event-fx
:editor-plugin->get-postgres-schema
(fn
[{:keys [db]} [_ connection get-postgres-databases-query get-postgres-schema-query get-postgres-schema-with-index-query]]
(let [current-connection-data (get-in db [:database-schema :data (:connection-name connection)])
has-databases? (not-empty (:databases current-connection-data))]
(if has-databases?
{:db (-> db
(assoc-in [:database-schema :current-connection] (:connection-name connection))
(assoc-in [:database-schema :data (:connection-name connection) :database-schema-status] :loading))
:fx [[:dispatch [:fetch {:method "POST"
:uri (str "/connections/" (:connection-name connection) "/exec")
:body {:script get-postgres-schema-query}
:on-success #(rf/dispatch [:editor-plugin->get-postgres-indexes
connection
get-postgres-schema-with-index-query
%
{:output (:databases current-connection-data)}])}]]]}
{:db (-> db
(assoc-in [:database-schema :current-connection] (:connection-name connection))
(assoc-in [:database-schema :data (:connection-name connection) :status] :loading)
(assoc-in [:database-schema :data (:connection-name connection) :database-schema-status] :loading))
:fx [[:dispatch [:fetch {:method "POST"
:uri (str "/connections/" (:connection-name connection) "/exec")
:body {:script get-postgres-databases-query}
:on-success #(rf/dispatch [:editor-plugin->get-postgres-schema-details
connection
%
get-postgres-schema-query
get-postgres-schema-with-index-query])}]]]}))))

(rf/reg-event-fx
:editor-plugin->get-postgres-schema-details
(fn
[{:keys [db]} [_ connection databases-payload get-postgres-schema-query get-postgres-schema-with-index-query]]
{:fx [[:dispatch [:fetch {:method "POST"
:uri (str "/connections/" (:connection-name connection) "/exec")
:body {:script get-postgres-schema-query}
:on-success #(rf/dispatch [:editor-plugin->get-postgres-indexes
connection
get-postgres-schema-with-index-query
%
databases-payload])}]]]}))

(rf/reg-event-fx
:editor-plugin->get-postgres-indexes
(fn
[{:keys [db]} [_ connection index-query schema-payload databases-payload]]
{:fx [[:dispatch [:fetch {:method "POST"
:uri (str "/connections/" (:connection-name connection) "/exec")
:body {:script index-query}
:on-success #(rf/dispatch [:editor-plugin->set-postgres-schema
{:schema-payload schema-payload
:indexes-payload %
:databases-payload databases-payload
:status :success
:database-schema-status :success
:connection connection}])}]]]}))

(rf/reg-event-fx
:editor-plugin->set-postgres-schema
(fn
[{:keys [db]} [_ {:keys [schema-payload indexes-payload databases-payload status database-schema-status connection]}]]
(let [schema {:status status
:data (assoc (-> db :database-schema :data)
(:connection-name connection)
{:status status
:database-schema-status database-schema-status
:type (:connection-type connection)
:raw (:output schema-payload)
:schema-tree (if-let [_ (empty? schema-payload)]
"Couldn't get database schema"
(:tree (parse-sql-to-tree (:output schema-payload)
(:connection-type connection))))
:indexes-tree (:tree (parse-sql-to-tree (:output indexes-payload)
(:connection-type connection)))
:databases (parse-databases-list (:output databases-payload))})
:type (:connection-type connection)
:raw (:output schema-payload)
:schema-tree (if-let [_ (empty? schema-payload)]
"Couldn't get database schema"
(:tree (parse-sql-to-tree (:output schema-payload)
(:connection-type connection))))
:indexes-tree (:tree (parse-sql-to-tree (:output indexes-payload)
(:connection-type connection)))
:databases (parse-databases-list (:output databases-payload))}]
{:db (assoc-in db [:database-schema] schema)})))

(rf/reg-event-fx
:editor-plugin->set-mysql-schema
(fn
Expand Down
22 changes: 6 additions & 16 deletions webapp/src/webapp/webclient/aside/connections_running_list.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,12 @@
(when (and (show-tree? connection)
(not (schema-disabled? connection)))
[:li
[:> ui/Disclosure {:defaultOpen default-opened?}
(fn [params]
(r/as-element
[:<>
[:> (.-Button ui/Disclosure)
{:class (str "flex items-center gap-2 text-xs text-white font-semibold")}
[:> hero-solid-icon/CircleStackIcon {:class "text-white h-3 w-3 shrink-0"
:aria-hidden "true"}]
"Database schema"]

[:> (.-Panel ui/Disclosure) {:className "bg-gray-800 text-white p-2 rounded-md"}
[database-schema/main {:connection-name (:name connection)
:connection-type (cond
(not (cs/blank? (:subtype connection))) (:subtype connection)
(not (cs/blank? (:icon_name connection))) (:icon_name connection)
:else (:type connection))}]]]))]])
[database-schema/main {:connection-database-selected (:database_name connection)
:connection-name (:name connection)
:connection-type (cond
(not (cs/blank? (:subtype connection))) (:subtype connection)
(not (cs/blank? (:icon_name connection))) (:icon_name connection)
:else (:type connection))}]])

(when removed?
[:li {:class "flex items-center gap-2 text-xs text-white font-semibold cursor-pointer"
Expand Down
Loading

0 comments on commit 86acf6d

Please sign in to comment.