ar_protobuf_store 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,124 @@
1
+ PATH
2
+ remote: ../
3
+ specs:
4
+ ar_protobuf_store (0.1.0)
5
+ activerecord (>= 3.0, <= 4.1.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionmailer (4.1.1)
11
+ actionpack (= 4.1.1)
12
+ actionview (= 4.1.1)
13
+ mail (~> 2.5.4)
14
+ actionpack (4.1.1)
15
+ actionview (= 4.1.1)
16
+ activesupport (= 4.1.1)
17
+ rack (~> 1.5.2)
18
+ rack-test (~> 0.6.2)
19
+ actionview (4.1.1)
20
+ activesupport (= 4.1.1)
21
+ builder (~> 3.1)
22
+ erubis (~> 2.7.0)
23
+ activemodel (4.1.1)
24
+ activesupport (= 4.1.1)
25
+ builder (~> 3.1)
26
+ activerecord (4.1.1)
27
+ activemodel (= 4.1.1)
28
+ activesupport (= 4.1.1)
29
+ arel (~> 5.0.0)
30
+ activesupport (4.1.1)
31
+ i18n (~> 0.6, >= 0.6.9)
32
+ json (~> 1.7, >= 1.7.7)
33
+ minitest (~> 5.1)
34
+ thread_safe (~> 0.1)
35
+ tzinfo (~> 1.1)
36
+ appraisal (1.0.0)
37
+ bundler
38
+ rake
39
+ thor (>= 0.14.0)
40
+ arel (5.0.1.20140414130214)
41
+ builder (3.2.2)
42
+ coderay (1.1.0)
43
+ diff-lcs (1.2.5)
44
+ erubis (2.7.0)
45
+ hike (1.2.3)
46
+ i18n (0.6.9)
47
+ json (1.8.1)
48
+ mail (2.5.4)
49
+ mime-types (~> 1.16)
50
+ treetop (~> 1.4.8)
51
+ method_source (0.8.2)
52
+ mime-types (1.25.1)
53
+ minitest (5.3.4)
54
+ multi_json (1.10.1)
55
+ polyglot (0.3.4)
56
+ pry (0.9.12.6)
57
+ coderay (~> 1.0)
58
+ method_source (~> 0.8)
59
+ slop (~> 3.4)
60
+ rack (1.5.2)
61
+ rack-test (0.6.2)
62
+ rack (>= 1.0)
63
+ rails (4.1.1)
64
+ actionmailer (= 4.1.1)
65
+ actionpack (= 4.1.1)
66
+ actionview (= 4.1.1)
67
+ activemodel (= 4.1.1)
68
+ activerecord (= 4.1.1)
69
+ activesupport (= 4.1.1)
70
+ bundler (>= 1.3.0, < 2.0)
71
+ railties (= 4.1.1)
72
+ sprockets-rails (~> 2.0)
73
+ railties (4.1.1)
74
+ actionpack (= 4.1.1)
75
+ activesupport (= 4.1.1)
76
+ rake (>= 0.8.7)
77
+ thor (>= 0.18.1, < 2.0)
78
+ rake (10.3.2)
79
+ rspec (2.14.1)
80
+ rspec-core (~> 2.14.0)
81
+ rspec-expectations (~> 2.14.0)
82
+ rspec-mocks (~> 2.14.0)
83
+ rspec-core (2.14.8)
84
+ rspec-expectations (2.14.5)
85
+ diff-lcs (>= 1.1.3, < 2.0)
86
+ rspec-mocks (2.14.6)
87
+ ruby-protocol-buffers (1.5.1)
88
+ ruby_protobuf (0.4.11)
89
+ rubygems-tasks (0.2.4)
90
+ slop (3.5.0)
91
+ sprockets (2.12.1)
92
+ hike (~> 1.2)
93
+ multi_json (~> 1.0)
94
+ rack (~> 1.0)
95
+ tilt (~> 1.1, != 1.3.0)
96
+ sprockets-rails (2.1.3)
97
+ actionpack (>= 3.0)
98
+ activesupport (>= 3.0)
99
+ sprockets (~> 2.8)
100
+ sqlite3 (1.3.9)
101
+ thor (0.19.1)
102
+ thread_safe (0.3.3)
103
+ tilt (1.4.1)
104
+ treetop (1.4.15)
105
+ polyglot
106
+ polyglot (>= 0.3.1)
107
+ tzinfo (1.1.0)
108
+ thread_safe (~> 0.1)
109
+ yard (0.8.7.4)
110
+
111
+ PLATFORMS
112
+ ruby
113
+
114
+ DEPENDENCIES
115
+ appraisal (~> 1.0.0)
116
+ ar_protobuf_store!
117
+ pry (~> 0.9)
118
+ rails (~> 4.0)
119
+ rspec (~> 2.4)
120
+ ruby-protocol-buffers (~> 1.5)
121
+ ruby_protobuf (~> 0.4)
122
+ rubygems-tasks (~> 0.2)
123
+ sqlite3 (~> 1.3)
124
+ yard (~> 0.8)
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 4.1"
6
+ gem "protobuf", "~> 3.0"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,129 @@
1
+ PATH
2
+ remote: ../
3
+ specs:
4
+ ar_protobuf_store (0.1.0)
5
+ activerecord (>= 3.0, <= 4.1.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionmailer (4.1.1)
11
+ actionpack (= 4.1.1)
12
+ actionview (= 4.1.1)
13
+ mail (~> 2.5.4)
14
+ actionpack (4.1.1)
15
+ actionview (= 4.1.1)
16
+ activesupport (= 4.1.1)
17
+ rack (~> 1.5.2)
18
+ rack-test (~> 0.6.2)
19
+ actionview (4.1.1)
20
+ activesupport (= 4.1.1)
21
+ builder (~> 3.1)
22
+ erubis (~> 2.7.0)
23
+ activemodel (4.1.1)
24
+ activesupport (= 4.1.1)
25
+ builder (~> 3.1)
26
+ activerecord (4.1.1)
27
+ activemodel (= 4.1.1)
28
+ activesupport (= 4.1.1)
29
+ arel (~> 5.0.0)
30
+ activesupport (4.1.1)
31
+ i18n (~> 0.6, >= 0.6.9)
32
+ json (~> 1.7, >= 1.7.7)
33
+ minitest (~> 5.1)
34
+ thread_safe (~> 0.1)
35
+ tzinfo (~> 1.1)
36
+ appraisal (1.0.0)
37
+ bundler
38
+ rake
39
+ thor (>= 0.14.0)
40
+ arel (5.0.1.20140414130214)
41
+ builder (3.2.2)
42
+ coderay (1.1.0)
43
+ diff-lcs (1.2.5)
44
+ erubis (2.7.0)
45
+ hike (1.2.3)
46
+ i18n (0.6.9)
47
+ json (1.8.1)
48
+ mail (2.5.4)
49
+ mime-types (~> 1.16)
50
+ treetop (~> 1.4.8)
51
+ method_source (0.8.2)
52
+ middleware (0.1.0)
53
+ mime-types (1.25.1)
54
+ minitest (5.3.4)
55
+ multi_json (1.10.1)
56
+ polyglot (0.3.4)
57
+ protobuf (3.0.4)
58
+ activesupport (>= 3.2)
59
+ middleware
60
+ multi_json
61
+ thor
62
+ pry (0.9.12.6)
63
+ coderay (~> 1.0)
64
+ method_source (~> 0.8)
65
+ slop (~> 3.4)
66
+ rack (1.5.2)
67
+ rack-test (0.6.2)
68
+ rack (>= 1.0)
69
+ rails (4.1.1)
70
+ actionmailer (= 4.1.1)
71
+ actionpack (= 4.1.1)
72
+ actionview (= 4.1.1)
73
+ activemodel (= 4.1.1)
74
+ activerecord (= 4.1.1)
75
+ activesupport (= 4.1.1)
76
+ bundler (>= 1.3.0, < 2.0)
77
+ railties (= 4.1.1)
78
+ sprockets-rails (~> 2.0)
79
+ railties (4.1.1)
80
+ actionpack (= 4.1.1)
81
+ activesupport (= 4.1.1)
82
+ rake (>= 0.8.7)
83
+ thor (>= 0.18.1, < 2.0)
84
+ rake (10.3.2)
85
+ rspec (2.14.1)
86
+ rspec-core (~> 2.14.0)
87
+ rspec-expectations (~> 2.14.0)
88
+ rspec-mocks (~> 2.14.0)
89
+ rspec-core (2.14.8)
90
+ rspec-expectations (2.14.5)
91
+ diff-lcs (>= 1.1.3, < 2.0)
92
+ rspec-mocks (2.14.6)
93
+ ruby-protocol-buffers (1.5.1)
94
+ rubygems-tasks (0.2.4)
95
+ slop (3.5.0)
96
+ sprockets (2.12.1)
97
+ hike (~> 1.2)
98
+ multi_json (~> 1.0)
99
+ rack (~> 1.0)
100
+ tilt (~> 1.1, != 1.3.0)
101
+ sprockets-rails (2.1.3)
102
+ actionpack (>= 3.0)
103
+ activesupport (>= 3.0)
104
+ sprockets (~> 2.8)
105
+ sqlite3 (1.3.9)
106
+ thor (0.19.1)
107
+ thread_safe (0.3.3)
108
+ tilt (1.4.1)
109
+ treetop (1.4.15)
110
+ polyglot
111
+ polyglot (>= 0.3.1)
112
+ tzinfo (1.1.0)
113
+ thread_safe (~> 0.1)
114
+ yard (0.8.7.4)
115
+
116
+ PLATFORMS
117
+ ruby
118
+
119
+ DEPENDENCIES
120
+ appraisal (~> 1.0.0)
121
+ ar_protobuf_store!
122
+ protobuf (~> 3.0)
123
+ pry (~> 0.9)
124
+ rails (~> 4.1)
125
+ rspec (~> 2.4)
126
+ ruby-protocol-buffers (~> 1.5)
127
+ rubygems-tasks (~> 0.2)
128
+ sqlite3 (~> 1.3)
129
+ yard (~> 0.8)
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "rails", "~> 4.1"
6
+ gem "ruby_protobuf", "~> 0.4"
7
+
8
+ gemspec :path => "../"
@@ -0,0 +1,124 @@
1
+ PATH
2
+ remote: ../
3
+ specs:
4
+ ar_protobuf_store (0.1.0)
5
+ activerecord (>= 3.0, <= 4.1.1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionmailer (4.1.1)
11
+ actionpack (= 4.1.1)
12
+ actionview (= 4.1.1)
13
+ mail (~> 2.5.4)
14
+ actionpack (4.1.1)
15
+ actionview (= 4.1.1)
16
+ activesupport (= 4.1.1)
17
+ rack (~> 1.5.2)
18
+ rack-test (~> 0.6.2)
19
+ actionview (4.1.1)
20
+ activesupport (= 4.1.1)
21
+ builder (~> 3.1)
22
+ erubis (~> 2.7.0)
23
+ activemodel (4.1.1)
24
+ activesupport (= 4.1.1)
25
+ builder (~> 3.1)
26
+ activerecord (4.1.1)
27
+ activemodel (= 4.1.1)
28
+ activesupport (= 4.1.1)
29
+ arel (~> 5.0.0)
30
+ activesupport (4.1.1)
31
+ i18n (~> 0.6, >= 0.6.9)
32
+ json (~> 1.7, >= 1.7.7)
33
+ minitest (~> 5.1)
34
+ thread_safe (~> 0.1)
35
+ tzinfo (~> 1.1)
36
+ appraisal (1.0.0)
37
+ bundler
38
+ rake
39
+ thor (>= 0.14.0)
40
+ arel (5.0.1.20140414130214)
41
+ builder (3.2.2)
42
+ coderay (1.1.0)
43
+ diff-lcs (1.2.5)
44
+ erubis (2.7.0)
45
+ hike (1.2.3)
46
+ i18n (0.6.9)
47
+ json (1.8.1)
48
+ mail (2.5.4)
49
+ mime-types (~> 1.16)
50
+ treetop (~> 1.4.8)
51
+ method_source (0.8.2)
52
+ mime-types (1.25.1)
53
+ minitest (5.3.4)
54
+ multi_json (1.10.1)
55
+ polyglot (0.3.4)
56
+ pry (0.9.12.6)
57
+ coderay (~> 1.0)
58
+ method_source (~> 0.8)
59
+ slop (~> 3.4)
60
+ rack (1.5.2)
61
+ rack-test (0.6.2)
62
+ rack (>= 1.0)
63
+ rails (4.1.1)
64
+ actionmailer (= 4.1.1)
65
+ actionpack (= 4.1.1)
66
+ actionview (= 4.1.1)
67
+ activemodel (= 4.1.1)
68
+ activerecord (= 4.1.1)
69
+ activesupport (= 4.1.1)
70
+ bundler (>= 1.3.0, < 2.0)
71
+ railties (= 4.1.1)
72
+ sprockets-rails (~> 2.0)
73
+ railties (4.1.1)
74
+ actionpack (= 4.1.1)
75
+ activesupport (= 4.1.1)
76
+ rake (>= 0.8.7)
77
+ thor (>= 0.18.1, < 2.0)
78
+ rake (10.3.2)
79
+ rspec (2.14.1)
80
+ rspec-core (~> 2.14.0)
81
+ rspec-expectations (~> 2.14.0)
82
+ rspec-mocks (~> 2.14.0)
83
+ rspec-core (2.14.8)
84
+ rspec-expectations (2.14.5)
85
+ diff-lcs (>= 1.1.3, < 2.0)
86
+ rspec-mocks (2.14.6)
87
+ ruby-protocol-buffers (1.5.1)
88
+ ruby_protobuf (0.4.11)
89
+ rubygems-tasks (0.2.4)
90
+ slop (3.5.0)
91
+ sprockets (2.12.1)
92
+ hike (~> 1.2)
93
+ multi_json (~> 1.0)
94
+ rack (~> 1.0)
95
+ tilt (~> 1.1, != 1.3.0)
96
+ sprockets-rails (2.1.3)
97
+ actionpack (>= 3.0)
98
+ activesupport (>= 3.0)
99
+ sprockets (~> 2.8)
100
+ sqlite3 (1.3.9)
101
+ thor (0.19.1)
102
+ thread_safe (0.3.3)
103
+ tilt (1.4.1)
104
+ treetop (1.4.15)
105
+ polyglot
106
+ polyglot (>= 0.3.1)
107
+ tzinfo (1.1.0)
108
+ thread_safe (~> 0.1)
109
+ yard (0.8.7.4)
110
+
111
+ PLATFORMS
112
+ ruby
113
+
114
+ DEPENDENCIES
115
+ appraisal (~> 1.0.0)
116
+ ar_protobuf_store!
117
+ pry (~> 0.9)
118
+ rails (~> 4.1)
119
+ rspec (~> 2.4)
120
+ ruby-protocol-buffers (~> 1.5)
121
+ ruby_protobuf (~> 0.4)
122
+ rubygems-tasks (~> 0.2)
123
+ sqlite3 (~> 1.3)
124
+ yard (~> 0.8)
@@ -0,0 +1,67 @@
1
+ module ArProtobufStore
2
+ class CodekitchenProtobufParser
3
+ def initialize(pb_class, opts = nil)
4
+ @klass = pb_class
5
+ @opts = opts
6
+ @opts ||= { :default => Proc.new { pb_class.new() } }
7
+ end
8
+
9
+ def load(str)
10
+ if str.nil?
11
+ return default_value
12
+ else
13
+ return @klass.new.tap { |o| o.parse(str) }
14
+ end
15
+ rescue Exception
16
+ if defined?(Rails)
17
+ Rails.logger.error("Failed to deserialize: #{$!}")
18
+ else
19
+ puts "Failed to deserialize: #{$!}"
20
+ end
21
+
22
+ return default_value
23
+ end
24
+
25
+ def dump(str)
26
+ str.serialize_to_string
27
+ end
28
+
29
+ def extract_fields(accessors = nil)
30
+ fields = @klass.fields.values
31
+
32
+ if !accessors.nil?
33
+ accessors = accessors.dup.map { |a| a.to_s }
34
+ fields = fields.select { |field|
35
+ accessors.include?(field.name.to_s)
36
+ }
37
+ end
38
+
39
+ typed_fields = fields.map do |field|
40
+ t = case field
41
+ when ProtocolBuffers::Field::StringField
42
+ :string
43
+ when ProtocolBuffers::Field::VarintField
44
+ :int
45
+ when ProtocolBuffers::Field::FloatField, ProtocolBuffers::Field::DoubleField
46
+ :float
47
+ else
48
+ nil
49
+ end
50
+ { :name => field.name.to_s, :type => t }
51
+ end
52
+
53
+ return typed_fields
54
+ end
55
+
56
+ private
57
+ def default_value
58
+ if @opts[:default].respond_to? :call
59
+ @opts[:default].call
60
+ elsif @opts[:default].duplicable?
61
+ @opts[:default].dup
62
+ else
63
+ @opts[:default]
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,68 @@
1
+ module ArProtobufStore
2
+ class ProtobufParser
3
+ def initialize(pb_class, opts = nil)
4
+ @klass = pb_class
5
+ @opts = opts
6
+ @opts ||= { :default => Proc.new { pb_class.new() } }
7
+ end
8
+
9
+ def load(str)
10
+ if str.nil?
11
+ return default_value
12
+ else
13
+ return @klass.new.tap { |o| o.parse_from_string(str) }
14
+ end
15
+ rescue Exception
16
+ if defined?(Rails)
17
+ Rails.logger.error("Failed to deserialize: #{$!}")
18
+ else
19
+ puts "Failed to deserialize: #{$!}"
20
+ end
21
+
22
+ return default_value
23
+ end
24
+
25
+ def dump(str)
26
+ str.serialize_to_string
27
+ end
28
+
29
+ def extract_fields(accessors = nil)
30
+ fields = @klass.fields
31
+ fields = fields.values if fields.respond_to?(:values)
32
+
33
+ if !accessors.nil?
34
+ accessors = accessors.dup.map { |a| a.to_s }
35
+ fields = fields.select { |field|
36
+ accessors.include?(field.name.to_s)
37
+ }
38
+ end
39
+
40
+ typed_fields = fields.map do |field|
41
+ t = case field
42
+ when Protobuf::Field::StringField
43
+ :string
44
+ when Protobuf::Field::VarintField
45
+ :int
46
+ when Protobuf::Field::FloatField
47
+ :float
48
+ else
49
+ nil
50
+ end
51
+ { :name => field.name.to_s, :type => t }
52
+ end
53
+
54
+ return typed_fields
55
+ end
56
+
57
+ private
58
+ def default_value
59
+ if @opts[:default].respond_to? :call
60
+ @opts[:default].call
61
+ elsif @opts[:default].duplicable?
62
+ @opts[:default].dup
63
+ else
64
+ @opts[:default]
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,12 @@
1
+ require 'ar_protobuf_store'
2
+ require 'rails'
3
+
4
+ module ArProtobufStore
5
+ class Railtie < ::Rails::Railtie
6
+ initializer "ar_protobuf_store.active_record" do |app|
7
+ ActiveSupport.on_load :active_record do
8
+ Ar::Base.send :include, ArProtobufStore
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,4 @@
1
+ module ArProtobufStore
2
+ # ar_protobuf_store version
3
+ VERSION = "0.1.0"
4
+ end
@@ -0,0 +1,57 @@
1
+ require 'ar_protobuf_store/version'
2
+
3
+ require 'ar_protobuf_store/railtie.rb' if defined?(Rails)
4
+
5
+ module ArProtobufStore
6
+ autoload(:CodekitchenProtobufParser,
7
+ "ar_protobuf_store/codekitchen_protobuf_parser")
8
+ autoload(:ProtobufParser,
9
+ "ar_protobuf_store/protobuf_parser")
10
+
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ end
14
+
15
+ def self.find_parser!(pb_class)
16
+ if defined?(ProtocolBuffers) && ::ProtocolBuffers::Message > pb_class
17
+ return ArProtobufStore::CodekitchenProtobufParser.new(pb_class)
18
+ elsif defined?(Protobuf) && ::Protobuf::Message > pb_class
19
+ return ArProtobufStore::ProtobufParser.new(pb_class)
20
+ else
21
+ raise "Could not identify protocol buffer library for #{pb_class}"
22
+ end
23
+ end
24
+
25
+ module ClassMethods
26
+ def protobuf_store(store_attribute, pb_class, options={})
27
+ parser = ArProtobufStore.find_parser!(pb_class)
28
+ serialize(store_attribute, parser)
29
+ protobuf_store_accessor(store_attribute, parser.extract_fields(options[:accessors]))
30
+ end
31
+
32
+ def protobuf_store_accessor(store_attribute, *keys)
33
+ Array(keys).flatten.each do |key|
34
+ name = key[:name]
35
+ coercer = case key[:type]
36
+ when :int
37
+ ".to_i"
38
+ when :float
39
+ ".to_f"
40
+ when :string
41
+ ".to_s"
42
+ else
43
+ ""
44
+ end
45
+ class_eval <<-"END_EVAL", __FILE__, __LINE__
46
+ def #{name}=(value)
47
+ self.#{store_attribute}_will_change!
48
+ self.#{store_attribute}.#{name} = value#{coercer}
49
+ end
50
+ def #{name}
51
+ self.#{store_attribute}.#{name}
52
+ end
53
+ END_EVAL
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+ require 'ar_protobuf_store'
3
+ require 'protocol_buffers'
4
+
5
+ describe ArProtobufStore do
6
+ it "should have a VERSION constant" do
7
+ subject.const_get('VERSION').should_not be_empty
8
+ end
9
+ end
@@ -0,0 +1,63 @@
1
+ require "spec_helper"
2
+ require "ar_protobuf_store"
3
+
4
+ begin
5
+ require "protocol_buffers"
6
+
7
+ describe ArProtobufStore::CodekitchenProtobufParser do
8
+ around(:each) do |example|
9
+ setup_db do
10
+ create_table :foos do |t|
11
+ t.column :extras, :binary
12
+ end
13
+ end
14
+
15
+ example.run
16
+
17
+ teardown_db
18
+ end
19
+
20
+ let(:ar_klass) {
21
+ # Define everything using anonymous classes to reduce leakage.
22
+ extras = Class.new(::ProtocolBuffers::Message) do
23
+ optional :uint64, :int_attr, 1
24
+ optional :string, :str_attr, 2
25
+ end
26
+
27
+ Class.new(::ActiveRecord::Base) do
28
+ self.table_name = "foos"
29
+
30
+ include ArProtobufStore
31
+
32
+ protobuf_store :extras, extras
33
+ end
34
+ }
35
+
36
+ describe ArProtobufStore::ClassMethods do
37
+ it "should allow setting fields individually" do
38
+ record = ar_klass.create!
39
+ record.int_attr = 2
40
+ record.str_attr = "TEST"
41
+ record.save
42
+ expect(record.persisted?).to eq(true)
43
+ record_id = record.id
44
+
45
+ record = ar_klass.find(record_id)
46
+ expect(record.int_attr).to eq(2)
47
+ expect(record.str_attr).to eq("TEST")
48
+ end
49
+
50
+ it "should allow setting fields in constructor" do
51
+ record = ar_klass.create!(:int_attr => 2, :str_attr => "TEST")
52
+ expect(record.persisted?).to eq(true)
53
+ record_id = record.id
54
+
55
+ record = ar_klass.find(record_id)
56
+ expect(record.int_attr).to eq(2)
57
+ expect(record.str_attr).to eq("TEST")
58
+ end
59
+ end
60
+ end
61
+ rescue LoadError
62
+ # Ignore: protobuf isn't loaded!
63
+ end