Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update clojure/java.jdbc #38

Closed
kostafey opened this issue Dec 26, 2017 · 10 comments
Closed

Update clojure/java.jdbc #38

kostafey opened this issue Dec 26, 2017 · 10 comments

Comments

@kostafey
Copy link
Owner

No description provided.

@stardiviner
Copy link
Contributor

New clojure/java.jdbc from (maybe) 0.7.0 support new style db-spec like this:

(def postgresql-db {:dbtype   "postgresql"
                    :host     "localhost"
                    :user     "clojure_test"
                    :password "clojure_test"
                    :dbname   "clojure_test"})

Can ejc-sql update to this version so that define db-spec can be easier?

@kostafey
Copy link
Owner Author

kostafey commented Aug 24, 2018

Actually, you can try clojure_java.jdbc_0.7.6 branch. Unfortunately, it breaks backward compatibility with some existing connection examples (e.g. old-style Oracle connections). The most reliable approach is to use :connection-uri.
Anyway, I'll merge it to master after some mitigation measures of such update.

@stardiviner
Copy link
Contributor

That's great. Thanks 👍
If I want to try clojure_java.jdbc_0.7.6, How to configure it in ejc-sql?

@kostafey
Copy link
Owner Author

In the theory, the previous configuration can be used as-is, but backward compatibility may be broken.
If so, you can try to use :dbtype instead of :subprotocol and split :subname into :dbname, :host and :port.
E.g. replace

:subprotocol "oracle"
:subname "thin:@localhost:1521:my_db_name"

with

:dbtype "oracle"
:dbname "my_db_name"
:host "localhost"
:port "1521"

@stardiviner
Copy link
Contributor

If I use ejc-connect, It must be supported in ejc-sql struct, maybe I can use lein run, then ejc-connect-existing-repl? But I'm not sure that will not, I guess it will not, because seems ejc-sql did some extra work on SQL completion, and configuration etc.

@kostafey
Copy link
Owner Author

kostafey commented Aug 28, 2018

I use clojure_java.jdbc_0.7.6 branch for my personal work. But I keep the previous version - org.clojure/java.jdbc "0.5.8" as a dependency in master (and in MELPA) since someone can accidentally face a problem during the ordinary update. Connections can stop working. That is not ejc-sql issue, it's a clojure_java.jdbc - related.
I guess, that I should freeze some master's commit (as some release branch), and distribute it via MELPA STABLE. Then I will provide the latest versions in MELPA.

At this moment, If you want to use new db-spec style, you can checkout clojure_java.jdbc_0.7.6 branch manually, load it in your .emacs update ejc-create-connection configurations (see get-connection docs), launch REPL in new ejc-sql project and continue using it as you do it before.

@stardiviner
Copy link
Contributor

stardiviner commented Aug 29, 2018

I use the clojure_java.jdbc_0.7.6 branch, and got this error:

Debugger entered--Lisp error: (wrong-type-argument arrayp nil)
  file-truename(nil)
  (make-ejc-db-conn :classpath (file-truename classpath) :classname classname :subprotocol subprotocol :subname subname :dbtype dbtype :dbname dbname :host host :port port :user user :password password :database database :connection-uri connection-uri :separator separator)
  (cons connection-name (make-ejc-db-conn :classpath (file-truename classpath) :classname classname :subprotocol subprotocol :subname subname :dbtype dbtype :dbname dbname :host host :port port :user user :password password :database database :connection-uri connection-uri :separator separator))
  (cons (cons connection-name (make-ejc-db-conn :classpath (file-truename classpath) :classname classname :subprotocol subprotocol :subname subname :dbtype dbtype :dbname dbname :host host :port port :user user :password password :database database :connection-uri connection-uri :separator separator)) ejc-connections)
  (setq ejc-connections (cons (cons connection-name (make-ejc-db-conn :classpath (file-truename classpath) :classname classname :subprotocol subprotocol :subname subname :dbtype dbtype :dbname dbname :host host :port port :user user :password password :database database :connection-uri connection-uri :separator separator)) ejc-connections))
  (progn (setq ejc-connections (-remove (function (lambda (x) (equal (car x) connection-name))) ejc-connections)) (setq ejc-connections (cons (cons connection-name (make-ejc-db-conn :classpath (file-truename classpath) :classname classname :subprotocol subprotocol :subname subname :dbtype dbtype :dbname dbname :host host :port port :user user :password password :database database :connection-uri connection-uri :separator separator)) ejc-connections)))
  (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --cl-keys--) '(:classpath :classname :subprotocol :subname :dbtype :dbname :host :port :user :password :database :connection-uri :separator :allow-other-keys)) (setq --cl-keys-- (cdr (cdr --cl-keys--)))) ((car (cdr (memq ':allow-other-keys --cl-rest--))) (setq --cl-keys-- nil)) (t (error "Keyword argument %s not one of (:classpath :classname :subprotocol :subname :dbtype :dbname :host :port :user :password :database :connection-uri :separator)" (car --cl-keys--)))))) (progn (setq ejc-connections (-remove (function (lambda (x) (equal (car x) connection-name))) ejc-connections)) (setq ejc-connections (cons (cons connection-name (make-ejc-db-conn :classpath (file-truename classpath) :classname classname :subprotocol subprotocol :subname subname :dbtype dbtype :dbname dbname :host host :port port :user user :password password :database database :connection-uri connection-uri :separator separator)) ejc-connections))))
  (let* ((classpath (car (cdr (plist-member --cl-rest-- ':classpath)))) (classname (car (cdr (plist-member --cl-rest-- ':classname)))) (subprotocol (car (cdr (plist-member --cl-rest-- ':subprotocol)))) (subname (car (cdr (plist-member --cl-rest-- ':subname)))) (dbtype (car (cdr (plist-member --cl-rest-- ':dbtype)))) (dbname (car (cdr (plist-member --cl-rest-- ':dbname)))) (host (car (cdr (plist-member --cl-rest-- ':host)))) (port (car (cdr (plist-member --cl-rest-- ':port)))) (user (car (cdr (plist-member --cl-rest-- ':user)))) (password (car (cdr (plist-member --cl-rest-- ':password)))) (database (car (cdr (plist-member --cl-rest-- ':database)))) (connection-uri (car (cdr (plist-member --cl-rest-- ':connection-uri)))) (separator (car (cdr (plist-member --cl-rest-- ':separator))))) (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --cl-keys--) '(:classpath :classname :subprotocol :subname :dbtype :dbname :host :port :user :password :database :connection-uri :separator :allow-other-keys)) (setq --cl-keys-- (cdr (cdr --cl-keys--)))) ((car (cdr (memq ':allow-other-keys --cl-rest--))) (setq --cl-keys-- nil)) (t (error "Keyword argument %s not one of (:classpath :classname :subprotocol :subname :dbtype :dbname :host :port :user :password :database :connection-uri :separator)" (car --cl-keys--)))))) (progn (setq ejc-connections (-remove (function (lambda (x) (equal (car x) connection-name))) ejc-connections)) (setq ejc-connections (cons (cons connection-name (make-ejc-db-conn :classpath (file-truename classpath) :classname classname :subprotocol subprotocol :subname subname :dbtype dbtype :dbname dbname :host host :port port :user user :password password :database database :connection-uri connection-uri :separator separator)) ejc-connections)))))
  ejc-create-connection("PostgreSQL" :dbtype "postgresql" :host "localhost" :port "5432" :user "postgres" :password "324324")
  eval((ejc-create-connection "PostgreSQL" :dbtype "postgresql" :host "localhost" :port "5432" :user "postgres" :password "324324") nil)
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  eros-eval-last-sexp(nil)
  funcall-interactively(eros-eval-last-sexp nil)
  call-interactively(eros-eval-last-sexp nil nil)
  command-execute(eros-eval-last-sexp)

Seems the :classpath still is necessary? I thought it is automatically.

@stardiviner
Copy link
Contributor

I add connection with:

(ejc-create-connection
   "PostgreSQL"
   :classpath "~/.m2/repository/postgresql/postgresql/9.3-1102.jdbc41/postgresql-9.3-1102.jdbc41.jar"
   :classname "org.postgresql.Driver"
   :dbtype "postgresql"
   :host "localhost"
   :port "5432"
   :user "postgres"
   :password "324324")
Debugger entered--Lisp error: (error "NullPointerException   clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:26)\n")
  signal(error ("NullPointerException   clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:26)\n"))
  error("NullPointerException   clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:26)\n")
  clomacs-get-result((dict "status" ("eval-error" "done") "id" "26" "ns" "user" "session" "8e85b036-8f76-4a03-bf48-62c9a01b3aa9" "value" "nil" "ex" "class java.util.concurrent.ExecutionException" "root-ex" "class java.lang.NullPointerException" "err" "NullPointerException   clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:26)\n") :value :list ejc-sql\.structure)
  (let ((el-result (clomacs-get-result (nrepl-sync-request:eval request connection) :value ':list 'ejc-sql\.structure))) (if clomacs-restore-print-length (cider-repl-set-config)) el-result)
  (if (equal :sync :async) (nrepl-request:eval request (function (lambda (result) (if nil (let ((el-result (clomacs-get-result result :value ':list 'ejc-sql\.structure))) (if el-result (nil el-result)) (if clomacs-restore-print-length (cider-repl-set-config)))))) connection) (let ((el-result (clomacs-get-result (nrepl-sync-request:eval request connection) :value ':list 'ejc-sql\.structure))) (if clomacs-restore-print-length (cider-repl-set-config)) el-result))
  (let* ((connection (clomacs-get-connection "ejc-sql")) (request (concat (if 'ejc-sql\.structure (format "(require '%s) " '"ejc-sql.structure") "") (format "(do (set! *print-length* %s)\n                              (%s %s))" "100000" '"ejc-sql.structure/get-colomns-candidates" attrs)))) (if (equal :sync :async) (nrepl-request:eval request (function (lambda (result) (if nil (let ((el-result (clomacs-get-result result :value ':list 'ejc-sql\.structure))) (if el-result (nil el-result)) (if clomacs-restore-print-length (cider-repl-set-config)))))) connection) (let ((el-result (clomacs-get-result (nrepl-sync-request:eval request connection) :value ':list 'ejc-sql\.structure))) (if clomacs-restore-print-length (cider-repl-set-config)) el-result)))
  (let* ((attrs "")) (let ((--dolist-tail-- attributes)) (while --dolist-tail-- (let ((a (car --dolist-tail--))) (setq attrs (concat attrs " " (clomacs-format-arg a))) (setq --dolist-tail-- (cdr --dolist-tail--))))) (let* ((connection (clomacs-get-connection "ejc-sql")) (request (concat (if 'ejc-sql\.structure (format "(require '%s) " '"ejc-sql.structure") "") (format "(do (set! *print-length* %s)\n                              (%s %s))" "100000" '"ejc-sql.structure/get-colomns-candidates" attrs)))) (if (equal :sync :async) (nrepl-request:eval request (function (lambda (result) (if nil (let ((el-result (clomacs-get-result result :value ':list 'ejc-sql\.structure))) (if el-result (nil el-result)) (if clomacs-restore-print-length (cider-repl-set-config)))))) connection) (let ((el-result (clomacs-get-result (nrepl-sync-request:eval request connection) :value ':list 'ejc-sql\.structure))) (if clomacs-restore-print-length (cider-repl-set-config)) el-result))))
  ejc-get-colomns-candidates(((:classpath . "/home/stardiviner/.m2/repository/postgresql/postgresql/9.3-1102.jdbc41/postgresql-9.3-1102.jdbc41.jar") (:classname . "org.postgresql.Driver") (:dbtype . "postgresql") (:host . "localhost") (:port . "5432") (:user . "postgres") (:password . "324324")) "SELECT * FROM test;\ns\n" nil nil)
  funcall(ejc-get-colomns-candidates ((:classpath . "/home/stardiviner/.m2/repository/postgresql/postgresql/9.3-1102.jdbc41/postgresql-9.3-1102.jdbc41.jar") (:classname . "org.postgresql.Driver") (:dbtype . "postgresql") (:host . "localhost") (:port . "5432") (:user . "postgres") (:password . "324324")) "SELECT * FROM test;\ns\n" nil nil)
  (let* ((prefix-1 (ejc-get-prefix-word)) (prefix-2 (save-excursion (search-backward "." nil t) (ejc-get-prefix-word))) (result (funcall 'ejc-get-colomns-candidates ejc-db (apply 'buffer-substring (ejc-get-sql-boundaries-at-point)) prefix-1 prefix-2)) (pending (car result)) (candidates-cache (cdr result))) (if (ejc-not-nil-str pending) (message "Receiving database structure...") candidates-cache))
  (if (ejc-buffer-connected-p) (let* ((prefix-1 (ejc-get-prefix-word)) (prefix-2 (save-excursion (search-backward "." nil t) (ejc-get-prefix-word))) (result (funcall 'ejc-get-colomns-candidates ejc-db (apply 'buffer-substring (ejc-get-sql-boundaries-at-point)) prefix-1 prefix-2)) (pending (car result)) (candidates-cache (cdr result))) (if (ejc-not-nil-str pending) (message "Receiving database structure...") candidates-cache)))
  ejc-colomns-candidates()
  ac-candidates-1(((prefix . ac-prefix-default) (candidates . ejc-colomns-candidates) (symbol . "c") (requires . 1) (cache . t)))
  ac-candidates()
  ac-update(nil)
  ac-update-greedy()
  apply(ac-update-greedy nil)
  timer-event-handler([t 0 0 50000 0.05 ac-update-greedy nil idle 0])

Seems return nil. Don't know which request failed. I'm sure I have postgresql.service started correctly, and can connect normally.

@stardiviner
Copy link
Contributor

I found this why.
I have not set :dbname in connection setup.
Here is the diff:

(ejc-create-connection
 "MySQL"
 :classpath "~/.m2/repository/mysql/mysql-connector-java/5.1.32/mysql-connector-java-5.1.32.jar"
 :classname "com.mysql.jdbc.Driver"
 :dbtype "mysql"
 :host "localhost"
 :port "3306"
 :user "root"
 :password "324324"
+ :dbname "test"
  )

And need to make sure the database has at least one table. I think this can be put into README FAQ.

@kostafey
Copy link
Owner Author

kostafey commented Nov 4, 2018

@stardiviner Ok, new clojure/java.jdbc connection structure is in the master. It should works as expected (:classname param is optional, :dbname for new connection structure is required).
For the requirement of a database to have at least one table, please refer this issue: #51

@kostafey kostafey closed this as completed Nov 4, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants