I'm trying to achieve parallell MySQL access with Scheme engines (light threads, as I've come to understand it).
My problem is, I don't know how to interact with C properly, thus can't take care of the results from the MySQL C API. This could also be a question about integrating C and Scheme.
My choice of Ypsilon is because it's fast (faster than Spark at least) and R6RS. Choosing another Scheme implementation is only relevant if it's R6RS and has speed comparable to Ypsilon.
This file bind the C API:
http://code.google.com/p/ypsilon/source/browse/trunk/sitelib/ypsilon/mysql.scm?spec=svn444&r=444
Top make it compile, I had to change all int8_t to int, unsigned-int to int, etc. There's a lot of C types I miss in my Ypsilon library, that is (it's the latest complete distribution, still).
My book about Scheme, The Scheme Programming Language by Dybvig (4:th edition) sais nothing about C integration.
The function mysql_fetch_row returns a MYSQL_ROW struct. This page present a way to handle this:
(google for) fixedpoint mysql-client-in-ypsilon.html
I cannot compile this. Have to check why.
This is used:
make-bytevector-mapping = Provides transparent access to an arbitrary memory block
In its FFI, Ypsilon has a function called define-c-struct-type:
http://www.littlewing.co.jp/ypsilon/doc-draft/libref.ypsilon.c-types.html#define-c-struct-methods
I haven't tried that yet. I'll be back with more information. If anyone has succeeded with something like this, please let me know.
Regards Olle
My code so far:
(import (core)
(ypsilon ffi)
(ypsilon c-types)
(ypsilon mysql))
(define NULL 0)
(define host "localhost")
(define user "root")
(define passwd "bla")
(define database "bla")
(define mysql)
(define query "select bla from bla")
(begin
(set! mysql (mysql_init #f))
(mysql_real_connect mysql host user passwd database 0 #f 0)
(display (mysql_stat mysql))
(newline)
(display (string-append "mysql_query:\t" (number->string (mysql_query mysql query))))
(newline)
(let ([result (mysql_store_result mysql)])
(let rec ([n (mysql_num_fields result)] [row (mysql_fetch_row result)] [lengths (mysql_fetch_lengths result)])
(display (string-append "num_fields:\t" (number->string n)))
(newline)
(display (string-append "lengths:\t" (number->string lengths)))
(newline)
(display (string-append "row:\t\t" (number->string row)))
(newline)
(if (= row (- 0 1))
""
(let ([row (make-bytevector-mapping row (bytevector-c-int-ref (make-bytevector-mapping lengths sizeof:int)) (* 10 sizeof:int))])
(display (utf8->string row))
(newline)
(newline)
(newline)
(rec n (- lengths 1) (mysql_fetch_row result))
)))
(newline)))
This will output:
Uptime: 1203 Threads: 1 Questions: 204 Slow queries: 0 Opens: 569 Flush tables: 1 Open tables: 64 Queries per second avg: 0.169
mysql_query: 0
num_fields: 1
lengths: 8525640
row: 8541880
error in bytevector-c-int-ref: expected 2, but 1 argument given
irritants:
(#<bytevector-mapping 0x821748 4>)
backtrace:
0 (bytevector-c-int-ref (make-bytevector-mapping lengths sizeof:int))
..."/home/olle/scheme/div.scm" line 54
1 (rec n (- lengths 1) (mysql_fetch_row result))
..."/home/olle/scheme/div.scm" line 63
2 (let rec ((n (mysql_num_fields result)) (row (mysql_fetch_row result)) (lengths ...) ...) ...)
..."/home/olle/scheme/div.scm" line 37