Я пытаюсь добиться параллельного доступа к MySQL с помощью механизмов Scheme (легкие потоки, насколько я понял).
Моя проблема в том, что я не знаю, как правильно взаимодействовать с C, поэтому не могу позаботиться о результатах из MySQL C API. Это также может быть вопрос об интеграции C и Схемы.
Я выбрал Ypsilon потому, что он быстрый (по крайней мере, быстрее Spark) и R6RS. Выбор другой реализации Схемы уместен только в том случае, если она R6RS и имеет скорость, сравнимую с Ypsilon.
Этот файл связывает C API:
http://code.google.com/p/ypsilon/source/browse/trunk/sitelib/ypsilon/mysql.scm?spec=svn444&r=444
Сверху сделайте его компиляцией, мне пришлось изменить все int8_t на int, unsigned-int на int и т. Д. В моей библиотеке Ypsilon есть много типов C, которые я пропускаю (это все еще последний полный дистрибутив).
Моя книга о Scheme, Язык программирования схем от Dybvig (4-е издание) ничего не говорит об интеграции с Си.
Функция mysql_fetch_row возвращает структуру MYSQL_ROW. На этой странице представлен способ справиться с этим:
(Google для) с фиксированной точкой mysql-client-in-ypsilon.html
Я не могу скомпилировать это. Нужно проверить почему.
Используется:
make-bytevector-mapping = Обеспечивает прозрачный доступ к произвольному блоку памяти
В своем FFI Ypsilon имеет функцию define-c-struct-type:
http://www.littlewing.co.jp/ypsilon/doc-draft/libref.ypsilon.c-types.html#define-c-struct-methods
Я еще не пробовал это. Я вернусь с дополнительной информацией. Если кому-то это удалось, пожалуйста, дайте мне знать.
С уважением
Олле
Пока мой код:
(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)))
Будет выведено:
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