mcfly 0.0.4 → 0.0.5
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.
- data/README.md +7 -2
- data/lib/mcfly.rb +3 -0
- data/lib/mcfly/delete_trig.sql +7 -1
- data/lib/mcfly/has_mcfly.rb +12 -8
- data/lib/mcfly/insert_trig.sql +5 -0
- data/lib/mcfly/migration.rb +1 -0
- data/lib/mcfly/update_append_only_trig.sql +1 -0
- data/lib/mcfly/update_trig.sql +4 -1
- data/lib/mcfly/version.rb +1 -1
- data/spec/dummy/db/schema.rb +2 -0
- data/spec/model_spec.rb +34 -1
- metadata +2 -3
data/README.md
CHANGED
@@ -89,9 +89,14 @@ TODO: discuss using `current_user` method in `ApplicationController`. Also, sett
|
|
89
89
|
|
90
90
|
TODO
|
91
91
|
|
92
|
-
## Limitations
|
92
|
+
## Limitations/Requirements
|
93
93
|
|
94
|
-
Currently, Mcfly only works with PostgreSQL databases.
|
94
|
+
Currently, Mcfly only works with PostgreSQL databases. The following
|
95
|
+
line must be added to the `postgresql.conf` file. Mcfly uses the
|
96
|
+
PostgreSQL session variable `mcfly.whodunnit` to store the current
|
97
|
+
user id.
|
98
|
+
|
99
|
+
custom_variable_classes = 'mcfly'
|
95
100
|
|
96
101
|
## History
|
97
102
|
|
data/lib/mcfly.rb
CHANGED
data/lib/mcfly/delete_trig.sql
CHANGED
@@ -2,12 +2,18 @@ CREATE OR REPLACE FUNCTION "%{table}_delete" ()
|
|
2
2
|
RETURNS TRIGGER
|
3
3
|
AS $$
|
4
4
|
|
5
|
+
DECLARE
|
6
|
+
whodunnit int;
|
7
|
+
|
5
8
|
BEGIN
|
6
9
|
IF OLD.obsoleted_dt <> 'infinity' THEN
|
7
10
|
RAISE EXCEPTION 'can not delete old row version';
|
8
11
|
END IF;
|
9
12
|
|
10
|
-
|
13
|
+
SHOW mcfly.whodunnit INTO whodunnit;
|
14
|
+
|
15
|
+
UPDATE "%{table}"
|
16
|
+
SET "obsoleted_dt" = 'now()', "o_user_id" = whodunnit WHERE id = OLD.id;
|
11
17
|
|
12
18
|
RETURN NULL; -- the row is not actually deleted
|
13
19
|
END;
|
data/lib/mcfly/has_mcfly.rb
CHANGED
@@ -32,11 +32,14 @@ module McFly
|
|
32
32
|
# obsoleted_dt.
|
33
33
|
|
34
34
|
send :include, InstanceMethods
|
35
|
-
|
35
|
+
before_validation :record_validation
|
36
|
+
|
36
37
|
# FIXME: :created_dt should also be readonly. However, we set
|
37
38
|
# it for debugging purposes. Should consider making this
|
38
|
-
# readonly once we're in production.
|
39
|
-
|
39
|
+
# readonly once we're in production. Also, :user_id should be
|
40
|
+
# read-only. We should only set whodunnit and let PostgreSQL
|
41
|
+
# set it.
|
42
|
+
attr_readonly :group_id, :obsoleted_dt, :o_user_id #, :user_id
|
40
43
|
end
|
41
44
|
|
42
45
|
def mcfly_lookup(name, options = {}, &block)
|
@@ -78,11 +81,12 @@ module McFly
|
|
78
81
|
end
|
79
82
|
|
80
83
|
module InstanceMethods
|
81
|
-
def
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
84
|
+
def record_validation
|
85
|
+
if self.changed?
|
86
|
+
self.user_id = Mcfly.whodunnit.try(:id)
|
87
|
+
self.obsoleted_dt ||= 'infinity'
|
88
|
+
end
|
89
|
+
|
86
90
|
end
|
87
91
|
end
|
88
92
|
|
data/lib/mcfly/insert_trig.sql
CHANGED
@@ -25,3 +25,8 @@ $$ LANGUAGE plpgsql;
|
|
25
25
|
DROP TRIGGER IF EXISTS %{table}_insert ON %{table};
|
26
26
|
CREATE TRIGGER "%{table}_insert" BEFORE INSERT ON "%{table}" FOR EACH ROW
|
27
27
|
EXECUTE PROCEDURE "%{table}_insert"();
|
28
|
+
|
29
|
+
-- Add constraint to make sure o_user_id is set iff obsoleted_dt is
|
30
|
+
-- not infinity (i.e. object is obsoleted).
|
31
|
+
ALTER TABLE "%{table}" ADD CONSTRAINT check_o_user
|
32
|
+
CHECK ((obsoleted_dt = 'Infinity') = (o_user_id IS NULL));
|
data/lib/mcfly/migration.rb
CHANGED
data/lib/mcfly/update_trig.sql
CHANGED
@@ -5,6 +5,7 @@ DECLARE
|
|
5
5
|
rec "%{table}";
|
6
6
|
new_id INT4;
|
7
7
|
now timestamp;
|
8
|
+
whodunnit int;
|
8
9
|
|
9
10
|
BEGIN
|
10
11
|
IF OLD.obsoleted_dt <> 'infinity' THEN
|
@@ -15,6 +16,7 @@ BEGIN
|
|
15
16
|
-- obsoleted. We return the OLD row so that other field updates are
|
16
17
|
-- ignored. This is used by DELETE.
|
17
18
|
IF NEW.obsoleted_dt <> 'infinity' THEN
|
19
|
+
OLD.o_user_id = NEW.o_user_id;
|
18
20
|
OLD.obsoleted_dt = NEW.obsoleted_dt;
|
19
21
|
return OLD;
|
20
22
|
END IF;
|
@@ -31,7 +33,8 @@ BEGIN
|
|
31
33
|
|
32
34
|
rec.id = new_id;
|
33
35
|
rec.group_id = NEW.id;
|
34
|
-
|
36
|
+
rec.o_user_id = NEW.user_id;
|
37
|
+
|
35
38
|
-- FIXME: The following IF/ELSE handles cases where created_dt is
|
36
39
|
-- sent in on update. This is only useful for debugging. Consider
|
37
40
|
-- removing the surronding IF (and ELSE part) for production
|
data/lib/mcfly/version.rb
CHANGED
data/spec/dummy/db/schema.rb
CHANGED
@@ -18,6 +18,7 @@ ActiveRecord::Schema.define(:version => 2) do
|
|
18
18
|
t.datetime "created_dt", :null => false
|
19
19
|
t.datetime "obsoleted_dt", :null => false
|
20
20
|
t.integer "user_id", :null => false
|
21
|
+
t.integer "o_user_id"
|
21
22
|
t.integer "security_instrument_id", :null => false
|
22
23
|
t.decimal "coupon", :null => false
|
23
24
|
t.integer "settlement_mm", :null => false
|
@@ -30,6 +31,7 @@ ActiveRecord::Schema.define(:version => 2) do
|
|
30
31
|
t.datetime "created_dt", :null => false
|
31
32
|
t.datetime "obsoleted_dt", :null => false
|
32
33
|
t.integer "user_id", :null => false
|
34
|
+
t.integer "o_user_id"
|
33
35
|
t.string "name", :null => false
|
34
36
|
t.string "settlement_class", :limit => 1, :null => false
|
35
37
|
end
|
data/spec/model_spec.rb
CHANGED
@@ -182,7 +182,7 @@ describe "Mcfly" do
|
|
182
182
|
|
183
183
|
it "should be able to delete objects" do
|
184
184
|
si = SecurityInstrument.find_by_name("FN Fix-30 Cash")
|
185
|
-
dt =
|
185
|
+
dt = '2010-01-01 08:00 PST8PDT'
|
186
186
|
|
187
187
|
mp = MarketPrice.lookup_si(dt, si)
|
188
188
|
mp.obsoleted_dt.should == Float::INFINITY
|
@@ -203,4 +203,37 @@ describe "Mcfly" do
|
|
203
203
|
}.should raise_error(ActiveRecord::StatementInvalid)
|
204
204
|
end
|
205
205
|
|
206
|
+
it "whodunnit should set user/o_user on CRUD" do
|
207
|
+
Mcfly.whodunnit = TestUser.new(20)
|
208
|
+
|
209
|
+
si = SecurityInstrument.find_by_name("FN Fix-30 Cash")
|
210
|
+
dt = '2010-01-01 08:00 PST8PDT'
|
211
|
+
|
212
|
+
sleep 1.seconds
|
213
|
+
|
214
|
+
mp = MarketPrice.lookup_si(dt, si)
|
215
|
+
mp.user_id.should == 10
|
216
|
+
|
217
|
+
mp.price = 123
|
218
|
+
mp.save!
|
219
|
+
|
220
|
+
# old version should still have original creator user
|
221
|
+
mp = MarketPrice.lookup_si(dt, si)
|
222
|
+
mp.user_id.should == 10
|
223
|
+
mp.o_user_id.should == 20
|
224
|
+
|
225
|
+
# new version should have new creator
|
226
|
+
mp = MarketPrice.lookup_si('infinity', si)
|
227
|
+
mp.user_id.should == 20
|
228
|
+
mp.o_user_id.should == nil
|
229
|
+
|
230
|
+
rid = mp.id
|
231
|
+
|
232
|
+
Mcfly.whodunnit = TestUser.new(30)
|
233
|
+
|
234
|
+
mp.delete
|
235
|
+
mp = MarketPrice.find(rid)
|
236
|
+
mp.o_user_id.should == 30
|
237
|
+
end
|
238
|
+
|
206
239
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mcfly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-06-
|
12
|
+
date: 2013-06-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -148,7 +148,6 @@ files:
|
|
148
148
|
- spec/dummy/db/schema.rb
|
149
149
|
- spec/dummy/lib/assets/.gitkeep
|
150
150
|
- spec/dummy/log/.gitkeep
|
151
|
-
- spec/dummy/log/development.log
|
152
151
|
- spec/dummy/public/404.html
|
153
152
|
- spec/dummy/public/422.html
|
154
153
|
- spec/dummy/public/500.html
|