mcfly 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|