MY MONSTER IT LIVES!
This commit is contained in:
parent
7c9f7f91b4
commit
b69bcaa020
|
@ -44,7 +44,7 @@
|
||||||
(.exists (java.io.File. (first args)))
|
(.exists (java.io.File. (first args)))
|
||||||
(let [application (x/parse (first args))]
|
(let [application (x/parse (first args))]
|
||||||
(h/to-hugsql-queries application)
|
(h/to-hugsql-queries application)
|
||||||
;; (j/to-json-routes application)
|
(j/to-json-routes application)
|
||||||
(s/to-selmer-routes application)
|
(s/to-selmer-routes application)
|
||||||
(t/to-selmer-templates application))))
|
(t/to-selmer-templates application))))
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
(ns ^{:doc "Application Description Language: generate RING routes for REST requests."
|
(ns ^{:doc "Application Description Language: generate RING routes for REST requests."
|
||||||
:author "Simon Brooke"}
|
:author "Simon Brooke"}
|
||||||
adl.to-json-routes
|
adl.to-json-routes
|
||||||
(:require [clojure.java.io :refer [file]]
|
(:require [clojure.java.io :refer [file make-parents writer]]
|
||||||
|
[clojure.pprint :refer [pprint]]
|
||||||
[clojure.string :as s]
|
[clojure.string :as s]
|
||||||
|
[clojure.xml :as x]
|
||||||
[clj-time.core :as t]
|
[clj-time.core :as t]
|
||||||
[clj-time.format :as f]
|
[clj-time.format :as f]
|
||||||
[adl.utils :refer :all]))
|
[adl.utils :refer :all]
|
||||||
|
[adl.to-hugsql-queries :refer [queries]]))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;;;
|
;;;;
|
||||||
|
@ -34,11 +37,12 @@
|
||||||
;;; to-hugsql-queries, because essentially we need one JSON entry point to wrap
|
;;; to-hugsql-queries, because essentially we need one JSON entry point to wrap
|
||||||
;;; each query.
|
;;; each query.
|
||||||
|
|
||||||
(defn file-header [parent-name this-name]
|
|
||||||
|
(defn file-header [application]
|
||||||
(list
|
(list
|
||||||
'ns
|
'ns
|
||||||
(symbol (str parent-name ".routes." this-name))
|
(symbol (str (safe-name (:name (:attrs application))) ".routes.auto-json"))
|
||||||
(str "JSON routes for " parent-name
|
(str "JSON routes for " (:name (:attrs application))
|
||||||
" auto-generated by [Application Description Language framework](https://github.com/simon-brooke/adl) at "
|
" auto-generated by [Application Description Language framework](https://github.com/simon-brooke/adl) at "
|
||||||
(f/unparse (f/formatters :basic-date-time) (t/now)))
|
(f/unparse (f/formatters :basic-date-time) (t/now)))
|
||||||
(list
|
(list
|
||||||
|
@ -49,15 +53,11 @@
|
||||||
'[ring.util.http-response :as response]
|
'[ring.util.http-response :as response]
|
||||||
'[clojure.java.io :as io]
|
'[clojure.java.io :as io]
|
||||||
'[hugsql.core :as hugsql]
|
'[hugsql.core :as hugsql]
|
||||||
(vector (symbol (str parent-name ".db.core")) :as 'db))))
|
(vector (symbol (str (safe-name (:name (:attrs application))) ".db.core")) :as 'db))))
|
||||||
|
|
||||||
|
|
||||||
(defn make-safe-name [string]
|
|
||||||
(s/replace string #"[^a-zA-Z0-9-]" ""))
|
|
||||||
|
|
||||||
|
|
||||||
(defn declarations [handlers-map]
|
(defn declarations [handlers-map]
|
||||||
(cons 'declare (sort (map #(symbol (make-safe-name (name %))) (keys handlers-map)))))
|
(cons 'declare (sort (map #(symbol (name %)) (keys handlers-map)))))
|
||||||
|
|
||||||
|
|
||||||
(defn generate-handler-src
|
(defn generate-handler-src
|
||||||
|
@ -81,12 +81,12 @@
|
||||||
|
|
||||||
|
|
||||||
(defn handler
|
(defn handler
|
||||||
"Generate declarations for handlers from query with this `query-key` in this `queries-map` taken from within
|
"Generate declarations for handlers from query with this `query-key` in this `queries-map`
|
||||||
this `entities-map`. This method must follow the structure of
|
taken from within this `application`. This method must follow the structure of
|
||||||
`to-hugsql-queries/queries` quite closely, because we must generate the same names."
|
`to-hugsql-queries/queries` quite closely, because we must generate the same names."
|
||||||
[query-key queries-map entities-map]
|
[query-key queries-map application]
|
||||||
(let [query (query-key queries-map)
|
(let [query (query-key queries-map)
|
||||||
handler-name (symbol (make-safe-name (name query-key)))]
|
handler-name (symbol (name query-key))]
|
||||||
(hash-map
|
(hash-map
|
||||||
(keyword handler-name)
|
(keyword handler-name)
|
||||||
(merge
|
(merge
|
||||||
|
@ -182,6 +182,7 @@
|
||||||
|
|
||||||
|
|
||||||
(defn defroutes [handlers-map]
|
(defn defroutes [handlers-map]
|
||||||
|
"Generate JSON routes for all queries implied by this ADL `application` spec."
|
||||||
(cons
|
(cons
|
||||||
'defroutes
|
'defroutes
|
||||||
(cons
|
(cons
|
||||||
|
@ -190,7 +191,7 @@
|
||||||
#(let [handler (handlers-map %)]
|
#(let [handler (handlers-map %)]
|
||||||
(list
|
(list
|
||||||
(symbol (s/upper-case (name (:method handler))))
|
(symbol (s/upper-case (name (:method handler))))
|
||||||
(str "/json/auto/" (:name handler))
|
(str "/json/auto/" (safe-name (:name handler)))
|
||||||
'request
|
'request
|
||||||
(list
|
(list
|
||||||
'route/restricted
|
'route/restricted
|
||||||
|
@ -199,39 +200,46 @@
|
||||||
(keys handlers-map))))))
|
(keys handlers-map))))))
|
||||||
|
|
||||||
|
|
||||||
;; (defn migrations-to-json-routes
|
(defn make-handlers-map
|
||||||
;; ([migrations-path parent-namespace-name]
|
[application]
|
||||||
;; (migrations-to-json-routes migrations-path parent-namespace-name "auto-json-routes"))
|
(reduce
|
||||||
;; ([migrations-path parent-namespace-name namespace-name]
|
merge
|
||||||
;; (let [output (str (s/replace namespace-name #"-" "_") ".clj")
|
{}
|
||||||
;; adl-struct (migrations-to-xml migrations-path "Ignored")
|
(map
|
||||||
;; q (reduce
|
(fn [e]
|
||||||
;; merge
|
(let [qmap (queries application e)]
|
||||||
;; {}
|
(reduce
|
||||||
;; (map
|
merge
|
||||||
;; #(queries % adl-struct)
|
{}
|
||||||
;; (vals adl-struct)))
|
(map
|
||||||
;; h (reduce
|
(fn [k]
|
||||||
;; merge
|
(handler k qmap application))
|
||||||
;; {}
|
(keys qmap)))))
|
||||||
;; (map
|
(children-with-tag application :entity))))
|
||||||
;; #(handler % q adl-struct)
|
|
||||||
;; (keys q)))
|
|
||||||
;; f (cons
|
(defn to-json-routes
|
||||||
;; (file-header parent-namespace-name namespace-name)
|
[application]
|
||||||
;; ;; (pre-declare
|
(let [handlers-map (make-handlers-map application)
|
||||||
;; (cons
|
filepath (str *output-path* (:name (:attrs application)) "/routes/auto_json.clj")]
|
||||||
;; (declarations h)
|
(make-parents filepath)
|
||||||
;; (cons
|
(with-open [output (writer filepath)]
|
||||||
;; (defroutes h)
|
(binding [*out* output]
|
||||||
;; (map #(:src (h %)) (sort (keys h))))))]
|
(doall
|
||||||
;; (spit
|
(map
|
||||||
;; output
|
(fn [f]
|
||||||
;; (with-out-str
|
(pprint f)
|
||||||
;; (doall
|
(println "\n"))
|
||||||
;; (for [expr f]
|
(list
|
||||||
;; (do
|
(file-header application)
|
||||||
;; (pprint expr)
|
(declarations handlers-map)
|
||||||
;; (print "\n\n"))))))
|
(defroutes handlers-map))))
|
||||||
;; f
|
(doall
|
||||||
;; )))
|
(map
|
||||||
|
(fn [h]
|
||||||
|
(pprint (:src (handlers-map h)))
|
||||||
|
(println)
|
||||||
|
h)
|
||||||
|
(sort (keys handlers-map))))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
'[ring.util.http-response :as response]
|
'[ring.util.http-response :as response]
|
||||||
'[clojure.java.io :as io]
|
'[clojure.java.io :as io]
|
||||||
'[hugsql.core :as hugsql]
|
'[hugsql.core :as hugsql]
|
||||||
|
(vector (symbol (str (:name (:attrs application)) ".layout")) :as 'l)
|
||||||
(vector (symbol (str (:name (:attrs application)) ".db.core")) :as 'db)
|
(vector (symbol (str (:name (:attrs application)) ".db.core")) :as 'db)
|
||||||
(vector (symbol (str (:name (:attrs application)) ".routes.manual")) :as 'm))))
|
(vector (symbol (str (:name (:attrs application)) ".routes.manual")) :as 'm))))
|
||||||
|
|
||||||
|
@ -62,7 +63,7 @@
|
||||||
(vector 'r)
|
(vector 'r)
|
||||||
(list 'let (vector 'p (list :form-params 'r))
|
(list 'let (vector 'p (list :form-params 'r))
|
||||||
(list
|
(list
|
||||||
'layout/render
|
'l/render
|
||||||
(list 'resolve-template (str n ".html"))
|
(list 'resolve-template (str n ".html"))
|
||||||
(merge
|
(merge
|
||||||
{:title (capitalise (:name (:attrs f)))
|
{:title (capitalise (:name (:attrs f)))
|
||||||
|
@ -79,7 +80,7 @@
|
||||||
(list
|
(list
|
||||||
(symbol
|
(symbol
|
||||||
(str
|
(str
|
||||||
"db/search-"
|
"db/search-strings-"
|
||||||
(singularise (:name (:attrs e)))))
|
(singularise (:name (:attrs e)))))
|
||||||
'p)})))))))
|
'p)})))))))
|
||||||
|
|
||||||
|
@ -111,13 +112,38 @@
|
||||||
'defroutes
|
'defroutes
|
||||||
(cons
|
(cons
|
||||||
'auto-selmer-routes
|
'auto-selmer-routes
|
||||||
(interleave
|
(cons
|
||||||
(map
|
'(GET
|
||||||
(fn [r] (make-route 'GET r))
|
"/index"
|
||||||
(sort routes))
|
request
|
||||||
(map
|
(route/restricted
|
||||||
(fn [r] (make-route 'POST r))
|
(apply (resolve-handler "index") (list request))))
|
||||||
(sort routes)))))))
|
(interleave
|
||||||
|
(map
|
||||||
|
(fn [r] (make-route 'GET r))
|
||||||
|
(sort routes))
|
||||||
|
(map
|
||||||
|
(fn [r] (make-route 'POST r))
|
||||||
|
(sort routes))))))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn generate-handler-resolver
|
||||||
|
"Dodgy, dodgy, dodgy. Generate code which will look up functions in the
|
||||||
|
manual and in this namespace. I'm sure someone who really knew what they
|
||||||
|
were doing could write this more elegantly."
|
||||||
|
[application]
|
||||||
|
(list
|
||||||
|
'defn
|
||||||
|
'raw-resolve-handler
|
||||||
|
"Prefer the manually-written version of the handler with name `n`, if it exists, to the automatically generated one"
|
||||||
|
(vector 'n)
|
||||||
|
(list 'try
|
||||||
|
(list 'eval (list 'symbol (list 'str (:name (:attrs application)) ".routes.manual/" 'n)))
|
||||||
|
(list 'catch
|
||||||
|
'Exception '_
|
||||||
|
(list 'eval
|
||||||
|
(list 'symbol
|
||||||
|
(list 'str (:name (:attrs application)) ".routes.auto/" 'n)))))))
|
||||||
|
|
||||||
|
|
||||||
(defn to-selmer-routes
|
(defn to-selmer-routes
|
||||||
|
@ -134,13 +160,13 @@
|
||||||
n
|
n
|
||||||
(str "auto/" n))))
|
(str "auto/" n))))
|
||||||
(println)
|
(println)
|
||||||
(pprint '(def resolve-template (memoise raw-resolve-template)))
|
(pprint '(def resolve-template (memoize raw-resolve-template)))
|
||||||
(println)
|
(println)
|
||||||
(pprint '(defn index
|
(pprint '(defn index
|
||||||
[r]
|
[r]
|
||||||
(layout/render
|
(l/render
|
||||||
(resolve-template
|
(resolve-template
|
||||||
"application-index")
|
"application-index.html")
|
||||||
{:title "Administrative menu"})))
|
{:title "Administrative menu"})))
|
||||||
(println)
|
(println)
|
||||||
(doall
|
(doall
|
||||||
|
@ -153,14 +179,8 @@
|
||||||
(println))
|
(println))
|
||||||
(filter (fn [c] (#{:form :list :page} (:tag c))) (children e)))))
|
(filter (fn [c] (#{:form :list :page} (:tag c))) (children e)))))
|
||||||
(children-with-tag application :entity)))
|
(children-with-tag application :entity)))
|
||||||
(pprint '(defn raw-resolve-handler
|
(pprint
|
||||||
"Prefer the manually-written version of the handler with name `n`, if it exists, to the automatically generated one"
|
(generate-handler-resolver application))
|
||||||
[n]
|
|
||||||
(let [s (symbol (str "m." n))]
|
|
||||||
(if
|
|
||||||
(bound? s)
|
|
||||||
(eval s)
|
|
||||||
(eval (symbol n))))))
|
|
||||||
(println)
|
(println)
|
||||||
(pprint '(def resolve-handler
|
(pprint '(def resolve-handler
|
||||||
(memoize raw-resolve-handler)))
|
(memoize raw-resolve-handler)))
|
||||||
|
|
|
@ -90,7 +90,7 @@
|
||||||
"\n"
|
"\n"
|
||||||
(flatten
|
(flatten
|
||||||
(list
|
(list
|
||||||
"{% extends \"templates/base.html\" %}"
|
"{% extends \"base.html\" %}"
|
||||||
(str "<!-- File "
|
(str "<!-- File "
|
||||||
filename
|
filename
|
||||||
" generated "
|
" generated "
|
||||||
|
|
|
@ -181,6 +181,19 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(defn safe-name
|
||||||
|
([string]
|
||||||
|
(s/replace string #"[^a-zA-Z0-9-]" ""))
|
||||||
|
([string convention]
|
||||||
|
(case convention
|
||||||
|
(:sql :c) (s/replace string #"[^a-zA-Z0-9_]" "_")
|
||||||
|
:c-sharp (s/replace (capitalise string) #"[^a-zA-Z0-9]" "")
|
||||||
|
:java (let
|
||||||
|
[camel (s/replace (capitalise string) #"[^a-zA-Z0-9]" "")]
|
||||||
|
(apply str (cons (Character/toUpperCase (first camel)) (rest camel))))
|
||||||
|
(safe-name string))))
|
||||||
|
|
||||||
|
|
||||||
(defn link-table?
|
(defn link-table?
|
||||||
"Return true if this `entity` represents a link table."
|
"Return true if this `entity` represents a link table."
|
||||||
[entity]
|
[entity]
|
||||||
|
|
Loading…
Reference in a new issue