mysql_blob_streaming 1.1.3

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/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
+