sequel_paper_trail 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 61d2d99cb151f8ca3f3ce9e098d6bcc398da7a38
4
+ data.tar.gz: a94f1018b8b7dcdec22af0c026ac3c0cc9e1fa0b
5
+ SHA512:
6
+ metadata.gz: b067af614882469a32b3f3d761e925bf9db906fcb9bfae2c421f9ba8a42096175fa2d4d7ded996f5bff0649d5921a4982b4b0d9cf2ee8d9adacd83afd857ad8d
7
+ data.tar.gz: fef0e1027d6b5188d9021397a9f98f5de1fc35bf9cdaaf90acef402e557551c071a63630382cb2709ea88bf90d675e257ae02a22bd1bf7ac5b162a48c1cfc030
data/CHANGELOG.md ADDED
File without changes
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Vadim Lazebny
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,146 @@
1
+ Sequel plugin for Paper Trail
2
+ =============
3
+
4
+ This is a simple Sequel plugin for PaperTrail (with limited functionality).
5
+
6
+ Conributions are welcome!
7
+
8
+ [![Gem Version](https://badge.fury.io/rb/sequel_paper_trail.svg)](http://badge.fury.io/rb/sequel_paper_trail)
9
+ [![Travis badge](https://travis-ci.org/lazebny/sequel_paper_trail.svg?branch=master)](https://travis-ci.org/lazebny/sequel_paper_trail)
10
+ [![Coverage Status](https://coveralls.io/repos/lazebny/sequel_paper_trail/badge.png)](https://coveralls.io/r/lazebny/sequel_paper_trail)
11
+ [![Code Climate Badge](https://codeclimate.com/github/lazebny/sequel_paper_trail.svg)](https://codeclimate.com/github/lazebny/sequel_paper_trail)
12
+ [![Inch CI](http://inch-ci.org/github/lazebny/sequel_paper_trail.svg)](http://inch-ci.org/github/lazebny/sequel_paper_trail)
13
+ [![Dependency Status](https://gemnasium.com/lazebny/sequel_paper_trail.svg)](https://gemnasium.com/lazebny/sequel_paper_trail)
14
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT)
15
+
16
+ Features
17
+ ------------
18
+
19
+ * model are able to subscribe on create, update, delete callback
20
+ * can be specified whodunnit
21
+ * can be specified info_for_paper_trail
22
+ * versioning can be disabled or enabled globaly or in block context
23
+
24
+ Limitations
25
+ ------------
26
+
27
+ * this gem doesn't create a version table
28
+ * versions table has a structure as Paper Trail v0.6.x. has
29
+ * whodunnit is global
30
+ * info_for_paper_trail is global
31
+
32
+
33
+ Installation
34
+ ------------
35
+
36
+ Add this line to your application's Gemfile:
37
+
38
+ ```ruby
39
+ gem 'sequel_paper_trail'
40
+ ```
41
+
42
+ Documentation
43
+ -------------
44
+
45
+
46
+ Usage
47
+ -------------
48
+
49
+ Our usage model:
50
+
51
+ * separate service uses [Sequel](https://github.com/jeremyevans/sequel) + this plugin
52
+ * web uses [Paper Trail](https://github.com/airblade/paper_trail) + [Rails Admin](https://github.com/sferik/rails_admin).
53
+
54
+ Be sure that you have a proper tables from [Paper Trail](https://github.com/airblade/paper_trail) v0.6.x.
55
+
56
+ Than you can subscribe a model on create, update, destroy callbacks.
57
+
58
+ Quick start:
59
+
60
+ ```ruby
61
+
62
+ require 'sequel_paper_trail'
63
+ require 'sequel'
64
+ require 'sequel/plugins/has_paper_trail'
65
+
66
+ Album.pligin :has_paper_trail,
67
+ class_name: 'VersionClassName'
68
+ # or
69
+
70
+ Album.pligin :has_paper_trail,
71
+ item_class_name: SomeAlbum,
72
+ class_name: 'VersionClassName'
73
+
74
+ ```
75
+
76
+ Enable versioning globaly:
77
+
78
+ ```ruby
79
+
80
+ SequelPaperTrail.enabled = true
81
+
82
+ ```
83
+
84
+ Enable versioning for block of code:
85
+
86
+ ```ruby
87
+
88
+ SequelPaperTrail.with_versioning { 'code' }
89
+
90
+ ```
91
+
92
+ Disable versioning globaly:
93
+
94
+ ```ruby
95
+
96
+ SequelPaperTrail.enabled = false
97
+
98
+ ```
99
+
100
+ Disable versioning for block of code
101
+
102
+ ```ruby
103
+
104
+ SequelPaperTrail.with_versioning(false) { 'code' }
105
+
106
+ ```
107
+
108
+ Set whodunnit:
109
+
110
+ ```ruby
111
+
112
+ SequelPaperTrail.whodunnit = 'Mr. Smith'
113
+
114
+ ```
115
+
116
+ Set info_for_paper_trail - additional info (Hash) which will be attached to versions table.
117
+
118
+ ```ruby
119
+
120
+ # If you have 'release' and 'instance' columns in a versions table you can populate them.
121
+
122
+ SequelPaperTrail.info_for_paper_trail = { release: 'asdf131234', instance: `hostname` }
123
+
124
+ ```
125
+
126
+ Development
127
+ --------------
128
+
129
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
130
+
131
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
132
+
133
+
134
+ Contributing
135
+ --------------
136
+
137
+ This gem has a very limited functionality so conributions are welcome!
138
+
139
+ Bug reports and pull requests are welcome on GitHub at https://github.com/lazebny/sequel_paper_trail.
140
+
141
+
142
+ License
143
+ --------------
144
+
145
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
146
+
@@ -0,0 +1,128 @@
1
+ module Sequel
2
+ module Plugins
3
+ # Add Paper Trail versioning callbacks to model.
4
+ #
5
+ # Usage:
6
+ #
7
+ # # Enable versioning for all models.
8
+ # Sequel::Model.plugin :has_paper_trail
9
+ #
10
+ # # Make the Album class be able to versioning.
11
+ # Album.plugin :has_paper_trail, item_class_name: Album, class_name: 'Album::Version'
12
+ #
13
+ module HasPaperTrail
14
+ # rubocop:disable Metrics/MethodLength
15
+ def self.configure(model, opts = {})
16
+ paper_trail_item_class_name = opts.fetch(:item_class_name) { model.name }
17
+ paper_trail_version_class_name = opts.fetch(:class_name) { 'SequelPaperTrail::Version' }
18
+
19
+ model.plugin :dirty
20
+ model.one_to_many :versions,
21
+ class: paper_trail_version_class_name,
22
+ key: :item_id,
23
+ conditions: { item_type: paper_trail_item_class_name }
24
+
25
+ model.instance_eval do
26
+ @paper_trail_item_class_name = paper_trail_item_class_name
27
+ @paper_trail_version_class_name = paper_trail_version_class_name
28
+ end
29
+ end
30
+ # rubocop:enable Metrics/MethodLength
31
+
32
+ # rubocop:disable Style/Documentation
33
+ module ClassMethods
34
+ Sequel::Plugins.inherited_instance_variables(
35
+ self,
36
+ :@paper_trail_item_class_name => :dup,
37
+ :@paper_trail_version_class_name => :dup
38
+ )
39
+
40
+ # The class name of item for versioning
41
+ attr_reader :paper_trail_item_class_name
42
+
43
+ # The version class name
44
+ attr_reader :paper_trail_version_class_name
45
+ end
46
+ # rubocop:enable Style/Documentation
47
+
48
+ # rubocop:disable Style/Documentation
49
+ module InstanceMethods
50
+ def after_create
51
+ super
52
+
53
+ return unless SequelPaperTrail.enabled?
54
+
55
+ attrs = {
56
+ item_id: id,
57
+ event: :create,
58
+ object_changes: values.to_json,
59
+ object: nil
60
+ }
61
+
62
+ PaperTrailHelpers.create_version(model, attrs)
63
+ end
64
+
65
+ def after_update
66
+ super
67
+
68
+ return unless SequelPaperTrail.enabled?
69
+ return if column_changes.empty?
70
+
71
+ attrs = {
72
+ item_id: id,
73
+ event: :update,
74
+ object_changes: column_changes.to_json,
75
+ object: values.merge(initial_values).to_json
76
+ }
77
+
78
+ PaperTrailHelpers.create_version(model, attrs)
79
+ end
80
+
81
+ def after_destroy
82
+ super
83
+
84
+ return unless SequelPaperTrail.enabled?
85
+
86
+ attrs = {
87
+ item_id: id,
88
+ event: :destroy,
89
+ object_changes: nil,
90
+ object: values.to_json
91
+ }
92
+
93
+ PaperTrailHelpers.create_version(model, attrs)
94
+ end
95
+ end
96
+ # rubocop:enable Style/Documentation
97
+
98
+ # rubocop:disable Style/Documentation
99
+ module PaperTrailHelpers
100
+ def self.create_version(model, attrs)
101
+ default_attrs = {
102
+ item_type: model.paper_trail_item_class_name.to_s,
103
+ whodunnit: SequelPaperTrail.whodunnit,
104
+ created_at: Time.now.utc.iso8601,
105
+ transaction_id: nil
106
+ }
107
+
108
+ create_attrs = default_attrs
109
+ .merge(SequelPaperTrail.info_for_paper_trail)
110
+ .merge(attrs)
111
+
112
+ version_class(model.paper_trail_version_class_name).create(create_attrs)
113
+ end
114
+
115
+ private_class_method
116
+
117
+ def self.version_class(class_name)
118
+ if class_name.is_a?(String)
119
+ Kernel.const_get(class_name)
120
+ else
121
+ class_name
122
+ end
123
+ end
124
+ end
125
+ # rubocop:enable Style/Documentation
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,21 @@
1
+ require 'singleton'
2
+
3
+ module SequelPaperTrail
4
+ # Config storage
5
+ class Config
6
+ include Singleton
7
+
8
+ def initialize
9
+ @mutex = Mutex.new
10
+ @enabled = true
11
+ end
12
+
13
+ def enabled
14
+ @mutex.synchronize { @enabled }
15
+ end
16
+
17
+ def enabled=(enable)
18
+ @mutex.synchronize { @enabled = enable }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module SequelPaperTrail
2
+ VERSION = '0.0.1'.freeze
3
+ end
@@ -0,0 +1,43 @@
1
+ require 'sequel_paper_trail/version'
2
+ require 'sequel_paper_trail/config'
3
+
4
+ # Paper Trail config interface
5
+ module SequelPaperTrail
6
+ class << self
7
+ attr_accessor :whodunnit
8
+ attr_accessor :info_for_paper_trail
9
+
10
+ # Set versioning state.
11
+ #
12
+ # Boolean -> Boolean
13
+ #
14
+ def enabled=(enable)
15
+ Config.instance.enabled = enable
16
+ end
17
+
18
+ # Check if versioning enabled.
19
+ #
20
+ # Boolean
21
+ #
22
+ def enabled?
23
+ Config.instance.enabled
24
+ end
25
+
26
+ # Execute block with or without versioning.
27
+ #
28
+ # Boolean -> Proc -> Boolean
29
+ #
30
+ def with_versioning(enable = true)
31
+ was_enabled = enabled?
32
+ self.enabled = enable
33
+ yield
34
+ ensure
35
+ self.enabled = was_enabled
36
+ end
37
+ end
38
+ end
39
+
40
+ # Default Configuration
41
+ SequelPaperTrail.enabled = true
42
+ SequelPaperTrail.whodunnit = nil
43
+ SequelPaperTrail.info_for_paper_trail = {}
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe Sequel::Plugins::HasPaperTrail do
4
+ def without_fields(records, *fields)
5
+ records.map do |record|
6
+ record.to_hash.tap { |r| fields.each { |field| r.delete(field) } }
7
+ end
8
+ end
9
+
10
+ let(:paper_db) { SpecPaperDb.new }
11
+ let(:item_class) { paper_db.test_model }
12
+ let(:version_class) { paper_db.version_model }
13
+
14
+ before do
15
+ paper_db.create_test_table
16
+ paper_db.create_versions_table
17
+
18
+ item_class.plugin :has_paper_trail,
19
+ item_class_name: 'TetsClass',
20
+ class_name: version_class
21
+
22
+ SequelPaperTrail.whodunnit = 'Admin'
23
+ SequelPaperTrail.info_for_paper_trail = {
24
+ info: {
25
+ 'val' => 1
26
+ }.to_json,
27
+ other_info: '{}'
28
+ }
29
+ end
30
+
31
+ after do
32
+ paper_db.drop_all_tables
33
+ end
34
+
35
+ it 'creates versions on record create event' do
36
+ record = item_class.create(name: 'test', email: 'test@test.com')
37
+ expected = [
38
+ {
39
+ item_type: 'TetsClass',
40
+ item_id: 1,
41
+ event: 'create',
42
+ whodunnit: 'Admin',
43
+ created_at: Time.now.utc.iso8601,
44
+ transaction_id: nil,
45
+ object_changes: '{"name":"test","email":"test@test.com","id":1}',
46
+ object: nil,
47
+ info: '{"val":1}',
48
+ other_info: '{}'
49
+ }
50
+ ]
51
+ expect(without_fields(record.versions, :id)).to eql(expected)
52
+ end
53
+
54
+ it 'creates versions on record update event' do
55
+ record = item_class.create(name: 'test', email: 'test@test.com')
56
+ record.update(name: '2')
57
+ expected = {
58
+ item_type: 'TetsClass',
59
+ item_id: 1,
60
+ event: 'update',
61
+ whodunnit: 'Admin',
62
+ created_at: Time.now.utc.iso8601,
63
+ transaction_id: nil,
64
+ object_changes: '{"name":["test","2"]}',
65
+ object: '{"id":1,"name":"test","email":"test@test.com"}',
66
+ info: '{"val":1}',
67
+ other_info: '{}'
68
+ }
69
+ expect(without_fields(record.versions, :id)).to be_include(expected)
70
+ end
71
+
72
+ it 'creates versions on record destroy event' do
73
+ record = item_class.create(name: 'test', email: 'test@test.com')
74
+ record.destroy
75
+ expected = {
76
+ item_type: 'TetsClass',
77
+ item_id: 1,
78
+ event: 'destroy',
79
+ whodunnit: 'Admin',
80
+ created_at: Time.now.utc.iso8601,
81
+ transaction_id: nil,
82
+ object_changes: nil,
83
+ object: '{"id":1,"name":"test","email":"test@test.com"}',
84
+ info: '{"val":1}',
85
+ other_info: '{}'
86
+ }
87
+ expect(without_fields(record.versions, :id)).to be_include(expected)
88
+ end
89
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe SequelPaperTrail do
4
+ let(:paper_db) { SpecPaperDb.new }
5
+ let(:item_class) { paper_db.test_model }
6
+ let(:version_class) { paper_db.version_model }
7
+
8
+ before do
9
+ paper_db.create_test_table
10
+ paper_db.create_versions_table
11
+
12
+ item_class.plugin :has_paper_trail,
13
+ item_class_name: 'TestClass',
14
+ class_name: version_class
15
+ end
16
+
17
+ after do
18
+ paper_db.drop_all_tables
19
+ end
20
+
21
+ context '.with_versioning' do
22
+ it 'enabled' do
23
+ described_class.with_versioning(true) do
24
+ item = item_class.create(name: 'test')
25
+ expect(item.versions).not_to be_empty
26
+ end
27
+ end
28
+
29
+ it 'disabled' do
30
+ described_class.with_versioning(false) do
31
+ item = item_class.create(name: 'test')
32
+ expect(item.versions).to be_empty
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ require 'bundler/setup'
2
+ require 'sequel'
3
+ # require 'jdbc-sqlite3'
4
+ require 'pry'
5
+
6
+ require 'sequel_paper_trail'
7
+ require 'sequel/plugins/has_paper_trail'
8
+
9
+ Dir['./spec/support/*'].each(&method(:require))
10
+
11
+ require 'coveralls'
12
+ Coveralls.wear!
13
+
14
+ RSpec.configure do |config|
15
+ config.order = 'random'
16
+ # Enable flags like --only-failures and --next-failure
17
+ # config.example_status_persistence_file_path = '.rspec_status'
18
+
19
+ config.expect_with :rspec do |c|
20
+ c.syntax = :expect
21
+ end
22
+ end
@@ -0,0 +1,49 @@
1
+ class SpecPaperDb
2
+ def initialize
3
+ # https://gist.github.com/studiorailsway/1561497
4
+ @db = if RUBY_PLATFORM == 'java'
5
+ Sequel.connect('jdbc:sqlite:db.sqlite3')
6
+ else
7
+ Sequel.sqlite(':memory:')
8
+ end
9
+ end
10
+
11
+ def create_test_table
12
+ @db.create_table!(:test_table) do
13
+ primary_key :id
14
+ column :name, :text
15
+ column :email, :text
16
+ end
17
+ end
18
+
19
+ def test_model
20
+ Class.new(Sequel::Model(@db[:test_table]))
21
+ end
22
+
23
+ # rubocop:disable Metrics/MethodLength
24
+ def create_versions_table
25
+ @db.create_table!(:versions) do
26
+ primary_key :id
27
+ column 'item_type', :text
28
+ column 'item_id', :integer
29
+ column 'event', :text
30
+ column 'whodunnit', :text
31
+ column 'created_at', :text
32
+ column 'transaction_id', :integer
33
+ column 'object_changes', :text
34
+ column 'object', :text
35
+ column 'info', :text
36
+ column 'other_info', :text
37
+ end
38
+ end
39
+ # rubocop:enable Metrics/MethodLength
40
+
41
+ def version_model
42
+ Class.new(Sequel::Model(@db[:versions]))
43
+ end
44
+
45
+ def drop_all_tables
46
+ @db.drop_table(:test_table)
47
+ @db.drop_table(:versions)
48
+ end
49
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sequel_paper_trail
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Vadim Lazebny
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Sequel plugin for PaperTrail.
14
+ email:
15
+ - vadim.lazebny@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files:
19
+ - README.md
20
+ - LICENSE.txt
21
+ - CHANGELOG.md
22
+ files:
23
+ - CHANGELOG.md
24
+ - LICENSE.txt
25
+ - README.md
26
+ - lib/sequel/plugins/has_paper_trail.rb
27
+ - lib/sequel_paper_trail.rb
28
+ - lib/sequel_paper_trail/config.rb
29
+ - lib/sequel_paper_trail/version.rb
30
+ - spec/sequel/plugins/has_paper_trail_spec.rb
31
+ - spec/sequel_paper_trail_spec.rb
32
+ - spec/spec_helper.rb
33
+ - spec/support/spec_paper_db.rb
34
+ homepage: https://github.com/lazebny/sequel_paper_trail
35
+ licenses:
36
+ - MIT
37
+ metadata: {}
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 1.9.3
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project:
54
+ rubygems_version: 2.6.6
55
+ signing_key:
56
+ specification_version: 4
57
+ summary: Sequel plugin for PaperTrail.
58
+ test_files:
59
+ - spec/sequel/plugins/has_paper_trail_spec.rb
60
+ - spec/support/spec_paper_db.rb
61
+ - spec/spec_helper.rb
62
+ - spec/sequel_paper_trail_spec.rb