]> gitweb.factorcode.org Git - factor.git/blob - extra/db/mysql/mysql.factor
db.mysql: Add low-level MySQL support
[factor.git] / extra / db / mysql / mysql.factor
1 ! Copyright (C) 2008 Doug Coleman, 2021 Giftpflanze.
2 ! See http://factorcode.org/license.txt for license.
3 USING: accessors alien.c-types alien.data arrays byte-arrays
4 combinators db db.mysql.ffi db.private destructors
5 io.encodings.string io.encodings.utf8 kernel math namespaces
6 sequences specialized-arrays ;
7 IN: db.mysql
8
9 SPECIALIZED-ARRAYS: char ulong void* ;
10
11 TUPLE: mysql-db host user password db port ;
12 TUPLE: mysql-db-connection < db-connection ;
13 TUPLE: mysql-statement < statement ;
14 TUPLE: mysql-result-set < result-set
15     #columns has-more? pointers lengths ;
16
17 : <mysql-db> ( -- mysql-db )
18     mysql-db new ;
19
20 M: mysql-db db-open ( db -- conn )
21     f mysql_init
22     dup [ "Not enough memory to allocate mysql handle." throw ]
23     unless
24     dup 20 1 int <ref> mysql_options drop ! MYSQL_OPT_RECONNECT
25     dup rot {
26         [ host>> ]
27         [ user>> ]
28         [ password>> ]
29         [ db>> ]
30         [ port>> 0 or ]
31     } cleave f 0 mysql_real_connect
32     [ mysql_error throw ] unless
33     mysql-db-connection new-db-connection swap >>handle ;
34
35 M: mysql-db-connection db-close ( h -- )
36     mysql_close ;
37
38 M: mysql-db-connection parse-db-error ;
39
40 M: mysql-db-connection <simple-statement> ( str in out -- stmt )
41     mysql-statement new-statement ;
42
43 M: mysql-db-connection <prepared-statement> <simple-statement> ;
44
45 M: mysql-statement dispose drop ;
46
47 M: mysql-statement query-results ( stmt -- rs )
48     db-connection get handle>> dup pick sql>> mysql_query
49     zero? [ mysql_error throw ] unless dup mysql_use_result
50     dup [
51         nip dup mysql_num_fields
52         [ mysql-result-set new-result-set ] dip
53         >>#columns dup advance-row
54     ] [
55         swap dup mysql_field_count
56         zero? [ drop ] [ mysql_error throw ] if
57         mysql-result-set new-result-set
58     ] if ;
59
60 M: mysql-result-set #columns ( rs -- #c )
61     #columns>> ;
62
63 M: mysql-result-set advance-row ( rs -- )
64     dup handle>> dup mysql_fetch_row
65     [
66         swap mysql_fetch_lengths pick #columns>>
67         [ <direct-void*-array> >>pointers ]
68         [ <direct-ulong-array> >>lengths ] bi-curry bi*
69         t >>has-more?
70     ] [
71         db-connection get handle>> dup mysql_errno zero?
72         [ 2drop f >>has-more? f >>pointers f >>lengths ]
73         [ mysql_error throw ] if
74     ] if* drop ;
75
76 M: mysql-result-set dispose ( d -- )
77     [ mysql_free_result f ] change-handle drop ;
78
79 M: mysql-result-set more-rows? ( rs -- ? )
80     has-more?>> ;
81
82 M: mysql-result-set row-column ( rs i -- str )
83     swap [ pointers>> ] [ lengths>> ] bi
84     [ nth ] bi-curry@ bi <direct-char-array>
85     >byte-array utf8 decode ;