activerecord-coders 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +2 -0
  5. data/LICENSE +22 -0
  6. data/README.md +125 -0
  7. data/Rakefile +17 -0
  8. data/activerecord-coders.gemspec +35 -0
  9. data/lib/active_record/coders.rb +11 -0
  10. data/lib/active_record/coders/compressors.rb +4 -0
  11. data/lib/active_record/coders/compressors/base.rb +22 -0
  12. data/lib/active_record/coders/compressors/gzip.rb +9 -0
  13. data/lib/active_record/coders/encryptors.rb +3 -0
  14. data/lib/active_record/coders/encryptors/aes.rb +21 -0
  15. data/lib/active_record/coders/pipeline.rb +20 -0
  16. data/lib/active_record/coders/serializers.rb +7 -0
  17. data/lib/active_record/coders/serializers/base.rb +22 -0
  18. data/lib/active_record/coders/serializers/json.rb +9 -0
  19. data/lib/active_record/coders/serializers/marshal.rb +9 -0
  20. data/lib/active_record/coders/serializers/message_pack.rb +9 -0
  21. data/lib/active_record/coders/serializers/yaml.rb +9 -0
  22. data/lib/active_record/coders/version.rb +5 -0
  23. data/lib/activerecord-coders.rb +1 -0
  24. data/spec/env.rb +21 -0
  25. data/spec/lib/active_record/coders/compressors/gzip_spec.rb +32 -0
  26. data/spec/lib/active_record/coders/encryptors/aes_spec.rb +66 -0
  27. data/spec/lib/active_record/coders/pipeline_spec.rb +29 -0
  28. data/spec/lib/active_record/coders/serializers/json_spec.rb +29 -0
  29. data/spec/lib/active_record/coders/serializers/marshal_spec.rb +29 -0
  30. data/spec/lib/active_record/coders/serializers/message_pack_spec.rb +30 -0
  31. data/spec/lib/active_record/coders/serializers/yaml_spec.rb +29 -0
  32. data/spec/spec_helper.rb +17 -0
  33. data/spec/support/db/migrate/01_create_db_gzips.rb +8 -0
  34. data/spec/support/db/migrate/02_create_db_jsons.rb +8 -0
  35. data/spec/support/db/migrate/03_create_db_message_packs.rb +8 -0
  36. data/spec/support/db/migrate/04_create_db_yamls.rb +8 -0
  37. data/spec/support/db/migrate/05_create_db_marshals.rb +8 -0
  38. data/spec/support/db/migrate/06_create_db_aes.rb +9 -0
  39. data/spec/support/db/migrate/07_create_db_pipelines.rb +9 -0
  40. data/spec/support/fixtures/lipsum.txt +9 -0
  41. data/spec/support/models/db_aes.rb +6 -0
  42. data/spec/support/models/db_gzip.rb +3 -0
  43. data/spec/support/models/db_json.rb +3 -0
  44. data/spec/support/models/db_marshal.rb +3 -0
  45. data/spec/support/models/db_message_pack.rb +3 -0
  46. data/spec/support/models/db_pipeline.rb +14 -0
  47. data/spec/support/models/db_yaml.rb +3 -0
  48. metadata +255 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5737128052b05970281b00c05dbb9d5bb6b2b568
4
+ data.tar.gz: 45caf47aa40cc76d5ce2e261d56af9f806d6766f
5
+ SHA512:
6
+ metadata.gz: 5a57ddb9c08382bd4c8c2a66487d7a990572092ed01b4a394cecb35a9f10eb7bd1d6d5e7be17733201edbb437ad69176cf8387320bad05339b50466e8a9b416a
7
+ data.tar.gz: 307ee3ce6ec0acdc7989a7b1e0cd5bfb8f7059e3eae108040cac04bd0ec9fad94cd5732e525b1bc66ed8b6dd4cead803a54690c75d262e6ce6b1e4eb6c1d3a5c
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --format documentation
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) Michael van Rooijen - michael@vanrooijen.io - michael.vanrooijen.io
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # ActiveRecord::Coders
2
+
3
+ Library that provides a set of serializers and a pipeline for optionally chaining them.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem "activerecord-coders"
10
+
11
+ ## Usage
12
+
13
+ Here follows a list of various serializers, compressors and encryptors.
14
+
15
+ ### Serializers
16
+
17
+ Serializers allow you to serialize Ruby objects to text/binary format in order to store more complex data structures in a single column.
18
+
19
+ #### Marshal
20
+
21
+ Store as binary (`t.binary :info`)
22
+
23
+ ```rb
24
+ class User < ActiveRecord::Base
25
+ serialize :info, Coders::Seralizers::Marshal.new
26
+ end
27
+ ```
28
+
29
+ #### YAML
30
+
31
+ Store as text (`t.text :info`)
32
+
33
+ ```rb
34
+ class User < ActiveRecord::Base
35
+ serialize :info, Coders::Seralizers::YAML.new
36
+ end
37
+ ```
38
+
39
+ #### JSON
40
+
41
+ Store as text (`t.text :info`)
42
+
43
+ ```rb
44
+ class User < ActiveRecord::Base
45
+ serialize :info, Coders::Seralizers::JSON.new
46
+ end
47
+ ```
48
+
49
+ Store as binary (`t.binary :info`)
50
+
51
+ #### MessagePack
52
+
53
+ ```rb
54
+ class User < ActiveRecord::Base
55
+ serialize :info, Coders::Seralizers::MessagePack.new
56
+ end
57
+ ```
58
+
59
+ ### Compressors
60
+
61
+ Compressors allow you to compress raw text, or serialized Ruby objects to more efficiently store your data.
62
+
63
+ #### Gzip
64
+
65
+ Store as binary (`t.binary`)
66
+
67
+ ```rb
68
+ class User < ActiveRecord::Base
69
+ serialize :info, Coders::Compressors::Gzip.new
70
+ end
71
+ ```
72
+
73
+ ### Encryptors
74
+
75
+ Encryptors allow you to encrypt text/binary/serialized Ruby objects to more securely store your data.
76
+
77
+ #### AES
78
+
79
+ Store as binary (`t.binary`)
80
+
81
+ ```rb
82
+ class User < ActiveRecord::Base
83
+ serialize :info, Coders::Encryptors::AES.new(ENV["CIPHER_KEY"])
84
+ end
85
+ ```
86
+
87
+ Arguments you can pass to `Coders::Encryptors::AES.new`:
88
+
89
+ - password [String] *required*
90
+ - key_length [Integer] *optional, default: 256*
91
+ - options [Hash] *optional*
92
+ - :binary *optional, default: true*
93
+
94
+ ### Pipeline
95
+
96
+ You can chain together multiple coders to combine their operations for a single attribute.
97
+
98
+ #### Serialize -> Compress -> Encrypt
99
+
100
+ Store as binary (`t.binary`)
101
+
102
+ ```rb
103
+ class User < ActiveRecord::Base
104
+ serialize :info, Coders::Pipeline.new(
105
+ Coders::Serializers::MessagePack.new,
106
+ Coders::Compressors::Gzip.new,
107
+ Coders::Encryptors::AES.new(ENV["CIPHER"])
108
+ )
109
+ end
110
+
111
+ User.create(info: { cc: "0000-0000-0000-0000" })
112
+ ```
113
+
114
+ The above example will execute each coder in the defined order. The `{ cc: "0000-0000-0000-0000 }` Hash will be serialized to binary with MessagePack, then it'll be compressed with Gzip, and finally encrypted with AES (256), before being stored.
115
+
116
+ ## Contributing
117
+
118
+ * Requirements:
119
+ * Code style must match that of the project
120
+ * Avoid including libraries that have dependencies
121
+ * 100% test coverage with SimpleCov
122
+
123
+ ## License
124
+
125
+ Released under the MIT license. See `LICENSE`.
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :environment do
4
+ require_relative "spec/env"
5
+ end
6
+
7
+ namespace :db do
8
+ desc "Migrate the database"
9
+ task(:migrate => :environment) do
10
+ db = File.join(ROOT, "tmp/db.sqlite3")
11
+ File.delete(db) if File.exist?(db)
12
+
13
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
14
+ ActiveRecord::Migration.verbose = true
15
+ ActiveRecord::Migrator.migrate("spec/support/db/migrate")
16
+ end
17
+ end
@@ -0,0 +1,35 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "active_record/coders/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "activerecord-coders"
7
+ spec.version = ActiveRecord::Coders::VERSION
8
+ spec.authors = ["Michael van Rooijen"]
9
+ spec.email = ["michael@vanrooijen.io"]
10
+ spec.summary = %q{A collection of useful coders for ActiveRecord, including a pipeline for chaining them.}
11
+ spec.homepage = "http://michael.vanrooijen.io"
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
16
+ spec.require_paths = ["lib"]
17
+
18
+ # Utils
19
+ spec.add_development_dependency "bundler", "~> 1.5"
20
+ spec.add_development_dependency "rake"
21
+
22
+ # Core requirements
23
+ spec.add_development_dependency "activerecord", "~> 4.0.0"
24
+ spec.add_development_dependency "sqlite3"
25
+
26
+ # 3rd party libaries for coders
27
+ spec.add_development_dependency "gibberish"
28
+ spec.add_development_dependency "msgpack"
29
+
30
+ # Testing libraries
31
+ spec.add_development_dependency "rspec"
32
+ spec.add_development_dependency "mocha"
33
+ spec.add_development_dependency "database_cleaner"
34
+ spec.add_development_dependency "simplecov"
35
+ end
@@ -0,0 +1,11 @@
1
+ module ActiveRecord
2
+ module Coders
3
+ require_relative "coders/pipeline"
4
+ require_relative "coders/serializers"
5
+ require_relative "coders/compressors"
6
+ require_relative "coders/encryptors"
7
+ require_relative "coders/version"
8
+ end
9
+ end
10
+
11
+ Coders = ActiveRecord::Coders unless defined?(Coders)
@@ -0,0 +1,4 @@
1
+ module ActiveRecord::Coders::Compressors
2
+ require_relative "compressors/base"
3
+ require_relative "compressors/gzip"
4
+ end
@@ -0,0 +1,22 @@
1
+ class ActiveRecord::Coders::Compressors::Base
2
+
3
+ class << self
4
+ attr_accessor :load, :dump
5
+
6
+ def compress_with
7
+ yield self
8
+ end
9
+ end
10
+
11
+ def dump(data)
12
+ self.class.dump.call(data)
13
+ rescue
14
+ String.new
15
+ end
16
+
17
+ def load(data)
18
+ self.class.load.call(data)
19
+ rescue
20
+ nil
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRecord::Coders::Compressors
2
+ class Gzip < Base
3
+
4
+ compress_with do |c|
5
+ c.load = ->(data){ ::Zlib::Inflate.inflate(data) }
6
+ c.dump = ->(data){ ::Zlib::Deflate.deflate(data) }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module ActiveRecord::Coders::Encryptors
2
+ require_relative "encryptors/aes"
3
+ end
@@ -0,0 +1,21 @@
1
+ class ActiveRecord::Coders::Encryptors::AES
2
+
3
+ attr_reader :cipher, :options
4
+
5
+ def initialize(password, size = 256, options = {})
6
+ @cipher = ::Gibberish::AES.new(password, size)
7
+ @options = { binary: true }.merge(options)
8
+ end
9
+
10
+ def dump(data)
11
+ cipher.encrypt(data, options)
12
+ rescue
13
+ String.new
14
+ end
15
+
16
+ def load(data)
17
+ cipher.decrypt(data, options)
18
+ rescue
19
+ nil
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ class ActiveRecord::Coders::Pipeline
2
+
3
+ attr_reader :coders
4
+
5
+ def initialize(*coders)
6
+ @coders = coders.flatten
7
+ end
8
+
9
+ def dump(data)
10
+ coders.inject(data) do |data, coder|
11
+ coder ? coder.dump(data) : data
12
+ end
13
+ end
14
+
15
+ def load(data)
16
+ coders.reverse.inject(data) do |data, coder|
17
+ coder ? coder.load(data) : data
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ module ActiveRecord::Coders::Serializers
2
+ require_relative "serializers/base"
3
+ require_relative "serializers/marshal"
4
+ require_relative "serializers/yaml"
5
+ require_relative "serializers/json"
6
+ require_relative "serializers/message_pack"
7
+ end
@@ -0,0 +1,22 @@
1
+ class ActiveRecord::Coders::Serializers::Base
2
+
3
+ class << self
4
+ attr_accessor :load, :dump
5
+
6
+ def serialize_with
7
+ yield self
8
+ end
9
+ end
10
+
11
+ def dump(data)
12
+ self.class.dump.call(data)
13
+ rescue
14
+ String.new
15
+ end
16
+
17
+ def load(data)
18
+ self.class.load.call(data)
19
+ rescue
20
+ nil
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRecord::Coders::Serializers
2
+ class JSON < Base
3
+
4
+ serialize_with do |s|
5
+ s.load = ->(data){ ::JSON.parse(data) }
6
+ s.dump = ->(data){ ::JSON.generate(data) }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRecord::Coders::Serializers
2
+ class Marshal < Base
3
+
4
+ serialize_with do |s|
5
+ s.load = ->(data){ ::Marshal.load(data) }
6
+ s.dump = ->(data){ ::Marshal.dump(data) }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRecord::Coders::Serializers
2
+ class MessagePack < Base
3
+
4
+ serialize_with do |s|
5
+ s.load = ->(data){ ::MessagePack.unpack(data) }
6
+ s.dump = ->(data){ ::MessagePack.pack(data) }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module ActiveRecord::Coders::Serializers
2
+ class YAML < Base
3
+
4
+ serialize_with do |s|
5
+ s.load = ->(data){ ::YAML.load(data) }
6
+ s.dump = ->(data){ ::YAML.dump(data) }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ module ActiveRecord
2
+ module Coders
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ require_relative "active_record/coders"
data/spec/env.rb ADDED
@@ -0,0 +1,21 @@
1
+ # Load Dependencies
2
+ require "fileutils"
3
+ require "bundler"
4
+ Bundler.require(:development)
5
+ require "active_record"
6
+
7
+ # Prepare Environment
8
+ ROOT = File.expand_path("../..", __FILE__)
9
+ FileUtils.mkdir_p(File.join(ROOT, "tmp"))
10
+
11
+ # Load Coders
12
+ require File.join(ROOT, "lib/active_record/coders")
13
+
14
+ # Load Spec Models
15
+ Dir[File.join(ROOT, "spec/support/models/*.rb")].each { |f| require f }
16
+
17
+ # Configure and connect to SQlite with ActiveRecord
18
+ ActiveRecord::Base.establish_connection(
19
+ adapter: "sqlite3",
20
+ database: File.join(ROOT, "tmp/db.sqlite3")
21
+ )
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ describe ActiveRecord::Coders::Compressors::Gzip do
4
+
5
+ it "should create blank" do
6
+ DbGzip.create
7
+ end
8
+
9
+ it "should handle nil values" do
10
+ gzip = DbGzip.new
11
+ gzip.data = nil
12
+ gzip.save
13
+ gzip.reload.data.should == nil
14
+ end
15
+
16
+ it "should not compress invalid data" do
17
+ gzip = DbGzip.new
18
+ gzip.data = {}
19
+ gzip.save
20
+ gzip.reload.data.should == nil
21
+ end
22
+
23
+ it "should (de)compress" do
24
+ gzip = DbGzip.new
25
+ gzip.data = read_fixture("lipsum.txt")
26
+ gzip.save
27
+ gzip.data.should == read_fixture("lipsum.txt")
28
+ gzip.data.bytesize.should == 3640
29
+ gzip.reload.instance_variable_get("@attributes")["data"].
30
+ value.bytesize.should == 1374
31
+ end
32
+ end
@@ -0,0 +1,66 @@
1
+ require "spec_helper"
2
+
3
+ describe ActiveRecord::Coders::Encryptors::AES do
4
+
5
+ it "should create blank" do
6
+ DbAes.create
7
+ end
8
+
9
+ context "binary" do
10
+
11
+ it "should handle nil values" do
12
+ aes256 = DbAes.new
13
+ aes256.binary_data = nil
14
+ aes256.save
15
+ aes256.reload.binary_data.should == nil
16
+ end
17
+
18
+ it "should handle empty string values" do
19
+ aes256 = DbAes.new
20
+ aes256.binary_data = ""
21
+ aes256.save
22
+ aes256.reload.binary_data.should == nil
23
+ end
24
+
25
+ it "should (de)compress" do
26
+ aes256 = DbAes.new
27
+ aes256.binary_data = read_fixture("lipsum.txt")
28
+ aes256.save
29
+ aes256.binary_data.should == read_fixture("lipsum.txt")
30
+ aes256.binary_data.bytesize.should == 3640
31
+ aes256.reload.instance_variable_get("@attributes")["binary_data"].
32
+ value.bytesize.should == 3664
33
+ aes256.reload.instance_variable_get("@attributes")["binary_data"].
34
+ should_not == aes256.binary_data
35
+ end
36
+ end
37
+
38
+ context "text" do
39
+
40
+ it "should handle nil values" do
41
+ aes256 = DbAes.new
42
+ aes256.text_data = nil
43
+ aes256.save
44
+ aes256.reload.text_data.should == nil
45
+ end
46
+
47
+ it "should handle empty string values" do
48
+ aes256 = DbAes.new
49
+ aes256.text_data = ""
50
+ aes256.save
51
+ aes256.reload.text_data.should == nil
52
+ end
53
+
54
+ it "should (de)compress" do
55
+ aes256 = DbAes.new
56
+ aes256.text_data = read_fixture("lipsum.txt")
57
+ aes256.save
58
+ aes256.text_data.should == read_fixture("lipsum.txt")
59
+ aes256.text_data.bytesize.should == 3640
60
+ aes256.reload.instance_variable_get("@attributes")["text_data"].
61
+ value.bytesize.should == 4970
62
+ aes256.reload.instance_variable_get("@attributes")["text_data"].
63
+ should_not == aes256.text_data
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe ActiveRecord::Coders::Pipeline do
4
+
5
+ it "create a blank record" do
6
+ DbPipeline.create
7
+ end
8
+
9
+ it "should handle nil values" do
10
+ pipeline = DbPipeline.new
11
+ pipeline.sce = nil
12
+ pipeline.save
13
+ pipeline.reload.sce.should == nil
14
+ end
15
+
16
+ it "should serialize, compress and encrypt" do
17
+ pipeline = DbPipeline.new
18
+ pipeline.sce = { example: true }
19
+ pipeline.save
20
+ pipeline.reload.sce.should == { "example" => true }
21
+ end
22
+
23
+ it "should serialize, encrypt, but not compress" do
24
+ pipeline = DbPipeline.new
25
+ pipeline.se = { example: true }
26
+ pipeline.save
27
+ pipeline.reload.se.should == { "example" => true }
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe ActiveRecord::Coders::Serializers::JSON do
4
+
5
+ it "should create" do
6
+ DbJSON.create
7
+ end
8
+
9
+ it "should (de)serialize nil" do
10
+ json = DbJSON.new
11
+ json.data = nil
12
+ json.save
13
+ json.reload.data.should == nil
14
+ end
15
+
16
+ it "should (de)serialize" do
17
+ json = DbJSON.new
18
+ json.data = { some: "data", with: %w[a r r a y] }
19
+ json.save
20
+ json.reload.data.should == { "some" => "data", "with" => %w[a r r a y] }
21
+ end
22
+
23
+ it "should not serialize invalid data" do
24
+ json = DbJSON.new
25
+ json.data = 1
26
+ json.save
27
+ json.reload.data.should == nil
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe ActiveRecord::Coders::Serializers::Marshal do
4
+
5
+ it "should create" do
6
+ DbMarshal.create
7
+ end
8
+
9
+ it "should (de)serialize nil" do
10
+ marshal = DbMarshal.new
11
+ marshal.data = nil
12
+ marshal.save
13
+ marshal.reload.data.should == nil
14
+ end
15
+
16
+ it "should (de)serialize" do
17
+ marshal = DbMarshal.new
18
+ marshal.data = { some: "data", with: %w[a r r a y] }
19
+ marshal.save
20
+ marshal.reload.data.should == { some: "data", with: %w[a r r a y] }
21
+ end
22
+
23
+ it "should not serialize invalid data" do
24
+ marshal = DbMarshal.new
25
+ marshal.data = proc {}
26
+ marshal.save
27
+ marshal.reload.data.should == nil
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ require "spec_helper"
2
+
3
+ describe ActiveRecord::Coders::Serializers::MessagePack do
4
+
5
+ it "should create" do
6
+ DbMessagePack.create
7
+ end
8
+
9
+ it "should (de)serialize nil" do
10
+ msgpack = DbMessagePack.new
11
+ msgpack.data = nil
12
+ msgpack.save
13
+ msgpack.reload.data.should == nil
14
+ end
15
+
16
+ it "should (de)serialize" do
17
+ msgpack = DbMessagePack.new
18
+ msgpack.data = { some: "data", with: %w[a r r a y] }
19
+ msgpack.save
20
+ msgpack.reload.data.should ==
21
+ { "some" => "data", "with" => %w[a r r a y] }
22
+ end
23
+
24
+ it "should not serialize invalid data" do
25
+ msgpack = DbMessagePack.new
26
+ msgpack.data = proc {}
27
+ msgpack.save
28
+ msgpack.reload.data.should == nil
29
+ end
30
+ end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe ActiveRecord::Coders::Serializers::YAML do
4
+
5
+ it "should create" do
6
+ DbYAML.create
7
+ end
8
+
9
+ it "should (de)serialize nil" do
10
+ json = DbYAML.new
11
+ json.data = nil
12
+ json.save
13
+ json.reload.data.should == nil
14
+ end
15
+
16
+ it "should (de)serialize" do
17
+ json = DbYAML.new
18
+ json.data = { some: "data", with: %w[a r r a y] }
19
+ json.save
20
+ json.reload.data.should == { some: "data", with: %w[a r r a y] }
21
+ end
22
+
23
+ it "should deserialize invalid data" do
24
+ yaml = DbYAML.new
25
+ yaml.data = proc {}
26
+ yaml.save
27
+ yaml.reload.data.should == nil
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ # Load SimpleCov
2
+ require "simplecov"
3
+ SimpleCov.start
4
+
5
+ # Load Environment
6
+ require_relative "env"
7
+
8
+ # Configure RSpec
9
+ RSpec.configure do |config|
10
+ config.before(:all) { DatabaseCleaner.strategy = :truncation }
11
+ config.before { DatabaseCleaner.clean }
12
+ end
13
+
14
+ # Helper Methods
15
+ def read_fixture(path)
16
+ File.read(File.join(ROOT, "spec/support/fixtures", path))
17
+ end
@@ -0,0 +1,8 @@
1
+ class CreateDbGzips < ActiveRecord::Migration
2
+
3
+ def change
4
+ create_table :db_gzips do |t|
5
+ t.binary :data
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ class CreateDbJsons < ActiveRecord::Migration
2
+
3
+ def change
4
+ create_table :db_jsons do |t|
5
+ t.text :data
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ class CreateDbMessagePacks < ActiveRecord::Migration
2
+
3
+ def change
4
+ create_table :db_message_packs do |t|
5
+ t.binary :data
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ class CreateDbYamls < ActiveRecord::Migration
2
+
3
+ def change
4
+ create_table :db_yamls do |t|
5
+ t.text :data
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ class CreateDbMarshals < ActiveRecord::Migration
2
+
3
+ def change
4
+ create_table :db_marshals do |t|
5
+ t.binary :data
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ class CreateDbAes < ActiveRecord::Migration
2
+
3
+ def change
4
+ create_table :db_aes do |t|
5
+ t.text :text_data
6
+ t.binary :binary_data
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class CreateDbPipelines < ActiveRecord::Migration
2
+
3
+ def change
4
+ create_table :db_pipelines do |t|
5
+ t.binary :sce
6
+ t.binary :se
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla lorem sapien, aliquam eget tempus nec, pretium a velit. Pellentesque sit amet dictum lorem, in tempus neque. Nulla a interdum lectus, sed pellentesque quam. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc vel gravida felis, quis ornare diam. Curabitur at condimentum lectus. In malesuada, justo vitae sodales ornare, metus est rutrum dui, vel commodo tellus massa nec turpis. Aliquam erat volutpat. Quisque vitae eros consectetur, viverra mi feugiat, tincidunt eros.
2
+
3
+ Maecenas dui nisi, varius quis nibh in, ullamcorper auctor orci. Cras viverra condimentum sem, vitae egestas orci ullamcorper ac. Donec placerat, nisl eu feugiat fringilla, lectus mauris vestibulum est, a consectetur purus tellus ullamcorper massa. Nulla ultricies convallis eleifend. Cras ut tempus odio, vel interdum felis. Duis justo dui, mattis eget risus et, porta sagittis libero. Donec quam erat, venenatis nec gravida nec, lobortis sit amet purus. Mauris elit nisi, interdum ac aliquet nec, fringilla a sapien. Donec fringilla elit enim, nec vulputate neque ultrices facilisis. Pellentesque sodales eros et elementum rutrum. Duis vestibulum orci eget aliquam suscipit. Nunc at lacus ut quam lobortis auctor nec bibendum tellus. Quisque dui dolor, scelerisque laoreet velit sed, pellentesque blandit libero. Morbi erat nisl, ullamcorper at quam nec, suscipit tempus dolor. Pellentesque tristique libero erat, nec porttitor neque pretium a.
4
+
5
+ Vestibulum egestas adipiscing magna, et pulvinar enim vehicula sit amet. Suspendisse potenti. Suspendisse nec ipsum quis lectus fringilla facilisis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed sed nulla sit amet est sollicitudin mollis et id dolor. Suspendisse interdum, urna eu mattis rutrum, ipsum lorem pharetra ipsum, sed tincidunt neque nisi quis arcu. Quisque consequat lacus sit amet porta euismod. Vivamus congue dui non nibh blandit, sed iaculis sem rutrum. Aliquam in laoreet mauris, eget pellentesque odio. Cras molestie turpis at diam rutrum, eget laoreet massa dictum. Curabitur eu turpis rhoncus, elementum turpis in, molestie erat. Morbi vitae mi quis diam faucibus consequat vitae ut quam. Aenean rutrum magna at odio rutrum, sed dapibus odio mattis.
6
+
7
+ Quisque nec luctus felis. Pellentesque rhoncus purus sit amet quam sollicitudin vulputate. Aenean condimentum pretium nisl sed posuere. Vivamus ultrices urna nec nulla lobortis venenatis. Duis placerat, orci vel venenatis adipiscing, metus dolor auctor lacus, ornare malesuada eros nisi eget turpis. Donec ac bibendum nisl. Nunc odio neque, dictum a tempor nec, mollis id justo. Donec non metus nibh. Sed dignissim metus sapien, sit amet imperdiet libero tincidunt sit amet.
8
+
9
+ Donec sodales dui et neque auctor, malesuada eleifend enim interdum. Aliquam placerat velit eget nisi tempor, in pellentesque tellus accumsan. Ut eget congue mauris, non venenatis augue. Curabitur consequat, urna vel bibendum sagittis, elit odio placerat nibh, eget feugiat tortor tortor sit amet lectus. Cras sed nunc mauris. Donec urna ligula, accumsan a scelerisque ac, rhoncus ut nulla. Morbi a lorem sed magna placerat venenatis. Ut tincidunt bibendum massa eu mattis. Vestibulum cursus placerat metus, vitae ullamcorper lorem. Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque ac massa vitae metus vulputate vestibulum a eget leo. Sed in tempus lorem. In tincidunt metus in nulla blandit sagittis nec nec nibh. Duis non dignissim arcu. Pellentesque aliquam vehicula lectus non aliquam. Cras laoreet felis vel lacus rutrum, eu placerat dolor viverra.
@@ -0,0 +1,6 @@
1
+ class DbAes < ActiveRecord::Base
2
+ serialize :text_data,
3
+ ActiveRecord::Coders::Encryptors::AES.new("secret", 256, binary: false)
4
+ serialize :binary_data,
5
+ ActiveRecord::Coders::Encryptors::AES.new("secret")
6
+ end
@@ -0,0 +1,3 @@
1
+ class DbGzip < ActiveRecord::Base
2
+ serialize :data, ActiveRecord::Coders::Compressors::Gzip.new
3
+ end
@@ -0,0 +1,3 @@
1
+ class DbJSON < ActiveRecord::Base
2
+ serialize :data, ActiveRecord::Coders::Serializers::JSON.new
3
+ end
@@ -0,0 +1,3 @@
1
+ class DbMarshal < ActiveRecord::Base
2
+ serialize :data, ActiveRecord::Coders::Serializers::Marshal.new
3
+ end
@@ -0,0 +1,3 @@
1
+ class DbMessagePack < ActiveRecord::Base
2
+ serialize :data, ActiveRecord::Coders::Serializers::MessagePack.new
3
+ end
@@ -0,0 +1,14 @@
1
+ class DbPipeline < ActiveRecord::Base
2
+ serialize :sce,
3
+ Coders::Pipeline.new(
4
+ Coders::Serializers::MessagePack.new,
5
+ Coders::Compressors::Gzip.new,
6
+ Coders::Encryptors::AES.new("secret")
7
+ )
8
+
9
+ serialize :se,
10
+ Coders::Pipeline.new(
11
+ Coders::Serializers::MessagePack.new,
12
+ Coders::Encryptors::AES.new("secret")
13
+ )
14
+ end
@@ -0,0 +1,3 @@
1
+ class DbYAML < ActiveRecord::Base
2
+ serialize :data, ActiveRecord::Coders::Serializers::YAML.new
3
+ end
metadata ADDED
@@ -0,0 +1,255 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-coders
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael van Rooijen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activerecord
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 4.0.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 4.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: sqlite3
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: gibberish
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: msgpack
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: mocha
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: database_cleaner
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description:
154
+ email:
155
+ - michael@vanrooijen.io
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - ".gitignore"
161
+ - ".rspec"
162
+ - Gemfile
163
+ - LICENSE
164
+ - README.md
165
+ - Rakefile
166
+ - activerecord-coders.gemspec
167
+ - lib/active_record/coders.rb
168
+ - lib/active_record/coders/compressors.rb
169
+ - lib/active_record/coders/compressors/base.rb
170
+ - lib/active_record/coders/compressors/gzip.rb
171
+ - lib/active_record/coders/encryptors.rb
172
+ - lib/active_record/coders/encryptors/aes.rb
173
+ - lib/active_record/coders/pipeline.rb
174
+ - lib/active_record/coders/serializers.rb
175
+ - lib/active_record/coders/serializers/base.rb
176
+ - lib/active_record/coders/serializers/json.rb
177
+ - lib/active_record/coders/serializers/marshal.rb
178
+ - lib/active_record/coders/serializers/message_pack.rb
179
+ - lib/active_record/coders/serializers/yaml.rb
180
+ - lib/active_record/coders/version.rb
181
+ - lib/activerecord-coders.rb
182
+ - spec/env.rb
183
+ - spec/lib/active_record/coders/compressors/gzip_spec.rb
184
+ - spec/lib/active_record/coders/encryptors/aes_spec.rb
185
+ - spec/lib/active_record/coders/pipeline_spec.rb
186
+ - spec/lib/active_record/coders/serializers/json_spec.rb
187
+ - spec/lib/active_record/coders/serializers/marshal_spec.rb
188
+ - spec/lib/active_record/coders/serializers/message_pack_spec.rb
189
+ - spec/lib/active_record/coders/serializers/yaml_spec.rb
190
+ - spec/spec_helper.rb
191
+ - spec/support/db/migrate/01_create_db_gzips.rb
192
+ - spec/support/db/migrate/02_create_db_jsons.rb
193
+ - spec/support/db/migrate/03_create_db_message_packs.rb
194
+ - spec/support/db/migrate/04_create_db_yamls.rb
195
+ - spec/support/db/migrate/05_create_db_marshals.rb
196
+ - spec/support/db/migrate/06_create_db_aes.rb
197
+ - spec/support/db/migrate/07_create_db_pipelines.rb
198
+ - spec/support/fixtures/lipsum.txt
199
+ - spec/support/models/db_aes.rb
200
+ - spec/support/models/db_gzip.rb
201
+ - spec/support/models/db_json.rb
202
+ - spec/support/models/db_marshal.rb
203
+ - spec/support/models/db_message_pack.rb
204
+ - spec/support/models/db_pipeline.rb
205
+ - spec/support/models/db_yaml.rb
206
+ homepage: http://michael.vanrooijen.io
207
+ licenses:
208
+ - MIT
209
+ metadata: {}
210
+ post_install_message:
211
+ rdoc_options: []
212
+ require_paths:
213
+ - lib
214
+ required_ruby_version: !ruby/object:Gem::Requirement
215
+ requirements:
216
+ - - ">="
217
+ - !ruby/object:Gem::Version
218
+ version: '0'
219
+ required_rubygems_version: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ version: '0'
224
+ requirements: []
225
+ rubyforge_project:
226
+ rubygems_version: 2.2.2
227
+ signing_key:
228
+ specification_version: 4
229
+ summary: A collection of useful coders for ActiveRecord, including a pipeline for
230
+ chaining them.
231
+ test_files:
232
+ - spec/env.rb
233
+ - spec/lib/active_record/coders/compressors/gzip_spec.rb
234
+ - spec/lib/active_record/coders/encryptors/aes_spec.rb
235
+ - spec/lib/active_record/coders/pipeline_spec.rb
236
+ - spec/lib/active_record/coders/serializers/json_spec.rb
237
+ - spec/lib/active_record/coders/serializers/marshal_spec.rb
238
+ - spec/lib/active_record/coders/serializers/message_pack_spec.rb
239
+ - spec/lib/active_record/coders/serializers/yaml_spec.rb
240
+ - spec/spec_helper.rb
241
+ - spec/support/db/migrate/01_create_db_gzips.rb
242
+ - spec/support/db/migrate/02_create_db_jsons.rb
243
+ - spec/support/db/migrate/03_create_db_message_packs.rb
244
+ - spec/support/db/migrate/04_create_db_yamls.rb
245
+ - spec/support/db/migrate/05_create_db_marshals.rb
246
+ - spec/support/db/migrate/06_create_db_aes.rb
247
+ - spec/support/db/migrate/07_create_db_pipelines.rb
248
+ - spec/support/fixtures/lipsum.txt
249
+ - spec/support/models/db_aes.rb
250
+ - spec/support/models/db_gzip.rb
251
+ - spec/support/models/db_json.rb
252
+ - spec/support/models/db_marshal.rb
253
+ - spec/support/models/db_message_pack.rb
254
+ - spec/support/models/db_pipeline.rb
255
+ - spec/support/models/db_yaml.rb