├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── const.sc ├── ffi.sc ├── ftype.sc ├── mysql.h ├── mysql.sc ├── package.sc └── test └── test.sc /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sc linguist-language=Scheme 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.sc~ 2 | *.sc#* 3 | .#*.sc 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mysql 2 | 3 | mySQL binding for Chez Scheme 4 | 5 | 6 | OSX: 7 | ``` 8 | $ brew install mysql-client 9 | $ sudo ln -s /usr/local/opt/mysql-client/lib/libmysqlclient.dylib /usr/local/lib/libmysqlclient.dylib 10 | ``` 11 | 12 | 13 | 1. define mysql database set 14 | 15 | ``` 16 | (define conn (connect 17 | `((hostname . "IP") 18 | (user . "root") 19 | (password . "Password") 20 | (database . "DatabaseName")))) 21 | ``` 22 | 23 | 2. execute query 24 | 25 | `(query conn "SELECT * FROM TableName")` 26 | 27 | => 28 | 29 | ``` 30 | #( 31 | ((variable . diagnostics.allow_i_s_tables) (value . OFF) 32 | (set_time . #) (set_by . null)) 33 | ((variable . diagnostics.include_raw) (value . OFF) 34 | (set_time . #) (set_by . null)) 35 | ((variable . ps_thread_trx_info.max_length) (value . 65535) 36 | (set_time . #) (set_by . null)) 37 | ((variable . statement_performance_analyzer.limit) (value . 100) 38 | (set_time . #) (set_by . null)) 39 | ((variable . statement_performance_analyzer.view) (value . null) 40 | (set_time . #) (set_by . null)) 41 | ((variable . statement_truncate_len) (value . 64) 42 | (set_time . #) (set_by . null)) 43 | ) 44 | ``` 45 | 46 | you can use json library to convert this vector to json string 47 | 48 | 49 | -------------------------------------------------------------------------------- /const.sc: -------------------------------------------------------------------------------- 1 | (library (mysql const) 2 | (export 3 | mysql-stmt-init-done 4 | mysql-stmt-prepare-done 5 | mysql-stmt-execute-done 6 | mysql-stmt-fetch-done 7 | ) 8 | (import (scheme)) 9 | 10 | (define mysql-stmt-init-done 1) 11 | (define mysql-stmt-prepare-done 2) 12 | (define mysql-stmt-execute-done 3) 13 | (define mysql-stmt-fetch-done 4) 14 | ) -------------------------------------------------------------------------------- /ffi.sc: -------------------------------------------------------------------------------- 1 | (library (mysql ffi) 2 | (export 3 | mysql-lib-load 4 | mysql-init 5 | mysql-real-connect 6 | mysql-query 7 | mysql-store-result 8 | mysql-use-result 9 | mysql-fetch-field 10 | mysql-field-seek 11 | mysql-fetch-row 12 | mysql-free-result 13 | mysql-num-rows 14 | mysql-num-fields 15 | mysql-errno 16 | mysql-error 17 | mysql-get-client-info 18 | mysql-close 19 | ) 20 | (import 21 | (scheme) 22 | (mysql const) 23 | (mysql ftype) 24 | ) 25 | 26 | (define lib-name 27 | (case (machine-type) 28 | ((i3nt ti3nt a6nt ta6nt) "C:\\Program Files\\MySQL\\MySQL Connector C 6.1\\lib\\libmysql.dll") 29 | ((a6osx i3osx ta6osx ti3osx) "libmysqlclient.dylib") 30 | ((a6le i3le ta6le ti3le) "libmysqlclient.so") 31 | (else "libmysqlclient.so"))) 32 | 33 | (define mysql-lib-load 34 | (lambda (path) 35 | (load-shared-object path))) 36 | 37 | (define init (mysql-lib-load lib-name)) 38 | 39 | (define-syntax define-procedure 40 | (syntax-rules () 41 | ((_ name sym args rst) 42 | (define name 43 | (if (foreign-entry? sym) 44 | (foreign-procedure sym args rst) 45 | (lambda x (printf "error: ~a not found in ~a\n" sym lib-name))))))) 46 | 47 | (define-procedure mysql-init "mysql_init" ((* mysql)) (* mysql)) 48 | 49 | (define-procedure mysql-real-connect "mysql_real_connect" ((* mysql) string string string string unsigned-int string unsigned-long) (* mysql)) 50 | 51 | (define-procedure mysql-query "mysql_query" ((* mysql) string) int) 52 | 53 | (define-procedure mysql-store-result "mysql_store_result" ((* mysql)) (* mysql-res)) 54 | 55 | (define-procedure mysql-use-result "mysql_use_result" ((* mysql)) (* mysql-res)) 56 | 57 | (define-procedure mysql-fetch-field "mysql_fetch_field" ((* mysql-res)) (* mysql-field)) 58 | 59 | (define-procedure mysql-field-seek "mysql_field_seek" ((* mysql-res) unsigned-int) unsigned-int) 60 | 61 | (define-procedure mysql-fetch-row "mysql_fetch_row" ((* mysql-res)) (* mysql-row)) 62 | 63 | (define-procedure mysql-free-result "mysql_free_result" ((* mysql-res)) void) 64 | 65 | (define-procedure mysql-num-rows "mysql_num_rows" ((* mysql-res)) unsigned-long-long) 66 | 67 | (define-procedure mysql-num-fields "mysql_num_fields" ((* mysql-res)) unsigned-int) 68 | 69 | (define-procedure mysql-errno "mysql_errno" ((* mysql)) unsigned-int) 70 | 71 | (define-procedure mysql-error "mysql_error" ((* mysql)) string) 72 | 73 | (define-procedure mysql-get-client-info "mysql_get_client_info" () string) 74 | 75 | (define-procedure mysql-close "mysql_close" ((* mysql)) void) 76 | ) 77 | -------------------------------------------------------------------------------- /ftype.sc: -------------------------------------------------------------------------------- 1 | (library (mysql ftype) 2 | (export 3 | mysql-field 4 | mysql-row 5 | mysql-field-offset 6 | mysql-rows 7 | mysql-row-offset 8 | mysql 9 | mysql-res 10 | mysql-parameters 11 | ) 12 | (import (scheme)) 13 | 14 | (define-ftype mysql-field 15 | (struct 16 | (name (* char)) ; Name of column 17 | (org_name (* char)) ; Original column name, if an alias 18 | (table (* char)) ; Org table name, if table was an alias 19 | (org-table (* char)) ; Database for table 20 | (db (* char)) ; Catalog for table 21 | (catalog (* char)) ; Default value (set by mysql_list_fields) 22 | (def (* char)) ; Width of column (create length) 23 | (length unsigned-long) ; Max width for selected set 24 | (max-length unsigned-long) 25 | (name-length unsigned-int) 26 | (org-name-length unsigned-int) 27 | (table-length unsigned-int) 28 | (org-table-length unsigned-int) 29 | (db-length unsigned-int) 30 | (catalog-length unsigned-int) 31 | (def-length unsigned-int) 32 | (flags unsigned-int) ; Div flags 33 | (decimals unsigned-int) ; Number of decimals in field 34 | (charsetnr unsigned-int) ; Character set 35 | (type unsigned-8) ; Type of field. See mysql_com.h for types 36 | (extension void*))) 37 | 38 | (define-ftype mysql-row (* char)) ; return data as array of strings 39 | 40 | (define-ftype mysql-field-offset unsigned-int) ; offset to current field 41 | 42 | (define-ftype mysql-rows 43 | (struct 44 | (next (* mysql-rows)) 45 | (data (* mysql-row)) 46 | (length unsigned-long))) 47 | 48 | (define-ftype mysql-row-offset (* mysql-rows)) 49 | 50 | (define-ftype mysql (struct)) 51 | 52 | (define-ftype mysql-res (struct)) 53 | 54 | (define-ftype mysql-parameters 55 | (struct 56 | (p-max-allowed-packet (* unsigned-long)) 57 | (p-net-bufffer-length (* unsigned-long)) 58 | (extension void*))) 59 | ) 60 | -------------------------------------------------------------------------------- /mysql.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 2 | 3 | This program is free software; you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation; version 2 of the License. 6 | 7 | This program is distributed in the hope that it will be useful, 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | GNU General Public License for more details. 11 | 12 | You should have received a copy of the GNU General Public License 13 | along with this program; if not, write to the Free Software 14 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 15 | 16 | /* 17 | This file defines the client API to MySQL and also the ABI of the 18 | dynamically linked libmysqlclient. 19 | 20 | The ABI should never be changed in a released product of MySQL, 21 | thus you need to take great care when changing the file. In case 22 | the file is changed so the ABI is broken, you must also update 23 | the SHARED_LIB_MAJOR_VERSION in cmake/mysql_version.cmake 24 | */ 25 | 26 | #ifndef _mysql_h 27 | #define _mysql_h 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | #ifndef MY_GLOBAL_INCLUDED /* If not standard header */ 34 | #ifndef MYSQL_ABI_CHECK 35 | #include 36 | #endif 37 | typedef char my_bool; 38 | #if !defined(_WIN32) 39 | #define STDCALL 40 | #else 41 | #define STDCALL __stdcall 42 | #endif 43 | 44 | #ifndef my_socket_defined 45 | #ifdef _WIN32 46 | #include 47 | #ifdef WIN32_LEAN_AND_MEAN 48 | #include 49 | #endif 50 | #define my_socket SOCKET 51 | #else 52 | typedef int my_socket; 53 | #endif /* _WIN32 */ 54 | #endif /* my_socket_defined */ 55 | #endif /* MY_GLOBAL_INCLUDED */ 56 | 57 | #include "mysql_version.h" 58 | #include "mysql_com.h" 59 | #include "mysql_time.h" 60 | 61 | #include "my_list.h" /* for LISTs used in 'MYSQL' and 'MYSQL_STMT' */ 62 | 63 | /* Include declarations of plug-in API */ 64 | #include "mysql/client_plugin.h" 65 | 66 | /* 67 | Declare my_init() here because it is a documented C API function exported 68 | from the client library. No need to include whole my_sys.h, however. 69 | */ 70 | 71 | my_bool my_init(void); 72 | 73 | extern unsigned int mysql_port; 74 | extern char *mysql_unix_port; 75 | 76 | #define CLIENT_NET_READ_TIMEOUT 365*24*3600 /* Timeout on read */ 77 | #define CLIENT_NET_WRITE_TIMEOUT 365*24*3600 /* Timeout on write */ 78 | 79 | #define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG) 80 | #define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG) 81 | #define IS_BLOB(n) ((n) & BLOB_FLAG) 82 | /** 83 | Returns true if the value is a number which does not need quotes for 84 | the sql_lex.cc parser to parse correctly. 85 | */ 86 | #define IS_NUM(t) (((t) <= MYSQL_TYPE_INT24 && (t) != MYSQL_TYPE_TIMESTAMP) || (t) == MYSQL_TYPE_YEAR || (t) == MYSQL_TYPE_NEWDECIMAL) 87 | #define IS_LONGDATA(t) ((t) >= MYSQL_TYPE_TINY_BLOB && (t) <= MYSQL_TYPE_STRING) 88 | 89 | 90 | typedef struct st_mysql_field { 91 | char *name; /* Name of column */ 92 | char *org_name; /* Original column name, if an alias */ 93 | char *table; /* Table of column if column was a field */ 94 | char *org_table; /* Org table name, if table was an alias */ 95 | char *db; /* Database for table */ 96 | char *catalog; /* Catalog for table */ 97 | char *def; /* Default value (set by mysql_list_fields) */ 98 | unsigned long length; /* Width of column (create length) */ 99 | unsigned long max_length; /* Max width for selected set */ 100 | unsigned int name_length; 101 | unsigned int org_name_length; 102 | unsigned int table_length; 103 | unsigned int org_table_length; 104 | unsigned int db_length; 105 | unsigned int catalog_length; 106 | unsigned int def_length; 107 | unsigned int flags; /* Div flags */ 108 | unsigned int decimals; /* Number of decimals in field */ 109 | unsigned int charsetnr; /* Character set */ 110 | enum enum_field_types type; /* Type of field. See mysql_com.h for types */ 111 | void *extension; 112 | } MYSQL_FIELD; 113 | 114 | typedef char **MYSQL_ROW; /* return data as array of strings */ 115 | typedef unsigned int MYSQL_FIELD_OFFSET; /* offset to current field */ 116 | 117 | #ifndef MY_GLOBAL_INCLUDED 118 | #if defined (_WIN32) 119 | typedef unsigned __int64 my_ulonglong; 120 | #else 121 | typedef unsigned long long my_ulonglong; 122 | #endif 123 | #endif 124 | 125 | #include "typelib.h" 126 | 127 | #define MYSQL_COUNT_ERROR (~(my_ulonglong) 0) 128 | 129 | /* backward compatibility define - to be removed eventually */ 130 | #define ER_WARN_DATA_TRUNCATED WARN_DATA_TRUNCATED 131 | 132 | typedef struct st_mysql_rows { 133 | struct st_mysql_rows *next; /* list of rows */ 134 | MYSQL_ROW data; 135 | unsigned long length; 136 | } MYSQL_ROWS; 137 | 138 | typedef MYSQL_ROWS *MYSQL_ROW_OFFSET; /* offset to current row */ 139 | 140 | #include "my_alloc.h" 141 | 142 | typedef struct embedded_query_result EMBEDDED_QUERY_RESULT; 143 | typedef struct st_mysql_data { 144 | MYSQL_ROWS *data; 145 | struct embedded_query_result *embedded_info; 146 | MEM_ROOT alloc; 147 | my_ulonglong rows; 148 | unsigned int fields; 149 | /* extra info for embedded library */ 150 | void *extension; 151 | } MYSQL_DATA; 152 | 153 | enum mysql_option 154 | { 155 | MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE, 156 | MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP, 157 | MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE, 158 | MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT, 159 | MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT, 160 | MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION, 161 | MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH, 162 | MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, 163 | MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH, 164 | MYSQL_OPT_BIND, 165 | MYSQL_OPT_SSL_KEY, MYSQL_OPT_SSL_CERT, 166 | MYSQL_OPT_SSL_CA, MYSQL_OPT_SSL_CAPATH, MYSQL_OPT_SSL_CIPHER, 167 | MYSQL_OPT_SSL_CRL, MYSQL_OPT_SSL_CRLPATH, 168 | MYSQL_OPT_CONNECT_ATTR_RESET, MYSQL_OPT_CONNECT_ATTR_ADD, 169 | MYSQL_OPT_CONNECT_ATTR_DELETE, 170 | MYSQL_SERVER_PUBLIC_KEY, 171 | MYSQL_ENABLE_CLEARTEXT_PLUGIN, 172 | MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, 173 | MYSQL_OPT_SSL_ENFORCE, 174 | MYSQL_OPT_MAX_ALLOWED_PACKET, MYSQL_OPT_NET_BUFFER_LENGTH, 175 | MYSQL_OPT_TLS_VERSION, 176 | MYSQL_OPT_SSL_MODE 177 | }; 178 | 179 | /** 180 | @todo remove the "extension", move st_mysql_options completely 181 | out of mysql.h 182 | */ 183 | struct st_mysql_options_extention; 184 | 185 | struct st_mysql_options { 186 | unsigned int connect_timeout, read_timeout, write_timeout; 187 | unsigned int port, protocol; 188 | unsigned long client_flag; 189 | char *host,*user,*password,*unix_socket,*db; 190 | struct st_dynamic_array *init_commands; 191 | char *my_cnf_file,*my_cnf_group, *charset_dir, *charset_name; 192 | char *ssl_key; /* PEM key file */ 193 | char *ssl_cert; /* PEM cert file */ 194 | char *ssl_ca; /* PEM CA file */ 195 | char *ssl_capath; /* PEM directory of CA-s? */ 196 | char *ssl_cipher; /* cipher to use */ 197 | char *shared_memory_base_name; 198 | unsigned long max_allowed_packet; 199 | my_bool use_ssl; /* Deprecated ! Former use_ssl */ 200 | my_bool compress,named_pipe; 201 | my_bool unused1; 202 | my_bool unused2; 203 | my_bool unused3; 204 | my_bool unused4; 205 | enum mysql_option methods_to_use; 206 | union { 207 | /* 208 | The ip/hostname to use when authenticating 209 | client against embedded server built with 210 | grant tables - only used in embedded server 211 | */ 212 | char *client_ip; 213 | 214 | /* 215 | The local address to bind when connecting to 216 | remote server - not used in embedded server 217 | */ 218 | char *bind_address; 219 | } ci; 220 | my_bool unused5; 221 | /* 0 - never report, 1 - always report (default) */ 222 | my_bool report_data_truncation; 223 | 224 | /* function pointers for local infile support */ 225 | int (*local_infile_init)(void **, const char *, void *); 226 | int (*local_infile_read)(void *, char *, unsigned int); 227 | void (*local_infile_end)(void *); 228 | int (*local_infile_error)(void *, char *, unsigned int); 229 | void *local_infile_userdata; 230 | struct st_mysql_options_extention *extension; 231 | }; 232 | 233 | enum mysql_status 234 | { 235 | MYSQL_STATUS_READY, MYSQL_STATUS_GET_RESULT, MYSQL_STATUS_USE_RESULT, 236 | MYSQL_STATUS_STATEMENT_GET_RESULT 237 | }; 238 | 239 | enum mysql_protocol_type 240 | { 241 | MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET, 242 | MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY 243 | }; 244 | 245 | enum mysql_ssl_mode 246 | { 247 | SSL_MODE_DISABLED= 1, SSL_MODE_PREFERRED, SSL_MODE_REQUIRED, 248 | SSL_MODE_VERIFY_CA, SSL_MODE_VERIFY_IDENTITY 249 | }; 250 | 251 | typedef struct character_set 252 | { 253 | unsigned int number; /* character set number */ 254 | unsigned int state; /* character set state */ 255 | const char *csname; /* collation name */ 256 | const char *name; /* character set name */ 257 | const char *comment; /* comment */ 258 | const char *dir; /* character set directory */ 259 | unsigned int mbminlen; /* min. length for multibyte strings */ 260 | unsigned int mbmaxlen; /* max. length for multibyte strings */ 261 | } MY_CHARSET_INFO; 262 | 263 | struct st_mysql_methods; 264 | struct st_mysql_stmt; 265 | 266 | typedef struct st_mysql 267 | { 268 | NET net; /* Communication parameters */ 269 | unsigned char *connector_fd; /* ConnectorFd for SSL */ 270 | char *host,*user,*passwd,*unix_socket,*server_version,*host_info; 271 | char *info, *db; 272 | struct charset_info_st *charset; 273 | MYSQL_FIELD *fields; 274 | MEM_ROOT field_alloc; 275 | my_ulonglong affected_rows; 276 | my_ulonglong insert_id; /* id if insert on table with NEXTNR */ 277 | my_ulonglong extra_info; /* Not used */ 278 | unsigned long thread_id; /* Id for connection in server */ 279 | unsigned long packet_length; 280 | unsigned int port; 281 | unsigned long client_flag,server_capabilities; 282 | unsigned int protocol_version; 283 | unsigned int field_count; 284 | unsigned int server_status; 285 | unsigned int server_language; 286 | unsigned int warning_count; 287 | struct st_mysql_options options; 288 | enum mysql_status status; 289 | my_bool free_me; /* If free in mysql_close */ 290 | my_bool reconnect; /* set to 1 if automatic reconnect */ 291 | 292 | /* session-wide random string */ 293 | char scramble[SCRAMBLE_LENGTH+1]; 294 | my_bool unused1; 295 | void *unused2, *unused3, *unused4, *unused5; 296 | 297 | LIST *stmts; /* list of all statements */ 298 | const struct st_mysql_methods *methods; 299 | void *thd; 300 | /* 301 | Points to boolean flag in MYSQL_RES or MYSQL_STMT. We set this flag 302 | from mysql_stmt_close if close had to cancel result set of this object. 303 | */ 304 | my_bool *unbuffered_fetch_owner; 305 | /* needed for embedded server - no net buffer to store the 'info' */ 306 | char *info_buffer; 307 | void *extension; 308 | } MYSQL; 309 | 310 | 311 | typedef struct st_mysql_res { 312 | my_ulonglong row_count; 313 | MYSQL_FIELD *fields; 314 | MYSQL_DATA *data; 315 | MYSQL_ROWS *data_cursor; 316 | unsigned long *lengths; /* column lengths of current row */ 317 | MYSQL *handle; /* for unbuffered reads */ 318 | const struct st_mysql_methods *methods; 319 | MYSQL_ROW row; /* If unbuffered read */ 320 | MYSQL_ROW current_row; /* buffer to current row */ 321 | MEM_ROOT field_alloc; 322 | unsigned int field_count, current_field; 323 | my_bool eof; /* Used by mysql_fetch_row */ 324 | /* mysql_stmt_close() had to cancel this result */ 325 | my_bool unbuffered_fetch_cancelled; 326 | void *extension; 327 | } MYSQL_RES; 328 | 329 | 330 | #if !defined(MYSQL_SERVER) && !defined(MYSQL_CLIENT) 331 | #define MYSQL_CLIENT 332 | #endif 333 | 334 | /* 335 | Note: MYSQL_PARAMETERS and mysql_get_parameters() have been removed 336 | in server 5.7. But we keep them here to not break compatibility in 337 | Con/C 6.1 series. 338 | */ 339 | 340 | typedef struct st_mysql_parameters 341 | { 342 | unsigned long *p_max_allowed_packet; 343 | unsigned long *p_net_buffer_length; 344 | void *extension; 345 | } MYSQL_PARAMETERS; 346 | 347 | #if !defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) 348 | #define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet) 349 | #define net_buffer_length (*mysql_get_parameters()->p_net_buffer_length) 350 | #endif 351 | 352 | MYSQL_PARAMETERS *STDCALL mysql_get_parameters(void); 353 | 354 | /* 355 | Set up and bring down the server; to ensure that applications will 356 | work when linked against either the standard client library or the 357 | embedded server library, these functions should be called. 358 | */ 359 | int STDCALL mysql_server_init(int argc, char **argv, char **groups); 360 | void STDCALL mysql_server_end(void); 361 | 362 | /* 363 | mysql_server_init/end need to be called when using libmysqld or 364 | libmysqlclient (exactly, mysql_server_init() is called by mysql_init() so 365 | you don't need to call it explicitely; but you need to call 366 | mysql_server_end() to free memory). The names are a bit misleading 367 | (mysql_SERVER* to be used when using libmysqlCLIENT). So we add more general 368 | names which suit well whether you're using libmysqld or libmysqlclient. We 369 | intend to promote these aliases over the mysql_server* ones. 370 | */ 371 | #define mysql_library_init mysql_server_init 372 | #define mysql_library_end mysql_server_end 373 | 374 | 375 | /* 376 | Set up and bring down a thread; these function should be called 377 | for each thread in an application which opens at least one MySQL 378 | connection. All uses of the connection(s) should be between these 379 | function calls. 380 | */ 381 | my_bool STDCALL mysql_thread_init(void); 382 | void STDCALL mysql_thread_end(void); 383 | 384 | /* 385 | Functions to get information from the MYSQL and MYSQL_RES structures 386 | Should definitely be used if one uses shared libraries. 387 | */ 388 | 389 | my_ulonglong STDCALL mysql_num_rows(MYSQL_RES *res); 390 | unsigned int STDCALL mysql_num_fields(MYSQL_RES *res); 391 | my_bool STDCALL mysql_eof(MYSQL_RES *res); 392 | MYSQL_FIELD *STDCALL mysql_fetch_field_direct(MYSQL_RES *res, 393 | unsigned int fieldnr); 394 | MYSQL_FIELD * STDCALL mysql_fetch_fields(MYSQL_RES *res); 395 | MYSQL_ROW_OFFSET STDCALL mysql_row_tell(MYSQL_RES *res); 396 | MYSQL_FIELD_OFFSET STDCALL mysql_field_tell(MYSQL_RES *res); 397 | 398 | unsigned int STDCALL mysql_field_count(MYSQL *mysql); 399 | my_ulonglong STDCALL mysql_affected_rows(MYSQL *mysql); 400 | my_ulonglong STDCALL mysql_insert_id(MYSQL *mysql); 401 | unsigned int STDCALL mysql_errno(MYSQL *mysql); 402 | const char * STDCALL mysql_error(MYSQL *mysql); 403 | const char *STDCALL mysql_sqlstate(MYSQL *mysql); 404 | unsigned int STDCALL mysql_warning_count(MYSQL *mysql); 405 | const char * STDCALL mysql_info(MYSQL *mysql); 406 | unsigned long STDCALL mysql_thread_id(MYSQL *mysql); 407 | const char * STDCALL mysql_character_set_name(MYSQL *mysql); 408 | int STDCALL mysql_set_character_set(MYSQL *mysql, const char *csname); 409 | 410 | MYSQL * STDCALL mysql_init(MYSQL *mysql); 411 | my_bool STDCALL mysql_ssl_set(MYSQL *mysql, const char *key, 412 | const char *cert, const char *ca, 413 | const char *capath, const char *cipher); 414 | const char * STDCALL mysql_get_ssl_cipher(MYSQL *mysql); 415 | my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, 416 | const char *passwd, const char *db); 417 | MYSQL * STDCALL mysql_real_connect(MYSQL *mysql, const char *host, 418 | const char *user, 419 | const char *passwd, 420 | const char *db, 421 | unsigned int port, 422 | const char *unix_socket, 423 | unsigned long clientflag); 424 | int STDCALL mysql_select_db(MYSQL *mysql, const char *db); 425 | int STDCALL mysql_query(MYSQL *mysql, const char *q); 426 | int STDCALL mysql_send_query(MYSQL *mysql, const char *q, 427 | unsigned long length); 428 | int STDCALL mysql_real_query(MYSQL *mysql, const char *q, 429 | unsigned long length); 430 | MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql); 431 | MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql); 432 | 433 | void STDCALL mysql_get_character_set_info(MYSQL *mysql, 434 | MY_CHARSET_INFO *charset); 435 | 436 | int STDCALL mysql_session_track_get_first(MYSQL *mysql, 437 | enum enum_session_state_type type, 438 | const char **data, 439 | size_t *length); 440 | int STDCALL mysql_session_track_get_next(MYSQL *mysql, 441 | enum enum_session_state_type type, 442 | const char **data, 443 | size_t *length); 444 | /* local infile support */ 445 | 446 | #define LOCAL_INFILE_ERROR_LEN 512 447 | 448 | void 449 | mysql_set_local_infile_handler(MYSQL *mysql, 450 | int (*local_infile_init)(void **, const char *, 451 | void *), 452 | int (*local_infile_read)(void *, char *, 453 | unsigned int), 454 | void (*local_infile_end)(void *), 455 | int (*local_infile_error)(void *, char*, 456 | unsigned int), 457 | void *); 458 | 459 | void 460 | mysql_set_local_infile_default(MYSQL *mysql); 461 | 462 | int STDCALL mysql_shutdown(MYSQL *mysql, 463 | enum mysql_enum_shutdown_level 464 | shutdown_level); 465 | int STDCALL mysql_dump_debug_info(MYSQL *mysql); 466 | int STDCALL mysql_refresh(MYSQL *mysql, 467 | unsigned int refresh_options); 468 | int STDCALL mysql_kill(MYSQL *mysql,unsigned long pid); 469 | int STDCALL mysql_set_server_option(MYSQL *mysql, 470 | enum enum_mysql_set_option 471 | option); 472 | int STDCALL mysql_ping(MYSQL *mysql); 473 | const char * STDCALL mysql_stat(MYSQL *mysql); 474 | const char * STDCALL mysql_get_server_info(MYSQL *mysql); 475 | const char * STDCALL mysql_get_client_info(void); 476 | unsigned long STDCALL mysql_get_client_version(void); 477 | const char * STDCALL mysql_get_host_info(MYSQL *mysql); 478 | unsigned long STDCALL mysql_get_server_version(MYSQL *mysql); 479 | unsigned int STDCALL mysql_get_proto_info(MYSQL *mysql); 480 | MYSQL_RES * STDCALL mysql_list_dbs(MYSQL *mysql,const char *wild); 481 | MYSQL_RES * STDCALL mysql_list_tables(MYSQL *mysql,const char *wild); 482 | MYSQL_RES * STDCALL mysql_list_processes(MYSQL *mysql); 483 | int STDCALL mysql_options(MYSQL *mysql,enum mysql_option option, 484 | const void *arg); 485 | int STDCALL mysql_options4(MYSQL *mysql,enum mysql_option option, 486 | const void *arg1, const void *arg2); 487 | int STDCALL mysql_get_option(MYSQL *mysql, enum mysql_option option, 488 | const void *arg); 489 | void STDCALL mysql_free_result(MYSQL_RES *result); 490 | void STDCALL mysql_data_seek(MYSQL_RES *result, 491 | my_ulonglong offset); 492 | MYSQL_ROW_OFFSET STDCALL mysql_row_seek(MYSQL_RES *result, 493 | MYSQL_ROW_OFFSET offset); 494 | MYSQL_FIELD_OFFSET STDCALL mysql_field_seek(MYSQL_RES *result, 495 | MYSQL_FIELD_OFFSET offset); 496 | MYSQL_ROW STDCALL mysql_fetch_row(MYSQL_RES *result); 497 | unsigned long * STDCALL mysql_fetch_lengths(MYSQL_RES *result); 498 | MYSQL_FIELD * STDCALL mysql_fetch_field(MYSQL_RES *result); 499 | MYSQL_RES * STDCALL mysql_list_fields(MYSQL *mysql, const char *table, 500 | const char *wild); 501 | unsigned long STDCALL mysql_escape_string(char *to,const char *from, 502 | unsigned long from_length); 503 | unsigned long STDCALL mysql_hex_string(char *to,const char *from, 504 | unsigned long from_length); 505 | unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql, 506 | char *to,const char *from, 507 | unsigned long length); 508 | unsigned long STDCALL mysql_real_escape_string_quote(MYSQL *mysql, 509 | char *to, const char *from, 510 | unsigned long length, char quote); 511 | void STDCALL mysql_debug(const char *debug); 512 | void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name); 513 | unsigned int STDCALL mysql_thread_safe(void); 514 | my_bool STDCALL mysql_embedded(void); 515 | my_bool STDCALL mysql_read_query_result(MYSQL *mysql); 516 | int STDCALL mysql_reset_connection(MYSQL *mysql); 517 | 518 | /* 519 | The following definitions are added for the enhanced 520 | client-server protocol 521 | */ 522 | 523 | /* statement state */ 524 | enum enum_mysql_stmt_state 525 | { 526 | MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE, 527 | MYSQL_STMT_FETCH_DONE 528 | }; 529 | 530 | 531 | /* 532 | This structure is used to define bind information, and 533 | internally by the client library. 534 | Public members with their descriptions are listed below 535 | (conventionally `On input' refers to the binds given to 536 | mysql_stmt_bind_param, `On output' refers to the binds given 537 | to mysql_stmt_bind_result): 538 | 539 | buffer_type - One of the MYSQL_* types, used to describe 540 | the host language type of buffer. 541 | On output: if column type is different from 542 | buffer_type, column value is automatically converted 543 | to buffer_type before it is stored in the buffer. 544 | buffer - On input: points to the buffer with input data. 545 | On output: points to the buffer capable to store 546 | output data. 547 | The type of memory pointed by buffer must correspond 548 | to buffer_type. See the correspondence table in 549 | the comment to mysql_stmt_bind_param. 550 | 551 | The two above members are mandatory for any kind of bind. 552 | 553 | buffer_length - the length of the buffer. You don't have to set 554 | it for any fixed length buffer: float, double, 555 | int, etc. It must be set however for variable-length 556 | types, such as BLOBs or STRINGs. 557 | 558 | length - On input: in case when lengths of input values 559 | are different for each execute, you can set this to 560 | point at a variable containining value length. This 561 | way the value length can be different in each execute. 562 | If length is not NULL, buffer_length is not used. 563 | Note, length can even point at buffer_length if 564 | you keep bind structures around while fetching: 565 | this way you can change buffer_length before 566 | each execution, everything will work ok. 567 | On output: if length is set, mysql_stmt_fetch will 568 | write column length into it. 569 | 570 | is_null - On input: points to a boolean variable that should 571 | be set to TRUE for NULL values. 572 | This member is useful only if your data may be 573 | NULL in some but not all cases. 574 | If your data is never NULL, is_null should be set to 0. 575 | If your data is always NULL, set buffer_type 576 | to MYSQL_TYPE_NULL, and is_null will not be used. 577 | 578 | is_unsigned - On input: used to signify that values provided for one 579 | of numeric types are unsigned. 580 | On output describes signedness of the output buffer. 581 | If, taking into account is_unsigned flag, column data 582 | is out of range of the output buffer, data for this column 583 | is regarded truncated. Note that this has no correspondence 584 | to the sign of result set column, if you need to find it out 585 | use mysql_stmt_result_metadata. 586 | error - where to write a truncation error if it is present. 587 | possible error value is: 588 | 0 no truncation 589 | 1 value is out of range or buffer is too small 590 | 591 | Please note that MYSQL_BIND also has internals members. 592 | */ 593 | 594 | typedef struct st_mysql_bind 595 | { 596 | unsigned long *length; /* output length pointer */ 597 | my_bool *is_null; /* Pointer to null indicator */ 598 | void *buffer; /* buffer to get/put data */ 599 | /* set this if you want to track data truncations happened during fetch */ 600 | my_bool *error; 601 | unsigned char *row_ptr; /* for the current data position */ 602 | void (*store_param_func)(NET *net, struct st_mysql_bind *param); 603 | void (*fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *, 604 | unsigned char **row); 605 | void (*skip_result)(struct st_mysql_bind *, MYSQL_FIELD *, 606 | unsigned char **row); 607 | /* output buffer length, must be set when fetching str/binary */ 608 | unsigned long buffer_length; 609 | unsigned long offset; /* offset position for char/binary fetch */ 610 | unsigned long length_value; /* Used if length is 0 */ 611 | unsigned int param_number; /* For null count and error messages */ 612 | unsigned int pack_length; /* Internal length for packed data */ 613 | enum enum_field_types buffer_type; /* buffer type */ 614 | my_bool error_value; /* used if error is 0 */ 615 | my_bool is_unsigned; /* set if integer type is unsigned */ 616 | my_bool long_data_used; /* If used with mysql_send_long_data */ 617 | my_bool is_null_value; /* Used if is_null is 0 */ 618 | void *extension; 619 | } MYSQL_BIND; 620 | 621 | 622 | struct st_mysql_stmt_extension; 623 | 624 | /* statement handler */ 625 | typedef struct st_mysql_stmt 626 | { 627 | MEM_ROOT mem_root; /* root allocations */ 628 | LIST list; /* list to keep track of all stmts */ 629 | MYSQL *mysql; /* connection handle */ 630 | MYSQL_BIND *params; /* input parameters */ 631 | MYSQL_BIND *bind; /* output parameters */ 632 | MYSQL_FIELD *fields; /* result set metadata */ 633 | MYSQL_DATA result; /* cached result set */ 634 | MYSQL_ROWS *data_cursor; /* current row in cached result */ 635 | /* 636 | mysql_stmt_fetch() calls this function to fetch one row (it's different 637 | for buffered, unbuffered and cursor fetch). 638 | */ 639 | int (*read_row_func)(struct st_mysql_stmt *stmt, 640 | unsigned char **row); 641 | /* copy of mysql->affected_rows after statement execution */ 642 | my_ulonglong affected_rows; 643 | my_ulonglong insert_id; /* copy of mysql->insert_id */ 644 | unsigned long stmt_id; /* Id for prepared statement */ 645 | unsigned long flags; /* i.e. type of cursor to open */ 646 | unsigned long prefetch_rows; /* number of rows per one COM_FETCH */ 647 | /* 648 | Copied from mysql->server_status after execute/fetch to know 649 | server-side cursor status for this statement. 650 | */ 651 | unsigned int server_status; 652 | unsigned int last_errno; /* error code */ 653 | unsigned int param_count; /* input parameter count */ 654 | unsigned int field_count; /* number of columns in result set */ 655 | enum enum_mysql_stmt_state state; /* statement state */ 656 | char last_error[MYSQL_ERRMSG_SIZE]; /* error message */ 657 | char sqlstate[SQLSTATE_LENGTH+1]; 658 | /* Types of input parameters should be sent to server */ 659 | my_bool send_types_to_server; 660 | my_bool bind_param_done; /* input buffers were supplied */ 661 | unsigned char bind_result_done; /* output buffers were supplied */ 662 | /* mysql_stmt_close() had to cancel this result */ 663 | my_bool unbuffered_fetch_cancelled; 664 | /* 665 | Is set to true if we need to calculate field->max_length for 666 | metadata fields when doing mysql_stmt_store_result. 667 | */ 668 | my_bool update_max_length; 669 | struct st_mysql_stmt_extension *extension; 670 | } MYSQL_STMT; 671 | 672 | enum enum_stmt_attr_type 673 | { 674 | /* 675 | When doing mysql_stmt_store_result calculate max_length attribute 676 | of statement metadata. This is to be consistent with the old API, 677 | where this was done automatically. 678 | In the new API we do that only by request because it slows down 679 | mysql_stmt_store_result sufficiently. 680 | */ 681 | STMT_ATTR_UPDATE_MAX_LENGTH, 682 | /* 683 | unsigned long with combination of cursor flags (read only, for update, 684 | etc) 685 | */ 686 | STMT_ATTR_CURSOR_TYPE, 687 | /* 688 | Amount of rows to retrieve from server per one fetch if using cursors. 689 | Accepts unsigned long attribute in the range 1 - ulong_max 690 | */ 691 | STMT_ATTR_PREFETCH_ROWS 692 | }; 693 | 694 | 695 | MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql); 696 | int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, 697 | unsigned long length); 698 | int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt); 699 | int STDCALL mysql_stmt_fetch(MYSQL_STMT *stmt); 700 | int STDCALL mysql_stmt_fetch_column(MYSQL_STMT *stmt, MYSQL_BIND *bind_arg, 701 | unsigned int column, 702 | unsigned long offset); 703 | int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt); 704 | unsigned long STDCALL mysql_stmt_param_count(MYSQL_STMT * stmt); 705 | my_bool STDCALL mysql_stmt_attr_set(MYSQL_STMT *stmt, 706 | enum enum_stmt_attr_type attr_type, 707 | const void *attr); 708 | my_bool STDCALL mysql_stmt_attr_get(MYSQL_STMT *stmt, 709 | enum enum_stmt_attr_type attr_type, 710 | void *attr); 711 | my_bool STDCALL mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd); 712 | my_bool STDCALL mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd); 713 | my_bool STDCALL mysql_stmt_close(MYSQL_STMT * stmt); 714 | my_bool STDCALL mysql_stmt_reset(MYSQL_STMT * stmt); 715 | my_bool STDCALL mysql_stmt_free_result(MYSQL_STMT *stmt); 716 | my_bool STDCALL mysql_stmt_send_long_data(MYSQL_STMT *stmt, 717 | unsigned int param_number, 718 | const char *data, 719 | unsigned long length); 720 | MYSQL_RES *STDCALL mysql_stmt_result_metadata(MYSQL_STMT *stmt); 721 | MYSQL_RES *STDCALL mysql_stmt_param_metadata(MYSQL_STMT *stmt); 722 | unsigned int STDCALL mysql_stmt_errno(MYSQL_STMT * stmt); 723 | const char *STDCALL mysql_stmt_error(MYSQL_STMT * stmt); 724 | const char *STDCALL mysql_stmt_sqlstate(MYSQL_STMT * stmt); 725 | MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_seek(MYSQL_STMT *stmt, 726 | MYSQL_ROW_OFFSET offset); 727 | MYSQL_ROW_OFFSET STDCALL mysql_stmt_row_tell(MYSQL_STMT *stmt); 728 | void STDCALL mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong offset); 729 | my_ulonglong STDCALL mysql_stmt_num_rows(MYSQL_STMT *stmt); 730 | my_ulonglong STDCALL mysql_stmt_affected_rows(MYSQL_STMT *stmt); 731 | my_ulonglong STDCALL mysql_stmt_insert_id(MYSQL_STMT *stmt); 732 | unsigned int STDCALL mysql_stmt_field_count(MYSQL_STMT *stmt); 733 | 734 | my_bool STDCALL mysql_commit(MYSQL * mysql); 735 | my_bool STDCALL mysql_rollback(MYSQL * mysql); 736 | my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode); 737 | my_bool STDCALL mysql_more_results(MYSQL *mysql); 738 | int STDCALL mysql_next_result(MYSQL *mysql); 739 | int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt); 740 | void STDCALL mysql_close(MYSQL *sock); 741 | 742 | 743 | /* status return codes */ 744 | #define MYSQL_NO_DATA 100 745 | #define MYSQL_DATA_TRUNCATED 101 746 | 747 | #define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT) 748 | 749 | #define HAVE_MYSQL_REAL_CONNECT 750 | 751 | #ifdef __cplusplus 752 | } 753 | #endif 754 | 755 | #endif /* _mysql_h */ 756 | -------------------------------------------------------------------------------- /mysql.sc: -------------------------------------------------------------------------------- 1 | (library (mysql mysql) 2 | (export 3 | connect 4 | query 5 | err 6 | ) 7 | (import 8 | (scheme) 9 | (mysql const) 10 | (mysql ftype) 11 | (mysql ffi) 12 | (only (core alist) ref) 13 | ) 14 | 15 | (define-syntax make-ftype-null 16 | (syntax-rules () 17 | ((_ type) 18 | (make-ftype-pointer type #x00000000)))) 19 | 20 | (define connect 21 | (lambda (lst) 22 | (define host (or (ref lst 'hostname) '())) 23 | (define port (or (ref lst 'port) 3306)) 24 | (define user (or (ref lst 'user) '())) 25 | (define password (or (ref lst 'password) '())) 26 | (define database (or (ref lst 'database) '())) 27 | (define unix_socket (or (ref lst 'socket) #f)) 28 | (define clientflag (or (ref lst 'clientflag) 0)) 29 | (let* ((conn (mysql-init (make-ftype-null mysql))) 30 | (rst (mysql-real-connect conn host user password database port unix_socket clientflag))) 31 | (if (ftype-pointer-null? rst) 32 | (err conn "connect") 33 | conn)))) 34 | 35 | (define query 36 | (lambda (conn query) 37 | (if (zero? (mysql-query conn query)) 38 | (let ((result (mysql-store-result conn))) 39 | (if (not (ftype-pointer-null? result)) 40 | (let* ((num-fields (mysql-num-fields result)) 41 | (fields (parser-fields result num-fields)) 42 | (rows (parser-rows result fields '()))) 43 | (mysql-free-result result) 44 | (mysql-list->json rows fields)))) 45 | (err conn "query") 46 | ))) 47 | 48 | (define parser-fields 49 | (lambda (result num-fields) 50 | (mysql-field-seek result 0) 51 | (let ((fields (make-vector num-fields))) 52 | (let loop ((idx 0)) 53 | (let ((field (mysql-fetch-field result))) 54 | (if (ftype-pointer-null? field) 55 | fields 56 | (begin 57 | (vector-set! fields idx (cons (field-name field)(field-type field))) 58 | (loop (+ idx 1)) 59 | ))))))) 60 | 61 | (define parser-rows 62 | (lambda (result fields rows) 63 | (let ((row (mysql-fetch-row result))) 64 | (if (ftype-pointer-null? row) 65 | (reverse rows) 66 | (parser-rows result fields (cons (parser-columns row fields) rows)) 67 | )))) 68 | 69 | (define parser-columns 70 | (lambda (row fields) 71 | (let* ((len (vector-length fields)) 72 | (vec (make-vector len))) 73 | (let loop ((idx 0)) 74 | (if (= idx len) 75 | vec 76 | (let ((type (cdr (vector-ref fields idx)))) 77 | (vector-set! vec idx (parser-cell row idx type)) 78 | (loop (+ idx 1)) 79 | )))))) 80 | 81 | (define parser-cell 82 | (lambda (row column-index type) 83 | (if (null-cell? row column-index) 84 | 'null 85 | (type-convert (cell-string row column-index) type) 86 | ))) 87 | 88 | (define null-cell? 89 | (lambda (row column-index) 90 | (eq? 0 (foreign-ref 'unsigned-8 91 | (ftype-pointer-address 92 | (ftype-&ref mysql-row () row column-index)) 93 | 0)))) 94 | 95 | (define cell-string 96 | (lambda (row column-index) 97 | (char*->string 98 | (ftype-pointer-address 99 | (ftype-&ref mysql-row (*) row column-index))))) 100 | 101 | (define field-name 102 | (lambda (field) 103 | (char*->string 104 | (ftype-pointer-address 105 | (ftype-&ref mysql-field (name 0) field 0))))) 106 | 107 | (define field-type-map 108 | (let ((table (make-eq-hashtable))) 109 | (map 110 | (lambda (pair) 111 | (hashtable-set! table (car pair) (cdr pair))) 112 | '((0 . decimal) 113 | (1 . tiny) 114 | (2 . short) 115 | (3 . long) 116 | (4 . float) 117 | (5 . double) 118 | (6 . null) 119 | (7 . timestamp) 120 | (8 . longlong) 121 | (9 . int24) 122 | (10 . date) 123 | (11 . time) 124 | (12 . datetime) 125 | (13 . year) 126 | (14 . newdate) 127 | (15 . varchar) 128 | (16 . bit) 129 | (17 . timestamp2) 130 | (18 . datetime2) 131 | (19 . time2) 132 | (245 . json) 133 | (246 . newdecimal) 134 | (247 . enum) 135 | (248 . set) 136 | (249 . tiny-blob) 137 | (250 . medium-blob) 138 | (251 . long-blob) 139 | (252 . blob) 140 | (253 . var-string) 141 | (254 . string) 142 | (255 . geometry))) 143 | table)) 144 | 145 | (define field-type-symbol 146 | (lambda (field-type) 147 | (hashtable-ref field-type-map field-type '()))) 148 | 149 | (define field-type 150 | (lambda (field) 151 | (field-type-symbol 152 | (ftype-ref mysql-field (type) field 0)))) 153 | 154 | (define char*->string 155 | (lambda (address) 156 | (list->string 157 | (reverse 158 | (let loop ((pointer address) (chars '())) 159 | (let ((char (foreign-ref 'char pointer 0))) 160 | (if (char=? char #\nul) 161 | chars 162 | (loop (+ 1 pointer) (cons char chars))))))))) 163 | 164 | (define type-convert 165 | (lambda (value type) 166 | (case type 167 | ((decimal tiny short long float double longlong int24 newdecimal) 168 | (string->number value)) 169 | ((datetime timestamp) 170 | (date-string->date value)) 171 | (else value)))) 172 | 173 | (define date-string->date 174 | (lambda (date-string) 175 | (let ((part (lambda (start end) 176 | (string->number 177 | (substring date-string start end))))) 178 | (let ((year (part 0 4)) 179 | (month (part 5 7)) 180 | (day (part 8 10)) 181 | (hour (part 11 13)) 182 | (minute (part 14 16)) 183 | (second (part 17 19))) 184 | (make-date 0 second minute hour day month year 0))))) 185 | 186 | (define mysql-list->json 187 | (lambda (rows fields) 188 | (let* ((len (length rows)) 189 | (vec (make-vector len)) 190 | (field-len (vector-length fields))) 191 | (let loop1 ((idx1 0)) 192 | (if (< idx1 len) 193 | (let loop2 ((idx2 0) 194 | (lst '())) 195 | (if (< idx2 field-len) 196 | (loop2 (+ 1 idx2) 197 | (cons 198 | (cons 199 | (car (vector-ref fields idx2)) 200 | (vector-ref (list-ref rows idx1) idx2)) 201 | lst)) 202 | (begin 203 | (vector-set! vec idx1 (reverse lst)) 204 | (loop1 (+ 1 idx1))))) 205 | vec 206 | ))))) 207 | 208 | (define err 209 | (lambda (conn name) 210 | (let ((msg (format "errno: ~a, error: ~a" (mysql-errno conn) (mysql-error conn))) 211 | (act (string-append "" name))) 212 | (mysql-close conn) 213 | (error act msg)))) 214 | ) 215 | -------------------------------------------------------------------------------- /package.sc: -------------------------------------------------------------------------------- 1 | (("name" . "mysql") 2 | ("version" . "0.1.1") 3 | ("description" . "") 4 | ("keywords") 5 | ("author" 6 | ("ch")) 7 | ("private" . #f) 8 | ("scripts" 9 | ("run" . "scheme --script") 10 | ("repl" . "scheme") 11 | ("test" . "raven run mysql/test/test.ss")) 12 | ("dependencies" 13 | ("core" . "1.3.1")) 14 | ("devDependencies")) -------------------------------------------------------------------------------- /test/test.sc: -------------------------------------------------------------------------------- 1 | (import (mysql mysql)) 2 | 3 | (define conn (mysql:connect "localhost" "root" "123456" "sys")) 4 | 5 | (display (mysql:query conn "SELECT * FROM sys.sys_config")) 6 | --------------------------------------------------------------------------------