ffi-mysql 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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