Accessing profiles.clj data from within project.clj - clojure

I am trying to use Joplin and was thinking about tackling the issue hinted at in this issue.
Well, I want to store sensitive information outside of version control. I was thinking of using a profiles.clj file with environment information for each database. So, I could make a dev profile with an SQL database username and a password. So inside profiles.clj:
{:dev {:db {:user "dirtymike" :password "secret"}}}
But then in project.clj, I have to pass this to the :joplin map entry of defproject. Is that even possible?

You may want to look into environ. It does pretty much what you want to do in a slightly different way.

Maybe this blog post will help you http://blog.martinhynar.cz/2014/10/14/Project-clj-data-into-runtime.html

Related

How to access db.clj methods in core.cljs in clojure

I am trying to create a web app in clojure.
i have used clojurescript om and react.
there are two files core.cljs and db.clj.
core.cljs contains ui for login page and db.clj contains all database connections.
Now i am trying to call a db.clj method add-user[username password] in
core.cljs.
In db.clj
(defn add-user [username,password]
(sql/with-connection db
(sql/insert-values :users [:username :password]
[username password])))
In core.cljs
(dom/button #js {:ref "submit"
:onClick (fn[e](add-user usname passwrd))}"submit")
But i am not able to call that method in core.cljs.
It shows some error message like
clojure.lang.ExceptionInfo : failed compiling file:src\login_page\core.cljs
clojure.lang.ExceptionInfo : No such namespace: login_page.db, could not locate login_page/db.cljs, login_page/db.cljc, or Closure namespace "login_page.db"
Rename db.clj to either db.cljs or db.cljc. That should get you past the 'No such namespace' error message.
That's the basic gist of it. Of course your dependencies on clj libraries will have to be removed - that might be the reason for the negative comment below. Alter your code so that you use a simple atom as your database. That should get you developing.
And you can wait for a much better answer than this one that will show you how to get the Client and Server communication setup. But it may not come because, as pointed out in the comments, there is already documentation for this, and unfortunately quite a few choices that have to be made. Another unfortunate thing is that the way to do it now may not be the way to do it early next year. Watch the Om-Next space!
I've never had any problems compiling .cljs or .cljc files. You just have to set up your lein project.clj file properly. There will be plenty of examples if you Google around, or you can take a look at the following small Github project: https://github.com/chrismurrph/passing-time - no need to worry about the code, just look at its project.clj file.

How do I get the environment name when using environ in Clojure?

How do I get the environment name when using environ in Clojure? I mean, :dev, :test, etc. The reason for wanting this is to pass it to Yeller so when it displays errors it can tell me which environment they happened into. Errors in staging are treated differently than errors in production.
Environ only provides access to environment variables, you need to set them yourself. You can use lein-environ to set environment variables in your project.clj in different profiles. These profiles will be picked by leiningen and merged together, which you can then access from your code. For example, we have:
:profiles {:dev {:resource-paths ["test-resources"]
:env {:environment "development"
:db-host "localhost"
:port 5000}}}
In production we provide actual environment variables instead.
Just the same as you want to "Tell, don't ask" in your code, you need to just use the config options and let environ figure out what the right one is based on the environment. In the rare event that you actually need the environment name itself just put it in the :env map for each environment.

Clojure REPL and workflow

Coming from Haskell, my usual workflow would be to :l <file name.hs> on ghci and use the functions and ADT that I have there.
Right now I am using lein repl on a typical lein new app project context. I have created a testing.clj file next to my core.clj. There I defined a couple of functions, a protocol and a record implementing the protocol. I was able to use the function by (use 'testing.testing :reload) the problem is that I am not able to use the actual record:
(def c (Something. 0))
I get:
CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: Something
So, what would be the a "better" workflow in this case? Where I don't want to set the functions, protocols, records directly on the REPL, but also I don't want to rely on my core.cls file? I just want a file where I can dump a bunch of stuff and play with it.
PS: My env is Mac OSX Terminal + Sublime
Edit: After a couple of minutes I was able to load the record by:
(load-file <file name>)
(import 'testing.testing.Something)
I mean, for sure there is a better way than this... :/ I just want to load everything. On the other hand I am able to use the protocol methods the record implements.
Have you tried using the convenience function that is automatically defined for creating records? In this example it would be (->Something 0).
(Something. 0) is using the Java constructor, which requires importing the Java class separately. The Java class is created automatically when you define a record to allow Java interop with things you've defined in Clojure.
Using the (->Something 0) syntax is the correct way to go and should be possible after you (use 'testing.testing :reload).
Edit Given the above didn't seem to help, here's some step-by-step instructions to get a minimal working example
You have an app directory testing created with lein new app testing
In testing/src/testing you create testing.clj containing the following two lines
(ns testing.testing)
(defrecord Something [n])
Run lein repl from within your project directory
Use the namespace with (use 'testing.testing :reload)
(:n (->Something 42)) will create an instance of Something and retrieve the value of its n member - in this case 42.

Django doesn't read from database – no error

I just set up the environment for an existing Django project, on a new Mac. I know for certain there is nothing wrong with the code itself (just cloned the repo), but for some reason, Django can't seem to retrieve data from the database.
I know the correct tables and data is in the db.
I know the codebase is as it should be.
I can make queries using the Django shell.
Django doesn't throw any errors despite the data missing on the web page.
I realize that it's hard to debug this without further information, but I would really appreciate a finger pointing me to the right direction. I can't seem to find any useful logs.
EDIT:
I just realized the problem lies elsewhere. Unfortunately I can't delete this post with the bounty still open.
Without seeing any code, I can only suggest some general advice that might help you debug your problem. Please add a link to your repository if you can or some snippets of your database settings, the view which includes the database queries etc...
Debugging the view
The first thing I would recommend is using the python debugger inside the view which queries the database. If you've not used pdb before, it's a life saver which allows you to set breakpoints in your Python script and then interactively execute code inside the interpreter
>>> import pdb
>>> pdb.set_trace()
>>> # look at the results of your queries
If you are using the Django ORM, the QuerySet returned from the query should have all the data you expect.
If it doesn't then you need to look into your database configuration in settings.py.
If it does, then you must might not be returning that object to the template? Unlikely as you said the code was the same, but double check the objects you pass with your HttpResponse object.
Debugging the database settings
If you can query the database using the project settings inside settings.py from the django shell it sounds unlikley that there is a problem with this - but like everything double check.
You said that you've set up a new project on a mac. What is on a different operating system before? Maybe there is a problem with the paths now - to make your project platform independent remember to use the os.path.join() method when working with file paths.
And what about the username and password details....
Debugging the template
Maybe your template is referencing the wrong object variable name or object attribute.You mentioned that
Django doesn't throw any errors despite the data missing on the web
page.
This doesn't really tell us much - to quote the Django docs -
If you use a variable that doesn’t exist, the template system will
insert the value of the TEMPLATE_STRING_IF_INVALID setting, which is
set to '' (the empty string) by default.
So to check all the variables available to your template, you could use the debug template tag
{{ debug }}
Probably even better though is to use the django-debugging-toolbar - this will also let you examine the SQL queries your view is making.
Missing Modules
I would expect this to raise an exception if this were the problem, but have you checked that you have the psycopg module on your new machine?

Clojure: reload from string

EDIT: is what I want basically load-string?
Question
In Clojure, if I do:
(require :reload 'foo.bar)
then Clojure looks for src/foo/bar.clj, and reloads it.
Now, I want to do something like this:
(reload-from-string 'foo.bar STR)
the semantics of this would be: reload namespace 'foo.bar, but instead of compiling src/foo/bar.clj, compile STR instead.
How do I define reload-from-string?
Context
I need to hot reload code on a server that is running an Clojure application. I don't want to have to continuously shuffle files back & forth to the server (either via scp, sftp, or fuse/sshfs) in order to reload. Thus, I would prefer to just pass it a string.
Thanks!
You can use read-string and then eval. Keep in mind the risks though. An advantage of splitting them up is you can whitelist what is present in the resulting list before evaling it.
You probably want to bind *read-eval* to false also.