;;======================================================================
;; Copyright 2017, Matthew Welland.
;;
;; This file is part of Megatest.
;;
;; Megatest is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; Megatest is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with Megatest. If not, see <http://www.gnu.org/licenses/>.
;;======================================================================
(declare (unit rmtmod))
(declare (uses commonmod))
(declare (uses ulex))
(module rmtmod
*
(import scheme chicken data-structures extras)
(import (prefix sqlite3 sqlite3:) posix typed-records srfi-18)
(import commonmod)
(import (prefix ulex ulex:))
;; Hack to make these functions visible to the refactored code, goal is to eliminate these over time.
(define (rmt:send-receive . params) #f)
(define (http-transport:close-connections . params) #f)
;; from remote defstruct in common.scm
(define (remote-conndat-set! . params) #f)
(define (remote-server-url-set! . params) #f)
(define (remote-ro-mode . params) #f)
(define (remote-ro-mode-set! . params) #f)
(define (remote-ro-mode-checked-set! . params) #f)
(define (remote-ro-mode-checked . params) #f)
(define (debug:print . params) #f)
(define (debug:print-info . params) #f)
(define (set-functions send-receive rsus
close-connections rcs
dbgp dbgpinfo
ro-mode ro-mode-set
ro-mode-checked-set ro-mode-checked
)
(set! rmt:send-receive send-receive)
(set! remote-server-url-set! rsus)
(set! http-transport:close-connections close-connections)
(set! remote-conndat-set! rcs)
(set! debug:print dbgp)
(set! debug:print-info dbgpinfo)
(set! remote-ro-mode ro-mode)
(set! remote-ro-mode-set! ro-mode-set)
(set! remote-ro-mode-checked-set! ro-mode-checked-set)
(set! remote-ro-mode-checked ro-mode-checked))
;; return the handle struct for sending queries to a specific database
;; - initializes the connection object if this is the first access
;; - finds the "captain" and asks who to talk to for the given dbfname
;; - establishes the connection to the current dbowner
;;
(define (rmt:connect alldat dbfname dbtype)
(let* ((ulexdat (or (alldat-ulexdat alldat)
(rmt:setup-ulex alldat))))
(ulex:connect ulexdat dbfname dbtype)))
;; setup the remote calls
(define (rmt:setup-ulex alldat)
(let* ((udata (ulex:setup))) ;; establish connection to ulex
(alldat-ulexdat-set! alldat udata)
;; register all needed procs
(ulex:register-handler udata 'ping common:get-full-version) ;; override ping with get-full-version
(ulex:register-handler udata 'login common:get-full-version) ;; force setup of the connection
(ulex:register-handler udata 'execute api:execute-requests)
udata))
;; set up a connection to the current owner of the dbfile associated with rid
;; then send the query to that dbfile owner and wait for a response.
;;
(define (rmt:send-receive cmd rid params #!key (attemptnum 1)(area-dat #f)) ;; start attemptnum at 1 so the modulo below works as expected
(let* ((alldat *alldat*)
(areapath (alldat-areapath alldat))
(dbtype (if (or (not rid)(< rid 1)) ;; this is the criteria for "main.db"
"main" "runs"))
(dbfname (if (equal? dbtype "main")
"main.db"
(conc rid ".db")))
(dbfile (conc areapath "/.db/" dbfname))
(ulexconn (rmt:connect alldat dbfname dbtype)) ;; ulexconn is our new *runremote*, it is a dbowner struct < pdat lastrefresh >
(udata (alldat-ulexdat alldat)))
(ulex:remote-request udata ulexconn 'immediate dbfile 'execute rid params)))
;; need to call this on the other side
;; (api:execute-requests dbstruct-local (vector (symbol->string cmd) params))))
#;(with-input-from-string
(ulex:remote-request udata ulexconn 'immediate dbfile 'execute rid (with-output-to-string (lambda ()(serialize params))))
(lambda ()(deserialize)))
)