panko_serializer 0.1.10 → 0.2.0

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.
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