changebase 0.0.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7d9aa3e35e3c305c7d25abca6c5fb16e67277713afccabe5673c3fafab819fa8
4
- data.tar.gz: 8e1dc477d0122ae4bb24164f9deeaaed8916cfca94cc430fac47fc707a22e5d8
3
+ metadata.gz: dcaf7190bcd66bca83640222cc52f2bae125b65b9008c26c9e8dac4c88c35226
4
+ data.tar.gz: '099666dc5717843cf99230a8a22c51fed5568ef93b4aa550928621a29d8a3e72'
5
5
  SHA512:
6
- metadata.gz: 3be0b99793e34d274783aa55bea767fe5dd1ec660ab72366b616a112402e40b7ad5ff5d4012e02a9dc2b6bf097f1633e715fd9669b58f548e26bba86d1ec3bf2
7
- data.tar.gz: 30080425de141719518fe2c7cb3ceeefef0ecfc22f9491ff105ac6b52fbfce8529cbc433ca372232391a1a1fc6d81bdd4007a2e72f86dc12a2e64565636edfeb
6
+ metadata.gz: 0b3dc117e4516d95e353b2e4e4ad076020815e37c88a6c256bb40ca1633ff5a487b692ac49331a203e8c6f519c46523c20e231e1cee768078c007666dea23d35
7
+ data.tar.gz: f0915103e19c8966675d21d40b7091d62eb4eb97f686b92fc98087fe8277e3ef94ace4a3524ded170ead1cbd4f6d06395a03b6737fd937ca20edf4365a3225c3
data/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # Changebase Ruby Library
2
+
3
+ The Changebase Ruby library provides convenient access to the Changebase API from
4
+ applications written in the Ruby language.
5
+
6
+ ## Installation
7
+
8
+ ```sh
9
+ gem install changebase
10
+ ```
11
+
12
+ If you are installing via bundler:
13
+
14
+ ```ruby
15
+ gem "changebase"
16
+ ```
17
+
18
+ ## Rails
19
+
20
+ Once you install the Gem run your migration to autmatically create the metadata
21
+ table for your database by runing:
22
+
23
+ `rails db:migrate`
24
+
25
+ ### ActionController
26
+
27
+ In a controller you can use the following to log metadata with all updates during
28
+ a request:
29
+
30
+ ```ruby
31
+ class ApplicationController < ActionController::Base
32
+ changebase do
33
+ {
34
+ request_id: request.uuid,
35
+ user: {
36
+ id: current_user.id
37
+ }
38
+ }
39
+ end
40
+ end
41
+ ```
42
+
43
+ The `changebase` function can be called multiple times to include various data.
44
+ To nest a value simply give it all the keys so it knows where to bury the value.
45
+
46
+ Below are several diffent way of including metadata:
47
+
48
+ ```ruby
49
+ class ApplicationController < ActionController::Base
50
+
51
+ # Just a block returning a hash of metadata.
52
+ changebase do
53
+ { my: data }
54
+ end
55
+
56
+ # Sets `release` in the metadata to the string RELEASE_SHA
57
+ changebase :release, RELEASE_SHA
58
+
59
+ # Sets `request_id` in the metadata to the value returned from the `Proc`
60
+ changebase :request_id, -> { request.uuid }
61
+
62
+ # Sets `user.id` in the metadata to the value returned from the
63
+ # `current_user_id` function
64
+ changebase :user, :id, :current_user_id
65
+
66
+ # Sets `user.name` in the metadata to the value returned from the block
67
+ changebase :user, :name do
68
+ current_user.name
69
+ end
70
+
71
+ def current_user_id
72
+ current_user.id
73
+ end
74
+ end
75
+ ```
76
+
77
+ In the above example the following would be logged with all database changes:
78
+
79
+ ```ruby
80
+ {
81
+ release: 'd5db29cd03a2ed055086cef9c31c252b4587d6d0',
82
+ request_id: 'a39073a5-10b9-41b7-b5f0-06806853507b',
83
+ user: {
84
+ id: 'f06114cc-7819-4906-85dc-b93edb0fb08c',
85
+ name: 'Tom'
86
+ }
87
+ }
88
+ ```
89
+
90
+ ### ActiveRecord
91
+
92
+ To include metadata when creating or modifying data with ActiveRecord:
93
+
94
+ ```ruby
95
+ ActiveRecord::Base.with_metadata({user: {name: 'Tom'}}) do
96
+ @post.update(title: "A new beging")
97
+ end
98
+ ```
99
+
100
+ ### Configuration
101
+
102
+ To configure the metadata table that Changebase writes to create a initializer
103
+ at `config/initializers/changebase.rb` with the following:
104
+
105
+ ```ruby
106
+ Rails.application.config.tap do |config|
107
+ config.changebase.metadata_table = "my_very_cool_custom_metadata_table"
108
+ end
109
+ ```
110
+
111
+ If you are not using Rails you can configure Changebase directly via:
112
+
113
+ ```ruby
114
+ Changebase.metadata_table = "my_very_cool_custom_metadata_table"
115
+ ```
116
+
117
+ ## Bugs
118
+
119
+ If you think you found a bug, please file a ticket on the [issue
120
+ tracker](https://github.com/changebase-io/ruby-gem/issues).
@@ -0,0 +1,18 @@
1
+ class CreateChangebaseMetadataTable < ActiveRecord::Migration[6.0]
2
+
3
+ def up
4
+ table = Rails.application.config.changebase.metadata_table
5
+
6
+ if !ActiveRecord::Base.connection.table_exists?(table)
7
+ create_table table, id: false do |t|
8
+ t.primary_key :version, :integer
9
+ t.jsonb :data
10
+ end
11
+ end
12
+ end
13
+
14
+ def down
15
+ drop_table(Rails.application.config.changebase.metadata_table)
16
+ end
17
+
18
+ end
@@ -0,0 +1,72 @@
1
+ module Changebase::ActionController
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ prepend_around_action :changebase_metadata_wrapper
6
+ end
7
+
8
+ module ClassMethods
9
+ def changebase(*keys, &block)
10
+ method = if block
11
+ block
12
+ elsif keys.size > 1
13
+ keys.pop
14
+ else
15
+ keys.first
16
+ end
17
+
18
+ @changebase_metadata ||= []
19
+ @changebase_metadata << [keys, method]
20
+ end
21
+
22
+ def changebase_metadata
23
+ klass_metadata = if instance_variable_defined?(:@changebase_metadata)
24
+ @changebase_metadata
25
+ else
26
+ []
27
+ end
28
+
29
+ if self.superclass.respond_to?(:changebase_metadata)
30
+ klass_metadata + self.superclass.changebase_metadata
31
+ else
32
+ klass_metadata
33
+ end
34
+ end
35
+ end
36
+
37
+ def changebase_metadata
38
+ self.class.changebase_metadata
39
+ end
40
+
41
+ def changebase_metadata_wrapper(&block)
42
+ metadata = {}
43
+
44
+ changebase_metadata.each do |keys, value|
45
+ data = metadata
46
+ keys[0...-1].each do |key|
47
+ data[key] ||= {}
48
+ data = data[key]
49
+ end
50
+
51
+ value = case value
52
+ when Symbol
53
+ self.send(value)
54
+ when Proc
55
+ instance_exec(&value)
56
+ else
57
+ value
58
+ end
59
+
60
+ if keys.last
61
+ data[keys.last] ||= value
62
+ else
63
+ data.merge!(value)
64
+ end
65
+ end
66
+
67
+ ActiveRecord::Base.with_metadata(metadata, &block)
68
+ end
69
+
70
+ end
71
+
72
+ ActionController::Base.include(Changebase::ActionController)
@@ -0,0 +1,106 @@
1
+ module Changebase::ActiveRecord
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ def with_metadata(metadata, &block)
6
+ connection.with_metadata(metadata, &block)
7
+ end
8
+ end
9
+
10
+ def with_metadata(metadata, &block)
11
+ self.class.with_metadata(metadata, &block)
12
+ end
13
+ end
14
+
15
+ module Changebase::ActiveRecord::Connection
16
+
17
+ def with_metadata(metadata, &block)
18
+ @changebase_metadata = metadata
19
+ yield
20
+ ensure
21
+ @changebase_metadata = nil
22
+ end
23
+
24
+ end
25
+
26
+ module Changebase::ActiveRecord::PostgreSQLAdapter
27
+
28
+ def initialize(*args, **margs)
29
+ @without_changebase = false
30
+ @changebase_metadata = nil
31
+ super
32
+ end
33
+
34
+ def without_changebase
35
+ @without_changebase = true
36
+ yield
37
+ ensure
38
+ @without_changebase = false
39
+ end
40
+
41
+ def drop_database(name) # :nodoc:
42
+ without_changebase { super }
43
+ end
44
+
45
+ def drop_table(table_name, **options) # :nodoc:
46
+ without_changebase { super }
47
+ end
48
+
49
+ def create_database(name, options = {})
50
+ without_changebase { super }
51
+ end
52
+
53
+ def recreate_database(name, options = {}) # :nodoc:
54
+ without_changebase { super }
55
+ end
56
+
57
+ def execute(sql, name = nil)
58
+ if !@without_changebase && !current_transaction.open? && write_query?(sql)
59
+ transaction { super }
60
+ else
61
+ super
62
+ end
63
+ end
64
+
65
+ def exec_query(sql, name = "SQL", binds = [], prepare: false)
66
+ if !@without_changebase && !current_transaction.open? && write_query?(sql)
67
+ transaction { super }
68
+ else
69
+ super
70
+ end
71
+ end
72
+
73
+ def exec_delete(sql, name = nil, binds = []) # :nodoc:
74
+ if !@without_changebase && !current_transaction.open? && write_query?(sql)
75
+ transaction { super }
76
+ else
77
+ super
78
+ end
79
+ end
80
+
81
+ def commit_db_transaction
82
+ if !@without_changebase && @changebase_metadata && !@changebase_metadata.empty?
83
+ sql = ActiveRecord::Base.send(:replace_named_bind_variables, <<~SQL, {version: 1, metadata: ActiveSupport::JSON.encode(@changebase_metadata)})
84
+ INSERT INTO #{quote_table_name(Changebase.metadata_table)} ( version, data )
85
+ VALUES ( :version, :metadata )
86
+ ON CONFLICT ( version )
87
+ DO UPDATE SET version = :version, data = :metadata;
88
+ SQL
89
+
90
+ log(sql, "CHANGEBASE") do
91
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
92
+ @connection.async_exec(sql)
93
+ end
94
+ end
95
+ end
96
+ super
97
+ end
98
+
99
+ end
100
+
101
+ require 'active_record'
102
+ ActiveRecord::Base.include(Changebase::ActiveRecord)
103
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.include(Changebase::ActiveRecord::Connection)
104
+
105
+ require 'active_record/connection_adapters/postgresql_adapter'
106
+ ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.include(Changebase::ActiveRecord::PostgreSQLAdapter)
@@ -0,0 +1,23 @@
1
+ class Changebase::Engine < ::Rails::Engine
2
+
3
+ config.changebase = ActiveSupport::OrderedOptions.new
4
+ config.changebase.metadata_table = "changebase_metadata"
5
+
6
+ initializer :changebase do |app|
7
+ migration_paths = config.paths['db/migrate'].expanded
8
+
9
+ ActiveSupport.on_load(:active_record) do
10
+ require 'changebase/active_record'
11
+ migration_paths.each do |path|
12
+ ActiveRecord::Tasks::DatabaseTasks.migrations_paths << path
13
+ end
14
+ end
15
+
16
+ ActiveSupport.on_load(:action_controller) do
17
+ require 'changebase/action_controller'
18
+ end
19
+
20
+ Changebase.metadata_table = app.config.changebase.metadata_table
21
+ end
22
+
23
+ end
@@ -1,3 +1,3 @@
1
1
  module Changebase
2
- VERSION = '0.0.1'
2
+ VERSION = '0.1'
3
3
  end
data/lib/changebase.rb ADDED
@@ -0,0 +1,16 @@
1
+ module Changebase
2
+ autoload :ActiveRecord, 'changebase/active_record'
3
+ autoload :ActionController, 'changebase/action_controller'
4
+
5
+ @metadata_table = "changebase_metadata"
6
+
7
+ def self.metadata_table=(value)
8
+ @metadata_table = value
9
+ end
10
+
11
+ def self.metadata_table
12
+ @metadata_table
13
+ end
14
+ end
15
+
16
+ require 'changebase/railtie' if defined?(Rails)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: changebase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: '0.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Bracy
@@ -9,8 +9,68 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-12-29 00:00:00.000000000 Z
12
+ date: 2022-02-17 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '6'
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: '8'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ version: '6'
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '8'
34
+ - !ruby/object:Gem::Dependency
35
+ name: actionpack
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '6'
41
+ - - "<"
42
+ - !ruby/object:Gem::Version
43
+ version: '8'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '6'
51
+ - - "<"
52
+ - !ruby/object:Gem::Version
53
+ version: '8'
54
+ - !ruby/object:Gem::Dependency
55
+ name: railties
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '6'
61
+ - - "<"
62
+ - !ruby/object:Gem::Version
63
+ version: '8'
64
+ type: :runtime
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '6'
71
+ - - "<"
72
+ - !ruby/object:Gem::Version
73
+ version: '8'
14
74
  - !ruby/object:Gem::Dependency
15
75
  name: rake
16
76
  requirement: !ruby/object:Gem::Requirement
@@ -82,13 +142,69 @@ dependencies:
82
142
  - !ruby/object:Gem::Version
83
143
  version: '0'
84
144
  - !ruby/object:Gem::Dependency
85
- name: mini_mime
145
+ name: mocha
86
146
  requirement: !ruby/object:Gem::Requirement
87
147
  requirements:
88
148
  - - ">="
89
149
  - !ruby/object:Gem::Version
90
150
  version: '0'
91
- type: :runtime
151
+ type: :development
152
+ prerelease: false
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: faker
160
+ requirement: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ type: :development
166
+ prerelease: false
167
+ version_requirements: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - ">="
170
+ - !ruby/object:Gem::Version
171
+ version: '0'
172
+ - !ruby/object:Gem::Dependency
173
+ name: factory_bot
174
+ requirement: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ type: :development
180
+ prerelease: false
181
+ version_requirements: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ - !ruby/object:Gem::Dependency
187
+ name: simplecov
188
+ requirement: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ type: :development
194
+ prerelease: false
195
+ version_requirements: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - ">="
198
+ - !ruby/object:Gem::Version
199
+ version: '0'
200
+ - !ruby/object:Gem::Dependency
201
+ name: pg
202
+ requirement: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - ">="
205
+ - !ruby/object:Gem::Version
206
+ version: '0'
207
+ type: :development
92
208
  prerelease: false
93
209
  version_requirements: !ruby/object:Gem::Requirement
94
210
  requirements:
@@ -97,36 +213,44 @@ dependencies:
97
213
  version: '0'
98
214
  description: Ruby library for integrating with Changebase.io
99
215
  email:
100
- - jonbracy@gmail.com
101
- - waratuman@gmail.com
216
+ - jon@changebase.io
217
+ - james@changebase.io
102
218
  executables: []
103
219
  extensions: []
104
220
  extra_rdoc_files:
105
- - README.rdoc
221
+ - README.md
106
222
  files:
107
- - README.rdoc
223
+ - README.md
224
+ - db/migrate/20220217151934_create_changebase_metadata_table.rb
225
+ - lib/changebase.rb
226
+ - lib/changebase/action_controller.rb
227
+ - lib/changebase/active_record.rb
228
+ - lib/changebase/railtie.rb
108
229
  - lib/changebase/version.rb
109
230
  homepage: https://changebase.io
110
231
  licenses: []
111
- metadata: {}
232
+ metadata:
233
+ homepage_uri: https://changebase.io
234
+ source_code_uri: https://github.com/changebase-io/ruby-gem
235
+ bug_tracker_uri: https://github.com/changebase-io/ruby-gem/issues
112
236
  post_install_message:
113
237
  rdoc_options:
114
238
  - "--main"
115
- - README.rdoc
239
+ - README.md
116
240
  require_paths:
117
241
  - lib
118
242
  required_ruby_version: !ruby/object:Gem::Requirement
119
243
  requirements:
120
244
  - - ">="
121
245
  - !ruby/object:Gem::Version
122
- version: '0'
246
+ version: '2.7'
123
247
  required_rubygems_version: !ruby/object:Gem::Requirement
124
248
  requirements:
125
249
  - - ">="
126
250
  - !ruby/object:Gem::Version
127
251
  version: '0'
128
252
  requirements: []
129
- rubygems_version: 3.2.3
253
+ rubygems_version: 3.2.22
130
254
  signing_key:
131
255
  specification_version: 4
132
256
  summary: Changebase.io Client
data/README.rdoc DELETED
@@ -1,17 +0,0 @@
1
- = \Changebase Ruby Library
2
-
3
- The Changebase Ruby library provides convenient access to the Changebase API from
4
- applications written in the Ruby language.
5
-
6
- == Installation
7
-
8
- $ gem install changebase
9
-
10
- == Bugs
11
-
12
- If you think you found a bug, please file a ticket on the {issue
13
- tracker}[https://github.com/changebase-io/ruby-gem/issues].
14
-
15
- == License
16
-
17
- #TODO