1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
#
# For users with login '*test_user*', we don't want to store these documents in
# the main users db. This is because we create and destroy a lot of test
# users. This weirdness of using a different db for some users breaks a lot of
# things, such as associations. However, this is OK for now since we don't need
# those for running the frequent nagios tests.
#
# This module is included in user.rb. This will only work if it is included
# after designs are defined, otherwise, the design definition will overwrite
# find_by_login().
#
module TemporaryUser
extend ActiveSupport::Concern
include CouchRest::Model::DatabaseMethod
USER_DB = 'users'
TMP_USER_DB = 'tmp_users'
TMP_LOGIN = 'tmp_user' # created and deleted frequently
TEST_LOGIN = 'test_user' # created, rarely deleted
included do
use_database_method :db_name
# since the original find_by_login is dynamically created with
# instance_eval, it appears that we also need to use instance eval to
# override it.
instance_eval <<-EOS, __FILE__, __LINE__ + 1
def find_by_login(*args)
if args.grep(/^#{TMP_LOGIN}/).any?
by_login.database(tmp_database).key(*args).first()
else
by_login.key(*args).first()
end
end
EOS
end
module ClassMethods
def get(id, db = database)
super(id, db) || super(id, tmp_database)
end
alias :find :get
# calls db_name(TMP_LOGIN), then creates a CouchRest::Database
# from the name
def tmp_database
choose_database(TMP_LOGIN)
end
def db_name(login=nil)
if !login.nil? && login.include?(TMP_LOGIN)
TMP_USER_DB
else
USER_DB
end
end
# create the tmp db if it doesn't exist.
# requires admin access.
def create_tmp_database!
design_doc.sync!(tmp_database.tap{|db|db.create!})
end
def is_tmp?(login)
!login.nil? && login =~ /^#{TMP_LOGIN}/
end
def is_test?(login)
!login.nil? && (login =~ /^#{TMP_LOGIN}/ || login =~ /^#{TEST_LOGIN}/)
end
end
#
# this gets called each and every time a User object needs to
# access the database.
#
def db_name
self.class.db_name(self.login)
end
# returns true if this User instance is stored in tmp db.
def is_tmp?
self.class.is_tmp?(self.login)
end
# returns true if this user is used for testing purposes
# (either a temporary or long lived)
def is_test?
self.class.is_test?(self.login)
end
end
|