ffi-mysql 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.rdoc ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 / 2010-03-03
2
+
3
+ * 1 major enhancement
4
+ * mostly compatible to MySQL/Ruby
data/README ADDED
@@ -0,0 +1,55 @@
1
+ ffi-mysql
2
+ by Frank Fischer
3
+ http://bitbucket.org/lyro/ffi-mysql
4
+
5
+ == DESCRIPTION:
6
+
7
+ Pure Ruby FFI interface to MySQL.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * satisfies almost complete test-suite of MySQL/Ruby
12
+ * prepared statement does not handle Double fields
13
+ correctly
14
+
15
+ == SYNOPSIS:
16
+
17
+ See MySQL/Ruby for examples.
18
+
19
+ == REQUIREMENTS:
20
+
21
+ * ffi >= 0.6.2
22
+
23
+ == INSTALL:
24
+
25
+ gem install ffi-ruby
26
+
27
+ == ACKNOWLEDGEMENTS:
28
+
29
+ Tomita Masahiro for his MySQL/Ruby and Ruby/MySQL gems from which some
30
+ of the code has been stolen.
31
+
32
+ == LICENSE:
33
+
34
+ (The MIT License)
35
+
36
+ Copyright (c) 2010 Frank Fischer
37
+
38
+ Permission is hereby granted, free of charge, to any person obtaining
39
+ a copy of this software and associated documentation files (the
40
+ 'Software'), to deal in the Software without restriction, including
41
+ without limitation the rights to use, copy, modify, merge, publish,
42
+ distribute, sublicense, and/or sell copies of the Software, and to
43
+ permit persons to whom the Software is furnished to do so, subject to
44
+ the following conditions:
45
+
46
+ The above copyright notice and this permission notice shall be
47
+ included in all copies or substantial portions of the Software.
48
+
49
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
50
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
52
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
53
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
54
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
55
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,55 @@
1
+ ffi-mysql
2
+ by Frank Fischer
3
+ http://bitbucket.org/lyro/ffi-mysql
4
+
5
+ == DESCRIPTION:
6
+
7
+ Pure Ruby FFI interface to MySQL.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * satisfies almost complete test-suite of MySQL/Ruby
12
+ * prepared statement does not handle Double fields
13
+ correctly
14
+
15
+ == SYNOPSIS:
16
+
17
+ See MySQL/Ruby for examples.
18
+
19
+ == REQUIREMENTS:
20
+
21
+ * ffi >= 0.6.2
22
+
23
+ == INSTALL:
24
+
25
+ gem install ffi-ruby
26
+
27
+ == ACKNOWLEDGEMENTS:
28
+
29
+ Tomita Masahiro for his MySQL/Ruby and Ruby/MySQL gems from which some
30
+ of the code has been stolen.
31
+
32
+ == LICENSE:
33
+
34
+ (The MIT License)
35
+
36
+ Copyright (c) 2010 Frank Fischer
37
+
38
+ Permission is hereby granted, free of charge, to any person obtaining
39
+ a copy of this software and associated documentation files (the
40
+ 'Software'), to deal in the Software without restriction, including
41
+ without limitation the rights to use, copy, modify, merge, publish,
42
+ distribute, sublicense, and/or sell copies of the Software, and to
43
+ permit persons to whom the Software is furnished to do so, subject to
44
+ the following conditions:
45
+
46
+ The above copyright notice and this permission notice shall be
47
+ included in all copies or substantial portions of the Software.
48
+
49
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
50
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
52
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
53
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
54
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
55
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+
2
+ begin
3
+ require 'bones'
4
+ rescue LoadError
5
+ abort '### Please install the "bones" gem ###'
6
+ end
7
+
8
+ ensure_in_path 'lib'
9
+ require 'ffi-mysql'
10
+
11
+ task :default => 'test:run'
12
+ task 'gem:release' => 'test:run'
13
+
14
+ Bones {
15
+ name 'ffi-mysql'
16
+ authors 'Frank Fischer'
17
+ email 'frank.fischer@mathematik.tu-chemnitz.de'
18
+ url 'http://bitbucket.org/lyro/ffi-mysql/wiki'
19
+ ignore_file '.hgignore'
20
+ readme_file 'README.rdoc'
21
+ history_file 'History.rdoc'
22
+ version Mysql::VERSION
23
+ gem.extras = { :has_rdoc => 'yard' }
24
+ depend_on 'ffi', '>= 0.6.2'
25
+ }
26
+
27
+ # EOF
data/lib/ffi-mysql.rb ADDED
@@ -0,0 +1,49 @@
1
+
2
+ class Mysql
3
+
4
+ # :stopdoc:
5
+ VERSION = '0.0.1'
6
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
7
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
8
+ # :startdoc:
9
+
10
+ # Returns the version string for the library.
11
+ #
12
+ def self.version
13
+ VERSION
14
+ end
15
+
16
+ # Returns the library path for the module. If any arguments are given,
17
+ # they will be joined to the end of the libray path using
18
+ # <tt>File.join</tt>.
19
+ #
20
+ def self.libpath( *args )
21
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
22
+ end
23
+
24
+ # Returns the lpath for the module. If any arguments are given,
25
+ # they will be joined to the end of the path using
26
+ # <tt>File.join</tt>.
27
+ #
28
+ def self.path( *args )
29
+ args.empty? ? PATH : ::File.join(PATH, args.flatten)
30
+ end
31
+
32
+ # Utility method used to require all files ending in .rb that lie in the
33
+ # directory below this file that has the same name as the filename passed
34
+ # in. Optionally, a specific _directory_ name can be passed in such that
35
+ # the _filename_ does not have to be equivalent to the directory.
36
+ #
37
+ def self.require_all_libs_relative_to( fname, dir = nil )
38
+ dir ||= ::File.basename(fname, '.*')
39
+ search_me = ::File.expand_path(
40
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
41
+
42
+ Dir.glob(search_me).sort.each {|rb| require rb}
43
+ end
44
+
45
+ end # class Mysql
46
+
47
+ Mysql.require_all_libs_relative_to(__FILE__, "mysql")
48
+
49
+
@@ -0,0 +1,166 @@
1
+ # Copyright (C) 2003-2008 TOMITA Masahiro
2
+ # mailto:tommy@tmtm.org
3
+
4
+ class Mysql
5
+ # Command
6
+ COM_SLEEP = 0
7
+ COM_QUIT = 1
8
+ COM_INIT_DB = 2
9
+ COM_QUERY = 3
10
+ COM_FIELD_LIST = 4
11
+ COM_CREATE_DB = 5
12
+ COM_DROP_DB = 6
13
+ COM_REFRESH = 7
14
+ COM_SHUTDOWN = 8
15
+ COM_STATISTICS = 9
16
+ COM_PROCESS_INFO = 10
17
+ COM_CONNECT = 11
18
+ COM_PROCESS_KILL = 12
19
+ COM_DEBUG = 13
20
+ COM_PING = 14
21
+ COM_TIME = 15
22
+ COM_DELAYED_INSERT = 16
23
+ COM_CHANGE_USER = 17
24
+ COM_BINLOG_DUMP = 18
25
+ COM_TABLE_DUMP = 19
26
+ COM_CONNECT_OUT = 20
27
+ COM_REGISTER_SLAVE = 21
28
+ COM_STMT_PREPARE = 22
29
+ COM_STMT_EXECUTE = 23
30
+ COM_STMT_SEND_LONG_DATA = 24
31
+ COM_STMT_CLOSE = 25
32
+ COM_STMT_RESET = 26
33
+ COM_SET_OPTION = 27
34
+ COM_STMT_FETCH = 28
35
+
36
+ # Client flag
37
+ CLIENT_LONG_PASSWORD = 1 # new more secure passwords
38
+ CLIENT_FOUND_ROWS = 1 << 1 # Found instead of affected rows
39
+ CLIENT_LONG_FLAG = 1 << 2 # Get all column flags
40
+ CLIENT_CONNECT_WITH_DB = 1 << 3 # One can specify db on connect
41
+ CLIENT_NO_SCHEMA = 1 << 4 # Don't allow database.table.column
42
+ CLIENT_COMPRESS = 1 << 5 # Can use compression protocol
43
+ CLIENT_ODBC = 1 << 6 # Odbc client
44
+ CLIENT_LOCAL_FILES = 1 << 7 # Can use LOAD DATA LOCAL
45
+ CLIENT_IGNORE_SPACE = 1 << 8 # Ignore spaces before '('
46
+ CLIENT_PROTOCOL_41 = 1 << 9 # New 4.1 protocol
47
+ CLIENT_INTERACTIVE = 1 << 10 # This is an interactive client
48
+ CLIENT_SSL = 1 << 11 # Switch to SSL after handshake
49
+ CLIENT_IGNORE_SIGPIPE = 1 << 12 # IGNORE sigpipes
50
+ CLIENT_TRANSACTIONS = 1 << 13 # Client knows about transactions
51
+ CLIENT_RESERVED = 1 << 14 # Old flag for 4.1 protocol
52
+ CLIENT_SECURE_CONNECTION = 1 << 15 # New 4.1 authentication
53
+ CLIENT_MULTI_STATEMENTS = 1 << 16 # Enable/disable multi-stmt support
54
+ CLIENT_MULTI_RESULTS = 1 << 17 # Enable/disable multi-results
55
+
56
+ # Connection Option
57
+ OPT_CONNECT_TIMEOUT = 0
58
+ OPT_COMPRESS = 1
59
+ OPT_NAMED_PIPE = 2
60
+ INIT_COMMAND = 3
61
+ READ_DEFAULT_FILE = 4
62
+ READ_DEFAULT_GROUP = 5
63
+ SET_CHARSET_DIR = 6
64
+ SET_CHARSET_NAME = 7
65
+ OPT_LOCAL_INFILE = 8
66
+ OPT_PROTOCOL = 9
67
+ SHARED_MEMORY_BASE_NAME = 10
68
+ OPT_READ_TIMEOUT = 11
69
+ OPT_WRITE_TIMEOUT = 12
70
+ OPT_USE_RESULT = 13
71
+ OPT_USE_REMOTE_CONNECTION = 14
72
+ OPT_USE_EMBEDDED_CONNECTION = 15
73
+ OPT_GUESS_CONNECTION = 16
74
+ SET_CLIENT_IP = 17
75
+ SECURE_AUTH = 18
76
+ REPORT_DATA_TRUNCATION = 19
77
+ OPT_RECONNECT = 20
78
+ OPT_SSL_VERIFY_SERVER_CERT = 21
79
+
80
+ # Server Option
81
+ OPTION_MULTI_STATEMENTS_ON = 0
82
+ OPTION_MULTI_STATEMENTS_OFF = 1
83
+
84
+ # Server Status
85
+ SERVER_STATUS_IN_TRANS = 1
86
+ SERVER_STATUS_AUTOCOMMIT = 1 << 1
87
+ SERVER_MORE_RESULTS_EXISTS = 1 << 3
88
+ SERVER_QUERY_NO_GOOD_INDEX_USED = 1 << 4
89
+ SERVER_QUERY_NO_INDEX_USED = 1 << 5
90
+ SERVER_STATUS_CURSOR_EXISTS = 1 << 6
91
+ SERVER_STATUS_LAST_ROW_SENT = 1 << 7
92
+ SERVER_STATUS_DB_DROPPED = 1 << 8
93
+ SERVER_STATUS_NO_BACKSLASH_ESCAPES = 1 << 9
94
+
95
+ # Refresh parameter
96
+ REFRESH_GRANT = 1
97
+ REFRESH_LOG = 1 << 1
98
+ REFRESH_TABLES = 1 << 2
99
+ REFRESH_HOSTS = 1 << 3
100
+ REFRESH_STATUS = 1 << 4
101
+ REFRESH_THREADS = 1 << 5
102
+ REFRESH_SLAVE = 1 << 6
103
+ REFRESH_MASTER = 1 << 7
104
+ REFRESH_READ_LOCK = 1 << 14
105
+ REFRESH_FAST = 1 << 15
106
+
107
+ class Field
108
+ # Field type
109
+ TYPE_DECIMAL = 0
110
+ TYPE_TINY = 1
111
+ TYPE_SHORT = 2
112
+ TYPE_LONG = 3
113
+ TYPE_FLOAT = 4
114
+ TYPE_DOUBLE = 5
115
+ TYPE_NULL = 6
116
+ TYPE_TIMESTAMP = 7
117
+ TYPE_LONGLONG = 8
118
+ TYPE_INT24 = 9
119
+ TYPE_DATE = 10
120
+ TYPE_TIME = 11
121
+ TYPE_DATETIME = 12
122
+ TYPE_YEAR = 13
123
+ TYPE_NEWDATE = 14
124
+ TYPE_VARCHAR = 15
125
+ TYPE_BIT = 16
126
+ TYPE_NEWDECIMAL = 246
127
+ TYPE_ENUM = 247
128
+ TYPE_SET = 248
129
+ TYPE_TINY_BLOB = 249
130
+ TYPE_MEDIUM_BLOB = 250
131
+ TYPE_LONG_BLOB = 251
132
+ TYPE_BLOB = 252
133
+ TYPE_VAR_STRING = 253
134
+ TYPE_STRING = 254
135
+ TYPE_GEOMETRY = 255
136
+ TYPE_CHAR = TYPE_TINY
137
+ TYPE_INTERVAL = TYPE_ENUM
138
+
139
+ # Flag
140
+ NOT_NULL_FLAG = 1
141
+ PRI_KEY_FLAG = 2
142
+ UNIQUE_KEY_FLAG = 4
143
+ MULTIPLE_KEY_FLAG = 8
144
+ BLOB_FLAG = 16
145
+ UNSIGNED_FLAG = 32
146
+ ZEROFILL_FLAG = 64
147
+ BINARY_FLAG = 128
148
+ ENUM_FLAG = 256
149
+ AUTO_INCREMENT_FLAG = 512
150
+ TIMESTAMP_FLAG = 1024
151
+ SET_FLAG = 2048
152
+ NUM_FLAG = 32768
153
+ PART_KEY_FLAG = 16384
154
+ GROUP_FLAG = 32768
155
+ UNIQUE_FLAG = 65536
156
+ BINCMP_FLAG = 131072
157
+ end
158
+
159
+ class Stmt
160
+ # Cursor type
161
+ CURSOR_TYPE_NO_CURSOR = 0
162
+ CURSOR_TYPE_READ_ONLY = 1
163
+ NO_DATA = 100
164
+ DATA_TRUNCATED = 101
165
+ end
166
+ end
@@ -0,0 +1,4 @@
1
+ class Mysql
2
+ class Error < Exception
3
+ end
4
+ end
@@ -0,0 +1,89 @@
1
+ class Mysql
2
+ # Information about one column.
3
+ class Field
4
+ attr_reader :name
5
+ attr_reader :org_name
6
+ attr_reader :table
7
+ attr_reader :org_table
8
+ attr_reader :db
9
+ attr_reader :catalog
10
+ attr_reader :def
11
+ attr_reader :length
12
+ attr_reader :max_length
13
+ attr_reader :name_length
14
+ attr_reader :org_name_length
15
+ attr_reader :table_length
16
+ attr_reader :org_table_length
17
+ attr_reader :db_length
18
+ attr_reader :catalog_length
19
+ attr_reader :def_length
20
+ attr_reader :flags
21
+ attr_reader :decimals
22
+ attr_reader :charsetnr
23
+ attr_reader :type
24
+
25
+ def initialize(c_field)
26
+ @name = c_field[:name]
27
+ @org_name = c_field[:org_name]
28
+ @table = c_field[:table]
29
+ @org_table = c_field[:org_table]
30
+ @db = c_field[:db]
31
+ @catalog = c_field[:catalog]
32
+ @def = c_field[:def]
33
+ @length = c_field[:length]
34
+ @max_length = c_field[:max_length]
35
+ @name_length = c_field[:name_length]
36
+ @org_name_length = c_field[:org_name_length]
37
+ @table_length = c_field[:table_length]
38
+ @org_table_length = c_field[:org_table_length]
39
+ @db_length = c_field[:db_length]
40
+ @catalog_length = c_field[:catalog_length]
41
+ @def_length = c_field[:def_length]
42
+ @flags = c_field[:flags]
43
+ @decimals = c_field[:decimals]
44
+ @charsetnr = c_field[:charsetnr]
45
+ # @type = C::FieldType[c_field[:type]]
46
+ @type = c_field[:type]
47
+ @flags |= NUM_FLAG if is_num_type?
48
+ end
49
+
50
+ # @return [Boolean] true if this field is not null
51
+ def is_not_null?
52
+ @flags & NOT_NULL_FLAG != 0
53
+ end
54
+
55
+ # @return [Boolean] true if this is a numeric field
56
+ def is_num?
57
+ @flags & NUM_FLAG != 0
58
+ end
59
+
60
+ # @return [Boolean] true if this field is a primary key
61
+ def is_pri_key?
62
+ @flags & PRI_KEY_FLAG != 0
63
+ end
64
+
65
+ # @return [Hash] this field as a hash
66
+ def hash
67
+ h = {}
68
+ h['name'] = @name
69
+ h['table'] = @table
70
+ h['def'] = @def
71
+ h['length'] = @length
72
+ h['max_length'] = @max_length
73
+ h['flags'] = @flags
74
+ h['decimals'] = @decimals
75
+ h['type'] = @type
76
+ h
77
+ end
78
+
79
+ def inspect
80
+ "#<Mysql::Field:#{@name}>"
81
+ end
82
+
83
+ private
84
+ # @return [Boolean] true if this field's type is a numeric type
85
+ def is_num_type?
86
+ [TYPE_DECIMAL, TYPE_TINY, TYPE_SHORT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_LONGLONG, TYPE_INT24].include?(@type) || (@type == TYPE_TIMESTAMP && (@length == 14 || @length == 8))
87
+ end
88
+ end
89
+ end