Fork me on GitHub
#clojure
<
2017-11-24
>
cmal08:11:39

Hi, I tried to do something like this in jdbc and get an Exception:

(j/db-do-prepared (:user-db @g-config) ["select
case
when (select 1 from user_favorstocks where uid=1823 and stockid='600123.SH') is not null
then (select 8)
else (select 5)
end as tmp"])
SQLException SQL String can not be NULL com.mysql.jdbc.SQLError.createSQLException (SQLError.java:957)

cmal08:11:09

what could be the reason?

pesterhazy08:11:55

@cmal, don't you need to prepare the statement first?

cmal08:11:17

maybe not

cmal08:11:39

The sql parameter can either be a SQL string or a PreparedStatement. in clojure.java.jdbc doc

cmal08:11:55

and here is the test code:

cmal08:11:00

(deftest test-do-prepared4
  (doseq [db (test-specs)]
    (create-test-table :fruit2 db)
    (sql/db-do-prepared db ["INSERT INTO fruit2 ( name, appearance, cost, grade ) VALUES ( ?, ?, ?, ? )" ["test" "test" 1 1.0] ["two" "two" 2 2.0]] {:multi? true})
    (is (= 2 (sql/query db ["SELECT * FROM fruit2"] {:result-set-fn count})))))

pesterhazy08:11:10

maybe you're looking for execute!?

cmal08:11:31

I've tried that seems not working.

cmal08:11:58

SQLException Can not issue executeUpdate() or executeLargeUpdate() for SELECTs com.mysql.jdbc.SQLError.createSQLException (SQLError.java:957) if I change to execute!

cmal08:11:52

btw, can I do an insert stmt in a then subclause?

pesterhazy08:11:34

ah you need query

pesterhazy08:11:29

execute! is only for "write"-y queries (INSERT, UPDATE, etc.)

cmal08:11:29

I am just trying to select something from the table, and if found, check the value of some column ( and if satisfied some condition do update, otherwise nothing ), if not ,do insert. And return a value that tells me what has been done.

cmal08:11:14

yes, but can I do an insert in a then subclause when using query?

pesterhazy08:11:25

you're shifting the goalposts

pesterhazy08:11:08

better to ask one thing at a time, not "everything I've always wanted to know about SQL"

cmal08:11:30

😄

cmal08:11:47

sorry for that.

cmal08:11:12

query works!

pesterhazy08:11:51

you can't nest INSERT inside of a compound statement - you'll need to do multiple queries, or use a stored procedure I think

cmal08:11:44

I tried to write a stored procedure but ERROR 1548 (HY000): Cannot load from mysql.proc. The table is probably corrupted happens. But it is not right to ask this here. It seems the mysql version is too old. some 5.1 version.

dominicm08:11:48

Is it possible to utilize java annotations from clojure?

dominicm09:11:43

@cmal perfect. Thanks. Completely missed that.

itaied10:11:52

I want to use migratus in my dev environment. I also use environ to manage environments variables. How can I set a value in my project.clj by evaluating data from environ? working example:

clojure
:migratus {:store         :database
             :migration-dir "migrations"
             :db            ""}
What I want:
clojure

itaied10:11:24

:migratus {:store         :database
             :migration-dir "migrations"
             :db            ~(environ.core/env :db-url)}

igrishaev11:11:55

@itaied :migratus {:store :database :db ~(get (System/getenv) "DATABASE_URL")}

igrishaev11:11:31

@itaied the rule is simple: once lein sees a list form, it tries to evaluate it.

itaied11:11:25

But using environ, my DB_URL is not in the System/getenv map

vemv11:11:18

Can (let [...] (defn ...)) be problematic? (generally I'd never do that, but from time to time I need some dynamism e.g. defns emitted from macros)

val_waeselynck17:11:58

Not that I know of; (def fname (let [,,,] (fn ,,,))) may be more conventional

vemv18:11:10

Thanks for the input! Might end up using that one

Bravi20:11:00

I’m using stuartsierra component and can’t figure out how to fix this error anyhow. any hints would be much appreciated:

IllegalArgumentException No implementation of method: :stop of protocol: #'com.stuartsierra.component/Lifecycle found for class: nil  clojure.core/-cache-protocol-fn (core_deftype.clj:568)
this is my application:
(ns application.system
  (:require [application.web :refer [app]]
            [com.stuartsierra.component :as component]
            [org.httpkit.server :refer [run-server]]))

(defn- start-server [handler port]
  (run-server app {:port port})
  (println "Started server on localhost" port))

(defn- stop-server [server]
  (when server
    (server)))

(defrecord Application []
  component/Lifecycle
  (start [this]
    (assoc this :server (start-server #'app 9009)))
  (stop [this]
    (stop-server (:server this))
    (dissoc this :server)))

(defn create-system []
  (Application.))

(defn -main [& args]
  (.start (create-system)))

danielsz20:11:56

Do you know about the system library?

danielsz20:11:53

It looks like it could be helpful based on your recent questions in the channel.

danielsz20:11:13

Also lots of examples in the repo

noisesmith20:11:31

@bravilogy that error means one of your components returns nil instead of a valid component

noisesmith20:11:48

(probably from a start method)

Bravi20:11:27

but it relates to this Application component right?

noisesmith20:11:49

how would I know?

noisesmith20:11:00

one of your components, when started, returns nil instead of a component

noisesmith20:11:06

that's what causes that error

noisesmith20:11:17

unless you call stop on the wrong object and it was not your component in the first place

Bravi20:11:19

😄 well this is my whole application, so .. it has to be here

Bravi20:11:20

somewhere

noisesmith20:11:08

OK - nothing in that code is calling the stop method

noisesmith20:11:12

who calls the stop method?

the2bears20:11:21

I don't know component at all, but should 'start-server' return anything? It's returning nil at the moment.

noisesmith20:11:46

@the2bears that's the error, good eye

noisesmith20:11:23

@bravilogy - println returns nil, so start-server returns nil

Bravi20:11:49

ah damn it should be the other way round

noisesmith20:11:53

we still don't know what is calling stop, but that's what is causing the error

Bravi20:11:14

yeah that was the issue. I had to have them other way round

Bravi20:11:24

now the server instance is returned and life is good

Bravi20:11:29

… again

qqq22:11:55

is there a clojure builtin for "take this vec of 5 elements, pad it to a list of 10 elemes by adding :null" 's ?

qqq22:11:08

basically, "make this vec longer by repeating this elem"

noisesmith22:11:55

no builtin, I'd use concat and repeat (concat coll (repeat 5 nil)) or (take 10 (concat coll (repeat nil)))

dpsutton22:11:01

(first (partition 10 10 (repeat :b) [:a]))

dpsutton22:11:08

you could partition with a pad and take the first partition

dpsutton22:11:26

although i think the take concat version is nicer