mysql_blob_streaming 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown ADDED
@@ -0,0 +1,24 @@
1
+ # A blob streaming extension for the native Ruby-MySQL adaptor.
2
+
3
+ It provides the module MysqlBlobStreaming, which gives the adaptor the ability
4
+ of streaming blobs right out of the MySQL database.
5
+
6
+ (c) 2008-2012 Infopark AG. See MIT-LICENSE for licensing details.
7
+
8
+ ## Dependencies
9
+
10
+ * Ruby-headers
11
+ * MySQL-headers
12
+ * [Native Ruby-MySQL adaptor](http://www.tmtm.org/en/mysql/ruby)
13
+
14
+ ## Building
15
+
16
+ gem build mysql_blob_streaming.gemspec
17
+
18
+ ## Installation
19
+
20
+ Install it like any other Gem:
21
+
22
+ gem install mysql_blob_streaming-X.X.X.gem
23
+
24
+ Run it with root privileges if needed.
@@ -0,0 +1,23 @@
1
+ require "mkmf"
2
+
3
+ additional_mysql_include_dirs = [
4
+ '/usr/local/mysql/include',
5
+ '/usr/include/mysql']
6
+ additional_mysql_lib_dirs = additional_mysql_include_dirs.map{
7
+ |d| d.sub('include', 'lib')}
8
+
9
+ find_header('mysql.h', *additional_mysql_include_dirs)
10
+ find_header('errmsg.h', *additional_mysql_include_dirs)
11
+ find_library('mysqlclient', nil, *additional_mysql_lib_dirs)
12
+
13
+ # --no-undefined forces us to link against libruby
14
+ def remove_no_undefined(ldflags)
15
+ ldflags.gsub("-Wl,--no-undefined", "")
16
+ end
17
+
18
+ with_ldflags("#{remove_no_undefined($LDFLAGS)}") { true }
19
+
20
+ # Do NOT link against libruby
21
+ $LIBRUBYARG = ""
22
+
23
+ create_makefile("mysql_blob_streaming/mysql_blob_streaming")
@@ -0,0 +1,98 @@
1
+ #include <ruby.h>
2
+ #include <stdlib.h>
3
+
4
+ #include <mysql.h>
5
+ #include <errmsg.h>
6
+
7
+ struct mysql_stmt {
8
+ MYSQL_STMT *stmt;
9
+ char closed;
10
+ struct {
11
+ int n;
12
+ MYSQL_BIND *bind;
13
+ unsigned long *length;
14
+ MYSQL_TIME *buffer;
15
+ } param;
16
+ struct {
17
+ int n;
18
+ MYSQL_BIND *bind;
19
+ my_bool *is_null;
20
+ unsigned long *length;
21
+ } result;
22
+ MYSQL_RES *res;
23
+ };
24
+
25
+
26
+ static void store_buffer(struct mysql_stmt *s, int offset_index, VALUE obj)
27
+ {
28
+ int status = mysql_stmt_fetch_column(s->stmt, s->result.bind, 0, offset_index);
29
+ if (status != 0) {
30
+ rb_raise(rb_eRuntimeError, "Fetching column failed");
31
+ }
32
+ if (!s->result.is_null[0]) {
33
+ if (s->result.bind[0].buffer_type == MYSQL_TYPE_BLOB) {
34
+ rb_funcall(obj, rb_intern("handle_data"), 1, rb_str_new(s->result.bind[0].buffer,
35
+ s->result.bind[0].buffer_length));
36
+ } else {
37
+ rb_raise(rb_eRuntimeError, "wrong buffer_type (must be: MYSQL_TYPE_BLOB): %d",
38
+ s->result.bind[0].buffer_type);
39
+ }
40
+ }
41
+ }
42
+
43
+
44
+ static int determine_blob_length(struct mysql_stmt *s)
45
+ {
46
+ s->result.bind[0].buffer_length = 0;
47
+ if (mysql_stmt_bind_result(s->stmt, s->result.bind) != 0) {
48
+ rb_raise(rb_eRuntimeError, "Could not determine the blob length: bind failed");
49
+ }
50
+ int status = mysql_stmt_fetch(s->stmt);
51
+ // MYSQL_DATA_TRUNCATED is returned if MYSQL_REPORT_DATA_TRUNCATION connection option is set
52
+ if (status != 0 && status != MYSQL_DATA_TRUNCATED) {
53
+ rb_raise(rb_eRuntimeError, "Could not determine the blob length: fetch failed");
54
+ }
55
+ return *s->result.bind[0].length;
56
+ }
57
+
58
+
59
+ static VALUE stmt_fetch_and_write(VALUE obj, VALUE rb_buffer_length)
60
+ {
61
+ int buffer_length = FIX2INT(rb_buffer_length);
62
+
63
+ if (buffer_length == 0) {
64
+ return 0;
65
+ }
66
+ if (buffer_length < 0) {
67
+ rb_raise(rb_eRuntimeError, "buffer size must be integer >= 0");
68
+ }
69
+
70
+ struct mysql_stmt *s = DATA_PTR(obj);
71
+ int blob_length = determine_blob_length(s);
72
+
73
+ s->result.bind[0].buffer_length = buffer_length;
74
+ if (blob_length <= s->result.bind[0].buffer_length) {
75
+ s->result.bind[0].buffer_length = blob_length;
76
+ store_buffer(s, 0, obj);
77
+ } else {
78
+ long loops = abs(blob_length / s->result.bind[0].buffer_length);
79
+ long i;
80
+ for (i = 0; i < loops; ++i) {
81
+ store_buffer(s, i * s->result.bind[0].buffer_length, obj);
82
+ }
83
+ int old_bufflen = s->result.bind[0].buffer_length;
84
+ int new_bufflen = blob_length % s->result.bind[0].buffer_length;
85
+ if (new_bufflen) {
86
+ s->result.bind[0].buffer_length = new_bufflen;
87
+ store_buffer(s, loops * old_bufflen, obj);
88
+ }
89
+ }
90
+ return Qnil;
91
+ }
92
+
93
+
94
+ void Init_mysql_blob_streaming()
95
+ {
96
+ VALUE rb_mMysqlBlobStreaming = rb_define_module("MysqlBlobStreaming");
97
+ rb_define_method(rb_mMysqlBlobStreaming, "stream", stmt_fetch_and_write, 1);
98
+ }
@@ -0,0 +1 @@
1
+ require "mysql_blob_streaming/mysql_blob_streaming"
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mysql_blob_streaming
3
+ version: !ruby/object:Gem::Version
4
+ hash: 21
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 1
9
+ - 3
10
+ version: 1.1.3
11
+ platform: ruby
12
+ authors:
13
+ - Infopark AG
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-07-12 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: mysql
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 13
29
+ segments:
30
+ - 2
31
+ - 7
32
+ version: "2.7"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: " This GEM is required by the Infopark Rails Connector (RC) when using MySQL.\n"
36
+ email: info@infopark.de
37
+ executables: []
38
+
39
+ extensions:
40
+ - ext/mysql_blob_streaming/extconf.rb
41
+ extra_rdoc_files:
42
+ - README.markdown
43
+ files:
44
+ - lib/mysql_blob_streaming.rb
45
+ - ext/mysql_blob_streaming/mysql_blob_streaming.c
46
+ - ext/mysql_blob_streaming/extconf.rb
47
+ - README.markdown
48
+ homepage: http://www.infopark.de/
49
+ licenses: []
50
+
51
+ post_install_message:
52
+ rdoc_options:
53
+ - --main
54
+ - README.markdown
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ hash: 57
63
+ segments:
64
+ - 1
65
+ - 8
66
+ - 7
67
+ version: 1.8.7
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ requirements:
78
+ - Infopark Rails Connector (RC)
79
+ rubyforge_project:
80
+ rubygems_version: 1.8.21
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: A blob streaming extension for the native Ruby-MySQL adapter
84
+ test_files: []
85
+