I have a clojure project and I want to use a h2 database with it. Is there a way to check if the database exists? I tried something like this:
(defn mysql-db []
(if (.exists (clojure.java.io/as-file "my-webapp.h2.db"))
(println "exists")
(j/with-connection
{:classname "org.h2.Driver"
:subprotocol "h2:file"
:subname "db/my-webapp"}
(j/create-table :locations
[:id "bigint primary key auto_increment"]
[:title "varchar (255)"]
[:part "clob"])
(j/insert-records :locations
{:title "Steven Gerrard: I'm not the new Beckham"
:part "He might not have the Becks appeal -- but Steven Gerrard says he's ready to light up Hollywood in his own way..."}))))
But the .exists function always returns false.
I changed the
(if (.exists (clojure.java.io/as-file "my-webapp.h2.db"))
line into
(if (.exists (clojure.java.io/as-file "db/my-webapp.h2.db"))
and it works. I guess I was not looking in the right folder.
Related
I am new to the Firestore and Clojure.
Below is my code, Get returns the correct data, however, Set is not successful, without any exception or response.
(defn database-instance
[]
(FirestoreClient/getFirestore))
(def user (java.util.HashMap. {"age" 50
"name" "Josh"
"user_id" "user02"}))
(defn get-credit-detail!
[msg]
(def result
(-> (database-instance)
(.collection "credits")
(.document "document")
(.get)
(.get)
))
(println (.getData result))
;; this Set does not work
(-> (database-instance)
(.collection "credits")
(.document "document1")
(.set user)
)
)
Can you help me with the Set to be able to add new data to firestore?
Thanks!
A little late to answer this but what you have should work. I tried it through the REPL and verified the set worked from the firebase console. Note that you can use a Clojure map with String keys as input without having to resort to creating a java.util.Map.
(-> (database-instance)
(.collection "credits")
(.document "document1")
(.set {"age" 50 "name" "Josh" "user_id" "user02"}))
The docstrings for some Clojure functions (e.g. defrecord) are quite long. When running Clojure at in a terminal window, I'd like to be able to in effect send doc's output through a pager such as more (or less). If someone has written a pager function in Clojure, then I think I could use it along with something like:
(with-out-str (doc defrecord))
Or if there is a standard Java class that implements a pager, I can figure out how to send the output to that.
Alternatively, how can I send the output of doc to a shell command? This doesn't do the job:
(clojure.java.shell/sh "more" :in (with-out-str (doc defrecord))))
[This topic is difficult to search: "more", "less", and "doc" are obviously very common terms, and things like "java pager" bring up pages discussing ways to break text up into pages for formatting documents.]
You can use jline for this. If you call setPaginationEnabled, with true, and use the printColumns method, on your jline ConsoleReader, it will page.
But, if you are trying to do this at a standard Leiningen REPL, things get more complicated. The current version of Leiningen v2 uses REPL-y, which uses jline internally, but doesn't use printColumns, so the jline pagination is ignored.
You can, however, get the current Leiningen REPL height through REPL-y's ConsoleReader, in reply.reader.simple-jline/jline-state, and use it to partition the doc string.
(defmacro doc2 [x]
`(let [h# (-> #reply.reader.simple-jline/jline-state :reader (.. getTerminal getHeight) (- 4))
[s1# s2#] (split-at h# (-> ~x clojure.repl/doc with-out-str clojure.string/split-lines))]
(doseq [x# s1#] (println x#))
(doseq [i# (partition-all h# s2#)]
(println "\n<more>")
(read-line)
(doseq [x# i#] (println x#)))))
You would want to put this macro in your profiles.clj under the :repl profile.
{:user {:plugins [...]}
:repl {:repl-options {:init (defmacro doc2 [x] ...)}}}
This would put the doc2 macro in the user namespace when you load the repl.
echo "(doc defrecord)" |clj|more
I have a function that begins like this:
(defn data-one [suser]
(def suser-first-name
(select db/firstNames
(fields :firstname)
(where {:username suser})))
(def suser-middle-name
(select db/middleNames
(fields :middlename)
(where {:username suser})))
(def suser-last-name
(select db/middleNames
(fields :lastname)
(where {:username suser})))
;; And it just continues on and on...
)
Of course, I don't like this at all. I have this pattern repeating in many areas in my code-base and I'd like to generalize this.
So, I came up with the following to start:
(def data-input {:one '[suser-first-name db/firstNames :firstname]
'[suser-middle-name db/middleNames :middlename]
'[suser-last-name db/lastNames :lastname]})
(defpartial data-build [data-item suser]
;; data-item takes the arg :one in this case
`(def (data-input data-item)
(select (data-input data-item)
(fields (data-input data-item))
(where {:username suser}))))
There's really a few questions here:
-- How can I deconstruct the data-input so that it creates x functions when x is unknown, ie. that the values of :one is unknown, and that the quantities of keys in data-input is unknown.
-- I'm thinking that this is a time to create a macro, but I've never built one before, so I am hesitant on the idea.
And to give a little context, the functions must return values to be deconstructed, but I think once I get this piece solved, generalizing all of this will be doable:
(defpage "/page-one" []
(let [suser (sesh/get :username)]
(data-one suser)
[:p "Firat Name: "
[:i (let [[{fname :firstname}] suser-first-name]
(format "%s" fname))]
[:p "Middle Name: "
[:i (let [[{mname :emptype}] suser-middle-name]
(format "%s" mname))]
[:p "Last Name: "
[:i (let [[{lname :months}] suser-last-name]
(format "%s" lname))]]))
Some suggestions:
def inside a function is really nasty - you are altering the global environment, and it can cause all kinds of issues with concurrency. I would suggest storing the results in a map instead.
You don't need a macro here - all of the data fetches can be done relatively easily within a function
I would therefore suggest something like:
(def data-input [[:suser-first-name db/firstNames :firstname]
[:suser-middle-name db/middleNames :middlename]
[:suser-last-name db/lastNames :lastname]])
(def data-build [data-input suser]
(loop [output {}
items (seq data-input)]
(if items
(recur
(let [[kw db fieldname] (first items)]
(assoc output kw (select db (fields fieldname) (where {:username suser}))))
(next items))
output)))
Not tested as I don't have your database setup - but hopefully that gives you an idea of how to do this without either macros or mutable globals!
Nice question. First of all here's the macro that you asked for:
(defmacro defquery [fname table fields ]
(let [arg-name (symbol 'user-name)
fname (symbol fname)]
`(defn ~fname [~arg-name]
(print ~arg-name (str ~# fields)))))
You can call it like that:
(defquery suser-first-name db/firstNames [:firstname])
or if you prefer to keep all your configurations in a map, then it will accept string as the first argument instead of a symbol:
(defquery "suser-first-name" db/firstNames [:firstname])
Now, if you don't mind me recommending another solution, I would probably chose to use a single function closed around configuration. Something like that:
(defn make-reader [query-configurations]
(fn [query-type user-name]
(let [{table :table field-names :fields}
(get query-configurations query-type)]
(select table
(apply fields field-names)
(where {:username suser})))))
(def data-input {:firstname {:table db/firstNames :fields :firstname}
:middlename {:table db/middleNames :fields :middlename}
:lastname {:table db/lastNames :fields :lastname}})
(def query-function (make-reader data-input))
;; Example of executing a query
(query-function :firstname "tom")
By the way there's another way to use Korma:
;; This creates a template select from the table
(def table-select (select* db/firstNames))
;; This creates new select query for a specific field
(def first-name-select (fields table-select :firstname))
;; Creating yet another query that filters results by :username
(defn mkselect-for-user [suser query]
(where query {:username suser}))
;; Running the query for username "tom"
;; I fully specified exec function name only to show where it comes from.
(korma.core/exec (mkselect-for-user "tom" first-name-select))
For more information I highly recommend looking at Korma sources.
Clojure beginner here! I added flash message support to my Hiccup code in a Noir project.
What I'm trying to do is check if the message string for each specific was set or not. If there's no message, then I don't want to display the specific flash element containing that message.
(defpartial success-flash [msg]
[:div.alert.notice.alert-success
[:a.close {:data-dismiss "alert"} "x"]
[:div#flash_notice msg]])
(defpartial error-flash [msg]
[:div.alert.notice.alert-error
[:a.close {:data-dismiss "alert"} "x"]
[:div#flash_notice msg]])
[..]
(defpartial layout [& content]
(html5
[:head
[...]
[:body
(list
[...]
[:div.container
(let [error-msg (session/flash-get :error-message)
error-div (if (nil? error-msg) () (error-flash error-msg))
success-msg (session/flash-get :success-message)
success-div (if (nil? success-msg) () (success-flash success-msg))]
warning-msg (session/flash-get :warning-message)
warning-div (if (nil? warning-msg) () (warning-flash warning-msg))]
(list error-div success-div warning-div content))])]))
Disclaimer: I completely agree that you won't likely ever be in a situation where you'll need more than one of those specific flashes on at once, but indulge me in my attempt at figuring out a better and more functional way of implementing this.
I'm confident that there's a pattern out there for handling similar situations. Basically I check the value of several expressions, do a bunch of stuff with those values, and then act based on the results. You could pull this off with a progressively more and more monstrous (cond), but my solution is at least somewhat cleaner.
Tips?
You could also use when-let.
(defpartial layout
[& contents]
(html5
[:body
(when-let [msg (session/flash-get :error-message)]
(error-flash msg))
(when-let [msg (session/flash-get :warning-message)]
(warning-flash msg))
(when-let [msg (session/flash-get :success-message)]
(success-flash msg))
contents))
I'm not a hiccup expert, but I think this should work. I find it a little clearer on what's going on, although it's slightly more verbose.
The pattern is called mapping value. Below is an example that uses keep function to apply the pattern of mapping values and then filtering them
(use 'clojure.contrib.core)
(def flash-message
[[:error-message error-flash]
[:success-message success-flash]
[:warning-message warning-flash]])
(keep (fn [m f] (-?>> m (session/flash-get) (f))) flash-message)
[this may seem like my problem is with Compojure, but it isn't - it's with Clojure]
I've been pulling my hair out on this seemingly simple issue - but am getting nowhere.
I am playing with Compojure (a light web framework for Clojure) and I would just like to generate a web page showing showing my list of todos that are in a PostgreSQL database.
The code snippets are below (left out the database connection, query, etc - but that part isn't needed because specific issue is that the resulting HTML shows nothing between the <body> and </body> tags).
As a test, I tried hard-coding the string in the call to main-layout, like this:
(html (main-layout "Aki's Todos" "Haircut<br>Study Clojure<br>Answer a question on Stackoverfolw")) - and it works fine.
So the real issue is that I do not believe I know how to build up a string in Clojure. Not the idiomatic way, and not by calling out to Java's StringBuilder either - as I have attempted to do in the code below.
A virtual beer, and a big upvote to whoever can solve it! Many thanks!
=============================================================
;The master template (a very simple POC for now, but can expand on it later)
(defn main-layout
"This is one of the html layouts for the pages assets - just like a master page"
[title body]
(html
[:html
[:head
[:title title]
(include-js "todos.js")
(include-css "todos.css")]
[:body body]]))
(defn show-all-todos
"This function will generate the todos HTML table and call the layout function"
[]
(let [rs (select-all-todos)
sbHTML (new StringBuilder)]
(for [rec rs]
(.append sbHTML (str rec "<br><br>")))
(html (main-layout "Aki's Todos" (.toString sbHTML)))))
=============================================================
Again, the result is a web page but with nothing between the body tags. If I replace the code in the for loop with println statements, and direct the code to the repl - forgetting about the web page stuff (ie. the call to main-layout), the resultset gets printed - BUT - the issue is with building up the string.
Thanks again.
~Aki
for is lazy, and in your function it's never being evaluated. Change for to doseq.
user> (let [rs ["foo" "bar"]
sbHTML (new StringBuilder)]
(for [rec rs]
(.append sbHTML (str rec "<br><br>")))
(.toString sbHTML))
""
user> (let [rs ["foo" "bar"]
sbHTML (new StringBuilder)]
(doseq [rec rs]
(.append sbHTML (str rec "<br><br>")))
(.toString sbHTML))
"foo<br><br>bar<br><br>"
You could also use reduce and interpose, or clojure.string/join from clojure.string, or probably some other options.
user> (let [rs ["foo" "bar"]]
(reduce str (interpose "<br><br>" rs)))
"foo<br><br>bar"
user> (require 'clojure.string)
nil
user> (let [rs ["foo" "bar"]]
(clojure.string/join "<br><br>" rs))
"foo<br><br>bar"
You would like to use the re-gsub like this:
(require 'clojure.contrib.str-utils) ;;put in head for enabling us to use re-gsub later on
(clojure.contrib.str-utils/re-gsub #"\newline" "<br><br>" your-string-with-todos-separated-with-newlines)
This last line will result in the string you like. The require-part is, as you maybe already know, there to enable the compiler to reach the powerful clojure.contrib.str-utils library without importing it to your current namespace (which could potentially lead to unnescessary collisions when the program grows).
re- is for reg-exp, and lets you define a reg-exp of the form #"regexp", which to replace all instances that is hit by the regexp with the argument afterwards, applied to the third argument. The \newline is in this case clojures way of expressing newlines in regexps as well as strings and the character we are looking for.
What I think you really wanted to do is to make a nifty ordered or unordered list in html-format. These can be done with [hiccup-page-helpers][2] (if you don't have them you probably have a compojure from the time before it got splited up in compojure, hiccup and more, since you use the html-function).
If you want to use hiccup-page-helpers, use the command re-split from the clojure.contrib.str-utils mentioned above in this fashion:
(use 'hiccup.page-helpers) ;;watch out for namespace collisions, since all the functions in hiccup.page-helpers got into your current namespace.
(unordered-list (clojure.contrib.str-utils/re-split #"\newline" your-string-with-todos-separated-with-newlines))
which should render a neat
<ul>
<li>todo-item1</li>
<li>todo-item2</li>
</ul>
(and yes, there is an ordered-list command that works the same way!)
In the last line of clojure code above, all you todos gets into a (list "todo1" "todo2") which is immediately consumed by hiccup.page-helpers unordered-list function and is there converted to an html-ized list.
Good luck with compojure and friends!