Function in namespace isn't being read?

104 views Asked by At

I set up a basic luminus template with postgres. I want to be able to add new users and authenticate them, following an example from Ch.6 p.168 in this book: https://pragprog.com/titles/dswdcloj3/web-development-with-clojure-third-edition/

I had issues, so I started over with a new project to just try to get through this part.

I created a new luminus project, I created the database table, and I updated the project.clj file. I'm getting an error, when I try to create a test user.

I have done the following commands:

lein new luminus testproject --template-version 3.91 -- +postgres +http-kit
cd testproject
lein repl

in another terminal, I do

psql
CREATE USER testproject WITH PASSWORD 'password';
CREATE DATABASE testproject WITH OWNER testproject;

I updated the dev_config.edn file:

{:dev true
 :port 3000
 :nrepl-port 7000
 :database-url "postgresql://localhost:5432/testproject?user=testproject&password=password"

}

Then I did

lein repl
(start)
(create-migration "add-users-table")
(migrate)
(in-ns 'testproject)
(create-user! "testuser" "testpass")

I get this error:

Unable to resolve symbol: create-user! in this context

files I edited/created: project.clj (added buddy)

auth.clj:

(ns testproject.core
  (:require
   [buddy.hashers :as hashers]
   [next.jdbc :as jdbc]
   [testproject.db.core :as db]))

(defn create-user! [login password]
  (jdbc/with-transaction [t-conn db/*db*]
    (if-not (empty? (db/get-user-for-auth* t-conn {:login login}))
      (throw (ex-info "User already exists!"
                      {:testproject/error-id ::duplicate-user
                       :error "User already exists!"}))
      (db/create-user!* t-conn
                        {:login login
                         :password (hashers/derive password)}))))

(defn authenticate-user [login password]
  (let [{hashed :password :as user} (db/get-user-for-auth* {:login login})]
    (when (hashers/check password hashed)
      (dissoc user :password))))

queries.sql:

-- :name create-user!* :! :n
-- :doc creates a new user with the provided login and hashed password
INSERT INTO users
(login, password)
VALUES (:login, :password)
-- :name get-user-for-auth* :? :1
-- :doc selects a user for authentication
SELECT * FROM users
WHERE login = :login

migrations: add users table up:

CREATE TABLE users
(login text PRIMARY KEY,
password text not null,
created_at TIMESTAMP not null DEFAULT now());

add users table down:

DROP TABLE users;

I was able to add messages/posts just fine. For this testproject, I just am trying to do the new users to isolate the issue.

What am I doing wrong? What parts should I pay attention to?

Thanks.

3

There are 3 answers

3
Alan Thompson On

Try this:

(in-ns 'testproject.core)

Every part of the namespace symbol is important.

1
Sean Corfield On

You must require a namespace to load it before you use in-ns -- otherwise you're just going to navigate into an empty namespace with no functions in (and not even the clojure.core functions referred into it!).

0
JasonXuNAlasfjdao On

Thanks for the help everyone. I had a typo. My function is in the auth.clj file, which I labeled (ns testproject.core ...), so that was a big error. I changed it to testproject.auth, then required that namespace, and then was able to use the function correctly.