transaction_timestamps 0.1.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 +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +6 -0
- data/lib/transaction_timestamps.rb +6 -0
- data/lib/transaction_timestamps/railtie.rb +11 -0
- data/lib/transaction_timestamps/timestamp.rb +71 -0
- data/lib/transaction_timestamps/version.rb +3 -0
- data/transaction_timestamps.gemspec +29 -0
- metadata +143 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c4a2761cfc95474cdb9dabc2a55e898083089229
|
4
|
+
data.tar.gz: 00d2179d119e1a9062e5a452bde77a27cbcdb522
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8e86ecbb39ac5b6bef6cf35a5cb8d42abc22ff5967617b46a36033ca96bdb82b929ddf01dcbb55e034fafdb1257e76fde87614dbb99abc6ca64126074f60e5d8
|
7
|
+
data.tar.gz: 9196bc25e8519a4c761169659659ef191ebf2213b2c989670e66110f01c0456a5c09d179f4eaa691f2a6b278c5c8c92e1fe0d901a7d1419732ce1e90d2898aeb
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
transaction_timestamps
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.3
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Coupa Software Inc
|
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,43 @@
|
|
1
|
+
# TransactionTimestamps
|
2
|
+
|
3
|
+
Transaction timestamps sets a Rails model's `created_at` and `updated_at` timestamps to the database transaction time,
|
4
|
+
rather than the current time. This is useful for aligning the timestamps of different models saved within a single
|
5
|
+
transaction to be exactly the same.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'transaction_timestamps'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle install
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install transaction_timestamps
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
In an initializer (eg. `config/initializers/transaction_timestamps.rb`), flag on transaction timestamps:
|
26
|
+
|
27
|
+
TransactionTimestamps.enabled = true
|
28
|
+
|
29
|
+
Any models created or updated within a transaction will then get the transaction timestamp.
|
30
|
+
|
31
|
+
Note: For postgresql databases, the timestamp is generated from a SQL query for the actual transaction time. For other
|
32
|
+
databases (where querying the transaction time is not supported), the current system time as of the first timestamping
|
33
|
+
event in the transaction is used.
|
34
|
+
|
35
|
+
## Contributing
|
36
|
+
|
37
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/coupa/transaction_timestamps.
|
38
|
+
|
39
|
+
|
40
|
+
## License
|
41
|
+
|
42
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
43
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
module TransactionTimestamps
|
2
|
+
mattr_accessor :enabled
|
3
|
+
|
4
|
+
module Timestamp
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
# override the original timestamp with one our own that returns transaction-based timestamps
|
8
|
+
alias_method :original_current_time_from_proper_timezone, :current_time_from_proper_timezone
|
9
|
+
def current_time_from_proper_timezone
|
10
|
+
if use_transaction_timestamps?
|
11
|
+
current_transaction_time
|
12
|
+
else
|
13
|
+
original_current_time_from_proper_timezone
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def current_transaction_time
|
20
|
+
if new_transaction?
|
21
|
+
@@cached_timestamp = adjust_time_to_timezone(db_transaction_time)
|
22
|
+
else
|
23
|
+
@@cached_timestamp
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def use_transaction_timestamps?
|
29
|
+
# Timecop doesn't play well transaction timestamps, so don't enable them when using Timecop
|
30
|
+
# and the time is frozen
|
31
|
+
TransactionTimestamps.enabled &&
|
32
|
+
!(defined?(Timecop) && Timecop.frozen?)
|
33
|
+
end
|
34
|
+
|
35
|
+
def new_transaction?
|
36
|
+
# check whether the transaction object id has changed since the last time we checked
|
37
|
+
current_transaction_id = transaction_id
|
38
|
+
is_new = !defined?(@@prev_transaction_id) || (current_transaction_id != @@prev_transaction_id)
|
39
|
+
@@prev_transaction_id = current_transaction_id
|
40
|
+
|
41
|
+
is_new
|
42
|
+
end
|
43
|
+
|
44
|
+
def transaction_id
|
45
|
+
# use the transaction object id as a unique identifier for whether the transaction has changed
|
46
|
+
manager = ActiveRecord::Base.connection.instance_variable_get(:@transaction_manager)
|
47
|
+
manager.current_transaction.object_id
|
48
|
+
end
|
49
|
+
|
50
|
+
def db_transaction_time
|
51
|
+
if postgresql?
|
52
|
+
time_str = ActiveRecord::Base.connection.select_one("SELECT transaction_timestamp();")['transaction_timestamp']
|
53
|
+
Time.parse(time_str)
|
54
|
+
else
|
55
|
+
# other databases (MySQL, sqlite) don't support retrieval of the actual transaction time, so the best we can
|
56
|
+
# do is to use the current system time (and cache this until the transaction changes)
|
57
|
+
Time.now
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def postgresql?
|
62
|
+
defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) &&
|
63
|
+
ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
|
64
|
+
end
|
65
|
+
|
66
|
+
def adjust_time_to_timezone(time)
|
67
|
+
# do exactly the same time adjustment as performed in ActiveRecord::Timestamp
|
68
|
+
self.class.default_timezone == :utc ? time.utc : time.getlocal
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'transaction_timestamps/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "transaction_timestamps"
|
8
|
+
spec.version = TransactionTimestamps::VERSION
|
9
|
+
spec.authors = ["Kent Mewhort @ Coupa"]
|
10
|
+
spec.email = ["kent.mewhort@coupa.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Timestamp created_at and updated_at with the database transaction time}
|
13
|
+
spec.description = %q{Keeps the timestamps for all models created or updated in at transaction the same}
|
14
|
+
spec.homepage = "https://github.com/coupa/transaction_timestamps"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
|
23
|
+
spec.add_dependency "activerecord", "~> 4.0"
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.11"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
+
spec.add_development_dependency "sqlite3", "~> 1.0"
|
28
|
+
spec.add_development_dependency "combustion", "~> 0.5.0"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: transaction_timestamps
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kent Mewhort @ Coupa
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.11'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.11'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sqlite3
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: combustion
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.5.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.5.0
|
97
|
+
description: Keeps the timestamps for all models created or updated in at transaction
|
98
|
+
the same
|
99
|
+
email:
|
100
|
+
- kent.mewhort@coupa.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- ".rspec"
|
107
|
+
- ".ruby-gemset"
|
108
|
+
- ".ruby-version"
|
109
|
+
- ".travis.yml"
|
110
|
+
- Gemfile
|
111
|
+
- LICENSE.txt
|
112
|
+
- README.md
|
113
|
+
- Rakefile
|
114
|
+
- lib/transaction_timestamps.rb
|
115
|
+
- lib/transaction_timestamps/railtie.rb
|
116
|
+
- lib/transaction_timestamps/timestamp.rb
|
117
|
+
- lib/transaction_timestamps/version.rb
|
118
|
+
- transaction_timestamps.gemspec
|
119
|
+
homepage: https://github.com/coupa/transaction_timestamps
|
120
|
+
licenses:
|
121
|
+
- MIT
|
122
|
+
metadata: {}
|
123
|
+
post_install_message:
|
124
|
+
rdoc_options: []
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubyforge_project:
|
139
|
+
rubygems_version: 2.4.5.1
|
140
|
+
signing_key:
|
141
|
+
specification_version: 4
|
142
|
+
summary: Timestamp created_at and updated_at with the database transaction time
|
143
|
+
test_files: []
|