ghazel-slim-attributes 0.6.3.1 → 0.7.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -11,15 +11,16 @@ Measuring with just ActiveRecord code - fetching stuff from the database - we se
11
11
  Installation
12
12
  ============
13
13
 
14
- You're going to need the mysql headers for this to work.
14
+ Slim attributes works with Rails and Ruby 1.8.x. Ruby 1.9 is also supported with Rails version 2.3.5 and above.
15
15
 
16
16
  Try:
17
- gem install slim-attributes -- --with-mysql-config
17
+ sudo gem install slim-attributes
18
18
  or:
19
- gem install slim-attributes
19
+ sudo gem install slim-attributes -- --with-mysql-config
20
20
 
21
- then add this to environment.rb:
22
- require 'slim_attributes'
21
+ then add this to environment.rb in the Rails::Initializer.run section:
22
+
23
+ config.gem 'slim-attributes'
23
24
 
24
25
 
25
26
  Description
@@ -36,9 +37,25 @@ So this is an alternative implementation of all_hashes that returns a 'fake hash
36
37
  The field contents are then instantiated into Ruby strings on demand - ruby strings are only made if you need them. Note that if you always look at all the columns when you fetch data from the database then this won't necessarily be faster that the unpatched mysql adapter. But it won't be much slower either, and we do expect that most times not all the columns from a result set are accessed.
37
38
 
38
39
 
39
- ===========
40
+ Bugs
41
+ ====
42
+
43
+ Slim attributes will not work correctly with ruby 1.9.x with versions lower than Rails 2.3.5
44
+
45
+
46
+ Warranty
47
+ ========
48
+
49
+ No warranty - this gem has been extensively tested, but not in all environments.
50
+ We are using it in our production environment with very good results.
51
+ Please report bugs to sdsykes at symbol gmail pip com or via the github issue tracking system.
52
+
53
+
54
+ Credits
55
+ =======
40
56
 
41
- No warranty - this gem has been tested, but not in all environments. However, that said, we are using it in our production environment with good results.
42
- Please report bugs to sdsykes at symbol gmail pip com.
57
+ Thanks to IronDigital for the initial port for ruby 1.9.
58
+ Thanks to Greg Hazel (ghazel) for fixing compilation for windows.
59
+ Thanks to Nando Vieira (fnando) for adding slim-attributes.rb to avoid the underscore dash confusion.
43
60
 
44
- Copyright (c) 2008 Stephen Sykes, released under the MIT license
61
+ Copyright (c) 2008-2010 Stephen Sykes, released under the MIT license
data/Rakefile CHANGED
@@ -12,8 +12,16 @@ begin
12
12
  s.authors = ["Stephen Sykes"]
13
13
  s.files = FileList["[A-Z]*", "{ext,lib,test}/**/*"]
14
14
  s.extensions = "ext/extconf.rb"
15
+ s.rubyforge_project = 'slim-attributes'
15
16
  end
17
+ Jeweler::GemcutterTasks.new
18
+ Jeweler::RubyforgeTasks.new
16
19
  rescue LoadError
17
20
  puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://
18
21
  gems.github.com"
19
22
  end
23
+
24
+ task :rdoc do
25
+ `mkdir rdoc`
26
+ `echo documentation is at http://github.com/sdsykes/slim-attributes > rdoc/README.rdoc`
27
+ end
data/VERSION.yml CHANGED
@@ -1,4 +1,5 @@
1
1
  ---
2
- :patch: 3
2
+ :patch: 6
3
3
  :major: 0
4
- :minor: 6
4
+ :minor: 7
5
+ :build:
data/ext/extconf.rb CHANGED
@@ -1,12 +1,27 @@
1
- # this code is borrowed from Mysql/Ruby, credit to TOMITA Masahiro
1
+ # this code was originally borrowed from Mysql/Ruby, credit to TOMITA Masahiro
2
2
  # it works for me under OS X and Fedora, hope it works for you also
3
3
 
4
4
  require 'mkmf'
5
5
 
6
- if /mswin32/ =~ RUBY_PLATFORM
6
+ # Improved detection of mysql_config
7
+ # Code from DataObjects do_mysql adapter
8
+ # All instances of mysql_config on PATH ...
9
+ def mysql_config_paths
10
+ ENV['PATH'].split(File::PATH_SEPARATOR).collect do |path|
11
+ [ "#{path}/mysql_config", "#{path}/mysql_config5" ].
12
+ detect { |bin| File.exist?(bin) }
13
+ end
14
+ end
15
+
16
+ # The first mysql_config binary on PATH ...
17
+ def default_mysql_config_path
18
+ mysql_config_paths.compact.first
19
+ end
20
+
21
+ if RUBY_PLATFORM =~ /mswin|mingw/
7
22
  inc, lib = dir_config('mysql')
8
23
  exit 1 unless have_library("libmysql")
9
- elsif mc = with_config('mysql-config') then
24
+ elsif mc = with_config('mysql-config', default_mysql_config_path) then
10
25
  mc = 'mysql_config' if mc == true
11
26
  cflags = `#{mc} --cflags`.chomp
12
27
  exit 1 if $? != 0
@@ -2,7 +2,12 @@
2
2
  // http://pennysmalls.com
3
3
 
4
4
  #include "ruby.h"
5
+
6
+ #ifdef HAVE_RUBY_ST_H
7
+ #include "ruby/st.h"
8
+ #else
5
9
  #include "st.h"
10
+ #endif
6
11
 
7
12
  #include <mysql.h>
8
13
  #include <errmsg.h>
@@ -13,7 +18,8 @@
13
18
  #define GetCharStarPtr(obj) (Check_Type(obj, T_DATA), (char**)DATA_PTR(obj))
14
19
 
15
20
  VALUE cRowHash, cClass;
16
- ID pointers_id, row_info_id, field_indexes_id, real_hash_id, to_hash_id;
21
+ ID pointers_id, row_info_id, field_indexes_id, real_hash_id, to_hash_id, sq_parens_id,
22
+ sq_parens_equal_id, has_key_id;
17
23
 
18
24
  #define MAX_CACHED_COLUMN_IDS 40
19
25
  ID column_ids[MAX_CACHED_COLUMN_IDS];
@@ -25,8 +31,8 @@ struct mysql_res {
25
31
  };
26
32
 
27
33
  // row info
28
- #define SLIM_IS_NULL (char)0x01
29
- #define SLIM_IS_SET (char)0x02
34
+ #define SLIM_IS_NULL 0x01
35
+ #define SLIM_IS_SET 0x02
30
36
 
31
37
  #define GET_COL_IV_ID(str, cnum) (cnum < MAX_CACHED_COLUMN_IDS ? column_ids[cnum] : (sprintf(str, "@col_%ld", cnum), rb_intern(str)))
32
38
 
@@ -98,7 +104,7 @@ static VALUE fetch_by_index(VALUE obj, VALUE index) {
98
104
  long col_number = FIX2LONG(index);
99
105
  unsigned int length;
100
106
  row_info = GetCharPtr(rb_ivar_get(obj, row_info_id)) + col_number; // flags for this column
101
- if (*row_info == SLIM_IS_NULL) return Qnil; // return nil if null from db
107
+ if (*row_info & SLIM_IS_NULL) return Qnil; // return nil if null from db
102
108
  col_id = GET_COL_IV_ID(col_name, col_number);
103
109
  if (*row_info == SLIM_IS_SET) return rb_ivar_get(obj, col_id); // was made to a string already
104
110
  pointers = GetCharStarPtr(rb_ivar_get(obj, pointers_id)); // find the data and make ruby string
@@ -113,12 +119,16 @@ static VALUE fetch_by_index(VALUE obj, VALUE index) {
113
119
  // This is the [] method of the row data object.
114
120
  // It checks for a real hash, but if none exists it will call fetch_by_index
115
121
  static VALUE slim_fetch(VALUE obj, VALUE name) {
116
- VALUE field_indexes, hash_lookup;
122
+ VALUE field_indexes, hash_lookup, real_hash;
117
123
 
118
- if (REAL_HASH_EXISTS) return rb_hash_aref(rb_ivar_get(obj, real_hash_id), name);
124
+ if (REAL_HASH_EXISTS) return rb_funcall(rb_ivar_get(obj, real_hash_id), sq_parens_id, 1, name);
119
125
 
120
126
  hash_lookup = rb_hash_aref(field_indexes, name);
121
- if (NIL_P(hash_lookup)) return Qnil;
127
+ if (NIL_P(hash_lookup)) {
128
+ real_hash = rb_ivar_get(obj, real_hash_id);
129
+ if (NIL_P(real_hash)) return Qnil;
130
+ return rb_funcall(real_hash, sq_parens_id, 1, name);
131
+ }
122
132
  return fetch_by_index(obj, hash_lookup);
123
133
  }
124
134
 
@@ -131,10 +141,10 @@ static VALUE set_element(VALUE obj, VALUE name, VALUE val) {
131
141
  char col_name[16];
132
142
  ID col_id;
133
143
 
134
- if (REAL_HASH_EXISTS) return rb_hash_aset(rb_ivar_get(obj, real_hash_id), name, val);
144
+ if (REAL_HASH_EXISTS) return rb_funcall(rb_ivar_get(obj, real_hash_id), sq_parens_equal_id, 2, name, val);
135
145
 
136
146
  hash_lookup = rb_hash_aref(field_indexes, name);
137
- if (NIL_P(hash_lookup)) return rb_hash_aset(rb_funcall(obj, to_hash_id, 0), name, val);
147
+ if (NIL_P(hash_lookup)) return rb_funcall(rb_funcall(obj, to_hash_id, 0), sq_parens_equal_id, 2, name, val);
138
148
  col_number = FIX2LONG(hash_lookup);
139
149
  col_id = GET_COL_IV_ID(col_name, col_number);
140
150
  rb_ivar_set(obj, col_id, val);
@@ -159,7 +169,11 @@ static VALUE slim_dup(VALUE obj) {
159
169
 
160
170
  if (REAL_HASH_EXISTS) return rb_obj_dup(rb_ivar_get(obj, real_hash_id));
161
171
 
172
+ #ifdef RHASH_SIZE
173
+ nf = RHASH_SIZE(field_indexes);
174
+ #else
162
175
  nf = RHASH(field_indexes)->tbl->num_entries;
176
+ #endif
163
177
  row_info_space = ruby_xmalloc(nf); // dup needs its own set of flags
164
178
  if (!row_info_space) rb_raise(rb_eNoMemError, "out of memory");
165
179
  memcpy(row_info_space, GetCharPtr(rb_ivar_get(obj, row_info_id)), nf);
@@ -175,10 +189,20 @@ static VALUE slim_dup(VALUE obj) {
175
189
  // Calls to model property methods in AR cause a call to has_key?, so it
176
190
  // is implemented here in C for speed.
177
191
  static VALUE has_key(VALUE obj, VALUE name) {
178
- VALUE field_indexes;
192
+ VALUE field_indexes, real_hash;
179
193
 
194
+ #ifdef RHASH_TBL
195
+ if (REAL_HASH_EXISTS) return (st_lookup(RHASH_TBL(rb_ivar_get(obj, real_hash_id)), name, 0) ? Qtrue : Qfalse);
196
+ else if (st_lookup(RHASH_TBL(field_indexes), name, 0)) return Qtrue;
197
+ #else
180
198
  if (REAL_HASH_EXISTS) return (st_lookup(RHASH(rb_ivar_get(obj, real_hash_id))->tbl, name, 0) ? Qtrue : Qfalse);
181
- else return (st_lookup(RHASH(field_indexes)->tbl, name, 0) ? Qtrue : Qfalse);
199
+ else if (st_lookup(RHASH(field_indexes)->tbl, name, 0)) return Qtrue;
200
+ #endif
201
+ else {
202
+ real_hash = rb_ivar_get(obj, real_hash_id);
203
+ if (NIL_P(real_hash)) return Qfalse;
204
+ return rb_funcall(real_hash, has_key_id, 1, name);
205
+ }
182
206
  }
183
207
 
184
208
  void Init_slim_attrib_ext() {
@@ -196,13 +220,17 @@ void Init_slim_attrib_ext() {
196
220
  rb_define_method(cRowHash, "[]", (VALUE(*)(ANYARGS))slim_fetch, 1);
197
221
  rb_define_method(cRowHash, "[]=", (VALUE(*)(ANYARGS))set_element, 2);
198
222
  rb_define_method(cRowHash, "dup", (VALUE(*)(ANYARGS))slim_dup, 0);
199
- rb_define_method(cRowHash, "has_key?", (VALUE(*)(ANYARGS))has_key, 1);
223
+ rb_define_method(cRowHash, "has_key?", (VALUE(*)(ANYARGS))has_key, 1);
224
+
200
225
  // set up some symbols that we will need
201
226
  pointers_id = rb_intern("@pointers");
202
227
  row_info_id = rb_intern("@row_info");
203
228
  field_indexes_id = rb_intern("@field_indexes");
204
229
  real_hash_id = rb_intern("@real_hash");
205
230
  to_hash_id = rb_intern("to_hash");
231
+ sq_parens_id = rb_intern("[]");
232
+ sq_parens_equal_id = rb_intern("[]=");
233
+ has_key_id = rb_intern("has_key?");
206
234
  for(i=0; i < MAX_CACHED_COLUMN_IDS; i++) {
207
235
  sprintf(col_name, "@col_%d", i);
208
236
  column_ids[i] = rb_intern(col_name);
@@ -0,0 +1 @@
1
+ require 'slim_attributes'
@@ -9,6 +9,8 @@ require 'slim_attrib_ext'
9
9
 
10
10
  class Mysql::Result
11
11
  class RowHash
12
+ attr_accessor :real_hash
13
+
12
14
  def marshal_dump
13
15
  to_hash
14
16
  end
@@ -28,8 +30,8 @@ class Mysql::Result
28
30
  # This should be the exception though, and the efficiencies of using slim-attributes
29
31
  # are lost when this happens.
30
32
  def to_hash
31
- return @real_hash if @real_hash
32
- @real_hash = {}
33
+ return @real_hash unless @field_indexes
34
+ @real_hash ||= {}
33
35
  @field_indexes.each_pair {|name, index| @real_hash[name] = fetch_by_index(index)}
34
36
  @field_indexes = nil
35
37
  @real_hash
@@ -46,7 +48,7 @@ class Mysql::Result
46
48
  to_hash.freeze
47
49
  regular_freeze
48
50
  end
49
-
51
+
50
52
  def method_missing(name, *args, &block)
51
53
  to_hash.send(name, *args, &block)
52
54
  end
@@ -4,7 +4,7 @@
4
4
  require 'rubygems'
5
5
  require 'active_record'
6
6
  require 'active_record/version'
7
- require 'slim_attributes'
7
+ require File.dirname(__FILE__) + '/../lib/slim_attributes'
8
8
  require 'test/unit'
9
9
  require File.dirname(__FILE__) + "/products"
10
10
  require File.dirname(__FILE__) + "/slim_db_test_utils"
@@ -16,6 +16,11 @@ class SlimAttributesTest < Test::Unit::TestCase
16
16
  Product.make_some_products
17
17
  end
18
18
 
19
+ def test_slim_attributes_is_proxying_results
20
+ x = Product.find(:first)
21
+ assert_equal Mysql::Result::RowHash, x.instance_variable_get(:@attributes).class
22
+ end
23
+
19
24
  def test_finds_all
20
25
  items = Product.find(:all)
21
26
  assert items.size == 100, "must find all 100 items"
@@ -138,7 +143,10 @@ class SlimAttributesTest < Test::Unit::TestCase
138
143
  item1.name = "bar"
139
144
  assert_equal "product_0", item3.name, "name must be original from cached query"
140
145
  item2.name << "_test"
141
- # unmodified rails fails this test - but does it matter either way?
146
+ # unmodified rails fails this test because the attributes are not dupped, only the
147
+ # hash containing them is
148
+ # but this test is useful - it shows that the rowhash has not been made
149
+ # into a real hash before dup in called in the query cache code
142
150
  check_attributes_for(item3, 0)
143
151
  end
144
152
  end
@@ -149,7 +157,7 @@ class SlimAttributesTest < Test::Unit::TestCase
149
157
  item1.destroy # object is frozen
150
158
  assert_equal true, item1.frozen?
151
159
  check_attributes_for(item1, 0)
152
- assert_raises(TypeError) {item1.name = "another product"}
160
+ assert_raises(RUBY_VERSION >= "1.9" ? RuntimeError : TypeError) {item1.name = "another product"}
153
161
  end
154
162
 
155
163
  def teardown
@@ -163,7 +171,7 @@ class SlimAttributesTest < Test::Unit::TestCase
163
171
  assert_equal i, item.number, "item number must be right"
164
172
  assert_equal i + 1, item.id, "item id must be right"
165
173
  assert_equal "Made by the test suite", item.comment, "item comment must be right"
166
- assert ((1.minute.ago)..(Time.now)) === item.created_at, "item created_at must be reasonable"
174
+ assert item.created_at <= Time.now && item.created_at > Time.now - 30, "item created_at must be reasonable"
167
175
  assert_nil item.nil_test, "nil_test must be nil"
168
176
  end
169
177
  end
metadata CHANGED
@@ -1,7 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ghazel-slim-attributes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3.1
4
+ hash: 109
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 7
9
+ - 6
10
+ - 1
11
+ version: 0.7.6.1
5
12
  platform: ruby
6
13
  authors:
7
14
  - Stephen Sykes
@@ -9,11 +16,13 @@ autorequire:
9
16
  bindir: bin
10
17
  cert_chain: []
11
18
 
12
- date: 2009-07-12 00:00:00 -07:00
19
+ date: 2009-12-23 00:00:00 -08:00
13
20
  default_executable:
14
21
  dependencies: []
15
22
 
16
- description: Slim attributes boosts speed in Rails/Mysql ActiveRecord Models by avoiding instantiating Hashes for each result row, and lazily instantiating attributes as needed.
23
+ description: |-
24
+ Slim attributes boosts speed in Rails/Mysql ActiveRecord Models by avoiding
25
+ instantiating Hashes for each result row, and lazily instantiating attributes as needed.
17
26
  email: sdsykes@gmail.com
18
27
  executables: []
19
28
 
@@ -23,11 +32,12 @@ extra_rdoc_files:
23
32
  - README
24
33
  files:
25
34
  - MIT_LICENCE
26
- - Rakefile
27
35
  - README
36
+ - Rakefile
28
37
  - VERSION.yml
29
38
  - ext/extconf.rb
30
39
  - ext/slim_attrib_ext.c
40
+ - lib/slim-attributes.rb
31
41
  - lib/slim_attributes.rb
32
42
  - test/benchmark.rb
33
43
  - test/database.yml
@@ -36,30 +46,40 @@ files:
36
46
  - test/slim_db_test_utils.rb
37
47
  has_rdoc: true
38
48
  homepage: http://github.com/sdsykes/slim-attributes
49
+ licenses: []
50
+
39
51
  post_install_message:
40
52
  rdoc_options:
41
- - --inline-source
42
53
  - --charset=UTF-8
43
54
  require_paths:
44
55
  - lib
45
56
  required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
46
58
  requirements:
47
59
  - - ">="
48
60
  - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
49
64
  version: "0"
50
- version:
51
65
  required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
52
67
  requirements:
53
68
  - - ">="
54
69
  - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
55
73
  version: "0"
56
- version:
57
74
  requirements: []
58
75
 
59
- rubyforge_project:
60
- rubygems_version: 1.2.0
76
+ rubyforge_project: slim-attributes
77
+ rubygems_version: 1.3.7
61
78
  signing_key:
62
- specification_version: 2
79
+ specification_version: 3
63
80
  summary: Slim-attributes - lazy instantiation of attributes for ActiveRecord
64
- test_files: []
65
-
81
+ test_files:
82
+ - test/benchmark.rb
83
+ - test/products.rb
84
+ - test/slim_attributes_test.rb
85
+ - test/slim_db_test_utils.rb