panko_serializer 0.1.10 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21cd55b904edc40658adf9f43695d89e8962b2c5
4
- data.tar.gz: 664554f19ac39bca5e995e3fce1d50d2293e7ae2
3
+ metadata.gz: f657c0585ef9811fe8d9fcf0e2d1556869823b72
4
+ data.tar.gz: 9e4cc917aabb38d3b803e0978fc312b5fe5696da
5
5
  SHA512:
6
- metadata.gz: e4a4c7bd6d5e437ed52bb617dfa36b4970cd2274952df2870858f470bec00db243dd9fe1fd1b8bb163f42d51463ba41dce68f7a5d52a80803f0aa9d4dd0f9177
7
- data.tar.gz: d047bfc815bd8e092f0dceee0e2815a38e04d082157cf4fb873215e61a0f80a17e82ef793ce0665b22707da65779048bd6f0f66e6c465d82754b8d8890725303
6
+ metadata.gz: bd44b3774e47cbd74a400c53040f41bc9edb7f58c1dc63a1e7c530827b2c878948bdfebe6c0250c59ea5af122ef281113f09402fd282e4f16aff5d883ca5df8f
7
+ data.tar.gz: 3da4b8644375ed05481a7d9e00e27082ee5274eea06a60282395abe5aab06b90f0c17d4b525bcc4c44c08a5e48108f6cc725e9c6a6e85ee40c6c70b4f21e9102
data/.gitignore CHANGED
@@ -7,6 +7,7 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ /vendor/bundle/
10
11
 
11
12
  # rspec failure tracking
12
13
  .rspec_status
data/.travis.yml CHANGED
@@ -2,7 +2,13 @@ sudo: false
2
2
  cache: bundler
3
3
  language: ruby
4
4
  rvm:
5
- - 2.4.1
6
- - ruby-head
5
+ - 2.4.2
6
+ install: bundle install --path=vendor/bundle --retry=3 --jobs=3
7
7
  before_install: gem install bundler
8
8
  after_success: bundle exec rake benchmarks
9
+
10
+ env:
11
+ matrix:
12
+ - "RAILS_VERSION=4.2"
13
+ - "RAILS_VERSION=5.0"
14
+ - "RAILS_VERSION=5.1"
data/Gemfile CHANGED
@@ -3,15 +3,14 @@ source "https://rubygems.org"
3
3
 
4
4
  gemspec
5
5
 
6
- version = "4.2"
7
- gem_version = "~> #{version}.9"
8
-
9
- gem "rails", gem_version
10
- gem "railties", gem_version
11
- gem "activesupport", gem_version
12
- gem "activemodel", gem_version
13
- gem "actionpack", gem_version
14
- gem "activerecord", gem_version, group: :test
6
+ rails_version = "~> #{ENV.fetch("RAILS_VERSION", "4.2")}"
7
+
8
+ gem "rails", rails_version
9
+ gem "railties", rails_version
10
+ gem "activesupport", rails_version
11
+ gem "activemodel", rails_version
12
+ gem "actionpack", rails_version
13
+ gem "activerecord", rails_version, group: :test
15
14
 
16
15
  group :benchmarks do
17
16
  gem "sqlite3"
@@ -3,14 +3,27 @@ require_relative "./support"
3
3
 
4
4
  def ar_type_convert(type_klass, from, to)
5
5
  converter = type_klass.new
6
- assert type_klass.name, converter.type_cast_from_database(from), to
7
6
 
8
- Benchmark.run("#{type_klass.name}_TypeCast") do
9
- converter.type_cast_from_database(from)
10
- end
7
+ if ENV["RAILS_VERSION"].start_with? "4.2"
8
+ assert type_klass.name, converter.type_cast_from_database(from), to
9
+
10
+ Benchmark.run("#{type_klass.name}_TypeCast") do
11
+ converter.type_cast_from_database(from)
12
+ end
13
+
14
+ Benchmark.run("#{type_klass.name}_NoTypeCast") do
15
+ converter.type_cast_from_database(to)
16
+ end
17
+ else
18
+ assert type_klass.name, converter.deserialize(from), to
11
19
 
12
- Benchmark.run("#{type_klass.name}_NoTypeCast") do
13
- converter.type_cast_from_database(to)
20
+ Benchmark.run("#{type_klass.name}_TypeCast") do
21
+ converter.deserialize(from)
22
+ end
23
+
24
+ Benchmark.run("#{type_klass.name}_NoTypeCast") do
25
+ converter.deserialize(to)
26
+ end
14
27
  end
15
28
  end
16
29
 
@@ -22,8 +35,14 @@ def utc_ar_time
22
35
  type = ActiveRecord::ConnectionAdapters::PostgreSQL::OID::DateTime.new
23
36
  converter = ActiveRecord::AttributeMethods::TimeZoneConversion::TimeZoneConverter.new(type)
24
37
 
25
- Benchmark.run("#{tz}_#{type.class.name}_TypeCast") do
26
- converter.type_cast_from_database(from).iso8601
38
+ if ENV["RAILS_VERSION"].start_with? "4.2"
39
+ Benchmark.run("#{tz}_#{type.class.name}_TypeCast") do
40
+ converter.type_cast_from_database(from).iso8601
41
+ end
42
+ else
43
+ Benchmark.run("#{tz}_#{type.class.name}_TypeCast") do
44
+ converter.deserialize(from).iso8601
45
+ end
27
46
  end
28
47
  end
29
48
 
@@ -35,8 +54,15 @@ def db_ar_time
35
54
 
36
55
  from = "2017-07-10 09:26:40.937392"
37
56
 
38
- Benchmark.run("ActiveRecord_Time_TypeCast_WithISO8601") do
39
- converter.type_cast_from_database(from).iso8601
57
+
58
+ if ENV["RAILS_VERSION"].start_with? "4.2"
59
+ Benchmark.run("ActiveRecord_Time_TypeCast_WithISO8601") do
60
+ converter.type_cast_from_database(from).iso8601
61
+ end
62
+ else
63
+ Benchmark.run("ActiveRecord_Time_TypeCast_WithISO8601") do
64
+ converter.deserialize(from).iso8601
65
+ end
40
66
  end
41
67
  end
42
68
 
@@ -48,9 +74,11 @@ ar_type_convert ActiveRecord::Type::Float, "Infinity", 0.0
48
74
  ar_type_convert ActiveRecord::Type::Boolean, "true", true
49
75
  ar_type_convert ActiveRecord::Type::Boolean, "t", true
50
76
 
51
- ar_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer, "1", 1
52
- ar_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float, "1.23", 1.23
53
- ar_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float, "Infinity", ::Float::INFINITY
77
+ if ENV["RAILS_VERSION"].start_with? "4.2"
78
+ ar_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer, "1", 1
79
+ ar_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float, "1.23", 1.23
80
+ ar_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float, "Infinity", ::Float::INFINITY
81
+ end
54
82
  ar_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Json, '{"a":1}', {a:1}
55
83
 
56
84
  db_ar_time
@@ -44,6 +44,9 @@ def db_panko_time
44
44
  Panko::_type_cast(converter, from)
45
45
  end
46
46
  end
47
+ panko_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Json, '{"a":1}', {a:1}
48
+ db_panko_time
49
+ utc_panko_time
47
50
 
48
51
  panko_type_convert ActiveRecord::Type::String, 1, "1"
49
52
  panko_type_convert ActiveRecord::Type::Text, 1, "1"
@@ -53,9 +56,11 @@ panko_type_convert ActiveRecord::Type::Float, "Infinity", ::Float::INFINITY
53
56
  panko_type_convert ActiveRecord::Type::Boolean, "true", true
54
57
  panko_type_convert ActiveRecord::Type::Boolean, "t", true
55
58
 
56
- panko_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer, "1", 1
57
- panko_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float, "1.23", 1.23
58
- panko_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float, "Infinity", ::Float::INFINITY
59
+ if ENV["RAILS_VERSION"].start_with? "4.2"
60
+ panko_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer, "1", 1
61
+ panko_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float, "1.23", 1.23
62
+ panko_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float, "Infinity", ::Float::INFINITY
63
+ end
59
64
 
60
65
  panko_type_convert ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Json, '{"a":1}', {a:1}
61
66
  db_panko_time
@@ -14,19 +14,15 @@ VALUE read_attributes(VALUE obj) {
14
14
  }
15
15
 
16
16
  VALUE panko_read_lazy_attributes_hash(VALUE object) {
17
- volatile VALUE attributes_set, attributes_hash;
17
+ volatile VALUE attributes_set, lazy_attributes_hash;
18
18
 
19
19
  attributes_set = read_attributes(object);
20
20
  if (attributes_set == Qnil) {
21
21
  return Qnil;
22
22
  }
23
23
 
24
- attributes_hash = read_attributes(attributes_set);
25
- if (attributes_hash == Qnil) {
26
- return Qnil;
27
- }
28
-
29
- return attributes_hash;
24
+ lazy_attributes_hash = read_attributes(attributes_set);
25
+ return lazy_attributes_hash;
30
26
  }
31
27
 
32
28
  void panko_read_types_and_value(VALUE attributes_hash,
@@ -38,28 +34,60 @@ void panko_read_types_and_value(VALUE attributes_hash,
38
34
  *values = rb_ivar_get(attributes_hash, values_id);
39
35
  }
40
36
 
37
+ bool panko_is_empty_hash(VALUE hash) {
38
+ if (hash == Qnil || hash == Qundef) {
39
+ return true;
40
+ }
41
+
42
+ return RHASH_SIZE(hash) == 0;
43
+ }
44
+
45
+ void read_attribute_from_hash(VALUE attributes_hash,
46
+ VALUE member,
47
+ volatile VALUE* value,
48
+ volatile VALUE* type) {
49
+ volatile VALUE attribute_metadata = rb_hash_aref(attributes_hash, member);
50
+ if (attribute_metadata != Qnil) {
51
+ *value = rb_ivar_get(attribute_metadata, value_before_type_cast_id);
52
+ *type = rb_ivar_get(attribute_metadata, type_id);
53
+ }
54
+ }
55
+
41
56
  VALUE panko_each_attribute(VALUE obj,
42
57
  VALUE attributes,
43
58
  VALUE aliases,
44
59
  EachAttributeFunc func,
45
60
  VALUE context) {
46
- volatile VALUE attributes_hash, delegate_hash;
61
+ volatile VALUE lazy_attribute_hash, delegate_hash;
62
+ VALUE values = Qundef;
63
+ VALUE types = Qundef;
64
+ VALUE additional_types = Qundef;
47
65
  int i;
48
66
 
49
- attributes_hash = panko_read_lazy_attributes_hash(obj);
50
- if (attributes_hash == Qnil) {
67
+ lazy_attribute_hash = panko_read_lazy_attributes_hash(obj);
68
+ if (lazy_attribute_hash == Qnil) {
51
69
  return Qnil;
52
70
  }
53
71
 
54
- delegate_hash = rb_ivar_get(attributes_hash, delegate_hash_id);
55
- bool tryToReadFromDelegateHash = RHASH_SIZE(delegate_hash) > 0;
72
+ bool tryToReadFromDelegateHash = false;
73
+ bool tryToReadFromAdditionalTypes = false;
56
74
 
57
- VALUE types, additional_types, values;
58
- panko_read_types_and_value(attributes_hash, &types, &additional_types,
59
- &values);
60
- bool tryToReadFromAdditionalTypes = RHASH_SIZE(additional_types) > 0;
75
+ // If lazy_attribute_hash is not ActiveRecord::LazyAttributeHash
76
+ // and it's actually hash, read from it
77
+ if (RB_TYPE_P(lazy_attribute_hash, T_HASH)) {
78
+ delegate_hash = lazy_attribute_hash;
79
+ tryToReadFromDelegateHash = true;
80
+ } else {
81
+ delegate_hash = rb_ivar_get(lazy_attribute_hash, delegate_hash_id);
82
+ tryToReadFromDelegateHash = !panko_is_empty_hash(delegate_hash);
61
83
 
62
- bool tryToReadFromAliases = RHASH_SIZE(aliases) > 0;
84
+ panko_read_types_and_value(lazy_attribute_hash, &types, &additional_types,
85
+ &values);
86
+
87
+ tryToReadFromAdditionalTypes = !panko_is_empty_hash(additional_types);
88
+ }
89
+
90
+ bool tryToReadFromAliases = !panko_is_empty_hash(aliases);
63
91
 
64
92
  for (i = 0; i < RARRAY_LEN(attributes); i++) {
65
93
  volatile VALUE member_raw = RARRAY_AREF(attributes, i);
@@ -72,14 +100,10 @@ VALUE panko_each_attribute(VALUE obj,
72
100
  // If the object was create in memory `User.new(name: "Yosi")`
73
101
  // it won't exist in types/values
74
102
  if (tryToReadFromDelegateHash) {
75
- volatile VALUE attribute_metadata = rb_hash_aref(delegate_hash, member);
76
- if (attribute_metadata != Qnil) {
77
- value = rb_ivar_get(attribute_metadata, value_before_type_cast_id);
78
- type_metadata = rb_ivar_get(attribute_metadata, type_id);
79
- }
103
+ read_attribute_from_hash(delegate_hash, member, &value, &type_metadata);
80
104
  }
81
105
 
82
- if (value == Qundef) {
106
+ if (values != Qundef && value == Qundef) {
83
107
  value = rb_hash_aref(values, member);
84
108
 
85
109
  if (tryToReadFromAdditionalTypes) {
@@ -90,9 +114,9 @@ VALUE panko_each_attribute(VALUE obj,
90
114
  }
91
115
  }
92
116
 
93
- if(tryToReadFromAliases) {
117
+ if (tryToReadFromAliases) {
94
118
  volatile VALUE alias_name = rb_hash_aref(aliases, member_raw);
95
- if(alias_name != Qnil) {
119
+ if (alias_name != Qnil) {
96
120
  member = rb_sym2str(alias_name);
97
121
  }
98
122
  }
@@ -1,7 +1,7 @@
1
1
  #include "type_cast.h"
2
2
  #include "time_conversion.h"
3
3
 
4
- ID type_cast_from_database_id = 0;
4
+ ID deserialize_from_db_id = 0;
5
5
  ID to_s_id = 0;
6
6
  ID to_i_id = 0;
7
7
 
@@ -79,7 +79,7 @@ void cache_type_lookup() {
79
79
 
80
80
  initiailized = 1;
81
81
 
82
- VALUE ar, ar_type;
82
+ VALUE ar, ar_type, ar_type_methods;
83
83
 
84
84
  ar = rb_const_get_at(rb_cObject, rb_intern("ActiveRecord"));
85
85
 
@@ -93,6 +93,13 @@ void cache_type_lookup() {
93
93
  ar_boolean_type = rb_const_get_at(ar_type, rb_intern("Boolean"));
94
94
  ar_date_time_type = rb_const_get_at(ar_type, rb_intern("DateTime"));
95
95
 
96
+ ar_type_methods = rb_class_instance_methods(0, NULL, ar_string_type);
97
+ if(rb_ary_includes(ar_type_methods, rb_to_symbol(rb_str_new_cstr("deserialize")))) {
98
+ deserialize_from_db_id = rb_intern("deserialize");
99
+ } else {
100
+ deserialize_from_db_id = rb_intern("type_cast_from_database");
101
+ }
102
+
96
103
  // TODO: if we get error or not, add this to some debug log
97
104
  int isErrored;
98
105
  rb_protect(cache_postgres_type_lookup, ar, &isErrored);
@@ -241,7 +248,7 @@ VALUE cast_date_time_type(VALUE value) {
241
248
  }
242
249
 
243
250
  VALUE type_cast(VALUE type_metadata, VALUE value) {
244
- if(value == Qnil || value == Qundef) {
251
+ if (value == Qnil || value == Qundef) {
245
252
  return value;
246
253
  }
247
254
 
@@ -261,7 +268,7 @@ VALUE type_cast(VALUE type_metadata, VALUE value) {
261
268
  }
262
269
 
263
270
  if (typeCastedValue == Qundef) {
264
- return rb_funcall(type_metadata, type_cast_from_database_id, 1, value);
271
+ return rb_funcall(type_metadata, deserialize_from_db_id, 1, value);
265
272
  }
266
273
 
267
274
  return typeCastedValue;
@@ -272,7 +279,6 @@ VALUE public_type_cast(VALUE module, VALUE type_metadata, VALUE value) {
272
279
  }
273
280
 
274
281
  void panko_init_type_cast(VALUE mPanko) {
275
- type_cast_from_database_id = rb_intern_const("type_cast_from_database");
276
282
  to_s_id = rb_intern_const("to_s");
277
283
  to_i_id = rb_intern_const("to_i");
278
284
 
data/lib/panko/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Panko
3
- VERSION = "0.1.10"
3
+ VERSION = "0.2.0"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: panko_serializer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yosi Attias
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-14 00:00:00.000000000 Z
11
+ date: 2017-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler