sakai-info 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,7 @@
2
2
  # SakaiInfo::User library
3
3
  #
4
4
  # Created 2012-02-17 daveadams@gmail.com
5
- # Last updated 2012-02-17 daveadams@gmail.com
5
+ # Last updated 2012-02-24 daveadams@gmail.com
6
6
  #
7
7
  # https://github.com/daveadams/sakai-info
8
8
  #
@@ -17,31 +17,50 @@ module SakaiInfo
17
17
  @@cache = {}
18
18
  def self.find(id)
19
19
  if @@cache[id].nil?
20
- user_id = eid = nil
21
- DB.connect.exec("select user_id, eid from sakai_user_id_map " +
22
- "where user_id=:user_id or eid=:eid", id, id) do |row|
23
- user_id = row[0]
24
- eid = row[1]
25
- end
26
- if user_id.nil? or eid.nil?
20
+ eid = User.get_eid(id)
21
+ user_id = User.get_user_id(id)
22
+ if eid.nil? or user_id.nil?
27
23
  raise ObjectNotFoundException.new(User, id)
28
24
  end
29
25
 
30
- DB.connect.exec("select first_name, last_name, type, " +
31
- "to_char(createdon,'YYYY-MM-DD HH24:MI:SS'), " +
32
- "to_char(modifiedon,'YYYY-MM-DD HH24:MI:SS') " +
33
- "from sakai_user where user_id=:userid", user_id) do |row|
34
- first_name, last_name, type, created_at, modified_at = *row
35
- first_name ||= ""
36
- last_name ||= ""
37
- @@cache[eid] =
38
- @@cache[user_id] =
39
- User.new(user_id, eid, (first_name+' '+last_name), type, created_at, modified_at)
26
+ row = DB.connect.fetch("select first_name, last_name, type, " +
27
+ "to_char(createdon,'YYYY-MM-DD HH24:MI:SS') as created_at, " +
28
+ "to_char(modifiedon,'YYYY-MM-DD HH24:MI:SS') as modified_at " +
29
+ "from sakai_user where user_id=?", user_id).first
30
+ if row.nil?
31
+ raise ObjectNotFoundException.new(User, id)
40
32
  end
33
+ @@cache[eid] =
34
+ @@cache[user_id] =
35
+ User.new(user_id, eid,
36
+ ((row[:first_name] || "") + " " + (row[:last_name] || "")).strip,
37
+ row[:type], row[:created_at], row[:modified_at])
41
38
  end
42
39
  @@cache[id]
43
40
  end
44
41
 
42
+ @@id_cache = {}
43
+ def self.get_ids(id)
44
+ @@id_cache[id] ||=
45
+ DB.connect[:sakai_user_id_map].where({:user_id => id, :eid => id}.sql_or).first
46
+ end
47
+
48
+ def self.get_eid(id)
49
+ if ids = User.get_ids(id)
50
+ ids[:eid]
51
+ else
52
+ nil
53
+ end
54
+ end
55
+
56
+ def self.get_user_id(id)
57
+ if ids = User.get_ids(id)
58
+ ids[:user_id]
59
+ else
60
+ nil
61
+ end
62
+ end
63
+
45
64
  def initialize(id, eid, name, type, created_at, modified_at)
46
65
  @id = id
47
66
  @eid = eid
@@ -102,56 +121,46 @@ module SakaiInfo
102
121
 
103
122
  def preferences_xml
104
123
  if @preferences_xml.nil?
105
- db = DB.connect
106
124
  @preferences_xml = ""
107
- db.exec("select xml from sakai_preferences " +
108
- "where preferences_id=:userid", @user_id) do |row|
109
- REXML::Document.new(row[0].read).write(@preferences_xml, 2)
125
+ row = DB.connect[:sakai_preferences].filter(:preferences_id => @user_id).first
126
+ if not row.nil?
127
+ REXML::Document.new(row[:xml].read).write(@preferences_xml, 2)
110
128
  end
111
129
  end
112
130
  @preferences_xml
113
131
  end
114
132
 
115
133
  # finders/counters
116
- @@total_user_count = nil
117
134
  def self.count
118
- if @@total_user_count.nil?
119
- @@total_user_count = 0
120
- DB.connect.exec("select count(*) from sakai_user") do |row|
121
- @@total_user_count = row[0].to_i
122
- end
123
- end
124
- @@total_user_count
135
+ DB.connect[:sakai_user].count
125
136
  end
126
137
 
127
138
  def self.count_by_realm_id_and_role_id(realm_id, role_id)
128
- count = 0
129
- DB.connect.exec("select count(*) from sakai_realm_rl_gr " +
130
- "where realm_key = :realm_id " +
131
- "and role_key = :role_id", realm_id, role_id) do |row|
132
- count = row[0].to_i
133
- end
134
- count
139
+ DB.connect[:sakai_realm_rl_gr].
140
+ filter(:realm_key => realm_id, :role_key => role_id).count
135
141
  end
136
142
 
137
143
  def self.find_by_realm_id_and_role_id(realm_id, role_id)
138
- users = []
139
- DB.connect.exec("select first_name, last_name, type, " +
140
- "to_char(createdon,'YYYY-MM-DD HH24:MI:SS'), " +
141
- "to_char(modifiedon,'YYYY-MM-DD HH24:MI:SS') " +
142
- "from sakai_user where user_id in " +
143
- "(select user_id from sakai_realm_rl_gr " +
144
- "where realm_key = :realm_id " +
145
- "and role_key = :role_id)", realm_id, role_id) do |row|
146
- first_name, last_name, type, created_at, modified_at = *row
147
- first_name ||= ""
148
- last_name ||= ""
149
- @@cache[eid] =
150
- @@cache[user_id] =
151
- User.new(user_id, eid, (first_name+' '+last_name), type, created_at, modified_at)
152
- users << @@cache[eid]
153
- end
154
- users
144
+ # TODO: implement this correctly
145
+ # (code below isn't going to work)
146
+ # users = []
147
+ # DB.connect.fetch("select first_name, last_name, type, " +
148
+ # "to_char(createdon,'YYYY-MM-DD HH24:MI:SS') as created_at, " +
149
+ # "to_char(modifiedon,'YYYY-MM-DD HH24:MI:SS') as modified_at " +
150
+ # "from sakai_user where user_id in " +
151
+ # "(select user_id from sakai_realm_rl_gr " +
152
+ # "where realm_key = ? " +
153
+ # "and role_key = ?)", realm_id, role_id) do |row|
154
+ # first_name, last_name, type, created_at, modified_at = *row
155
+ # first_name ||= ""
156
+ # last_name ||= ""
157
+ # @@cache[eid] =
158
+ # @@cache[user_id] =
159
+ # User.new(user_id, eid, (first_name+' '+last_name), type, created_at, modified_at)
160
+ # users << @@cache[eid]
161
+ # end
162
+ # users
163
+ nil
155
164
  end
156
165
 
157
166
  # yaml/json serialization
@@ -177,13 +186,13 @@ module SakaiInfo
177
186
  }
178
187
  end
179
188
 
180
- def membership_serialization
189
+ def sites_serialization
181
190
  {
182
191
  "sites" => self.membership.collect { |sm| sm.serialize(:user_summary) }
183
192
  }
184
193
  end
185
194
 
186
- def question_pools_serialization
195
+ def pools_serialization
187
196
  if self.question_pool_count > 0
188
197
  {
189
198
  "question_pools" => self.question_pools.collect { |qp| qp.serialize(:user_summary) }
@@ -192,27 +201,27 @@ module SakaiInfo
192
201
  {}
193
202
  end
194
203
  end
204
+
205
+ def self.all_serializations
206
+ [:default, :sites, :pools]
207
+ end
195
208
  end
196
209
 
197
210
  class UserProperty
198
211
  def self.get(user_id, property_name)
199
- db = DB.connect
200
- value = nil
201
- db.exec("select value from sakai_user_property " +
202
- "where user_id=:user_id and name=:name", user_id, property_name) do |row|
203
- value = row[0].read
212
+ row = DB.connect[:sakai_user_property].
213
+ filter(:user_id => user_id, :name => property_name).first
214
+ if row.nil?
215
+ nil
216
+ else
217
+ row[:value].read
204
218
  end
205
- return value
206
219
  end
207
220
 
208
221
  def self.find_by_user_id(user_id)
209
- db = DB.connect
210
222
  properties = {}
211
- db.exec("select name, value from sakai_user_property " +
212
- "where user_id=:user_id", user_id) do |row|
213
- name = row[0]
214
- value = row[1].read
215
- properties[name] = value
223
+ DB.connect[:sakai_user_property].where(:user_id => user_id).all.each do |row|
224
+ properties[row[:name]] = row[:value].read
216
225
  end
217
226
  return properties
218
227
  end
@@ -1,3 +1,3 @@
1
1
  module SakaiInfo
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sakai-info
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - David Adams
@@ -15,10 +15,37 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-02-19 00:00:00 -06:00
18
+ date: 2012-02-24 00:00:00 -06:00
19
19
  default_executable:
20
- dependencies: []
21
-
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: sequel
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: sqlite3
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
22
49
  description: A command line tool and a suite of libraries for representing the objects and relationships defined by a Sakai CLE database.
23
50
  email: daveadams@gmail.com
24
51
  executables:
@@ -40,12 +67,10 @@ files:
40
67
  - lib/sakai-info/user.rb
41
68
  - lib/sakai-info/version.rb
42
69
  - lib/sakai-info/announcement.rb
70
+ - lib/sakai-info/database.rb
43
71
  - lib/sakai-info/cli.rb
44
- - lib/sakai-info/instance.rb
45
- - lib/sakai-info/configuration.rb
46
72
  - lib/sakai-info/message.rb
47
73
  - lib/sakai-info/content.rb
48
- - lib/sakai-info/db.rb
49
74
  - lib/sakai-info/sakai_xml_entity.rb
50
75
  - bin/sakai-info
51
76
  - README.md
@@ -54,8 +79,8 @@ files:
54
79
  - ROADMAP.md
55
80
  has_rdoc: true
56
81
  homepage: https://github.com/daveadams/sakai-info
57
- licenses: []
58
-
82
+ licenses:
83
+ - Public Domain
59
84
  post_install_message:
60
85
  rdoc_options: []
61
86
 
@@ -1,288 +0,0 @@
1
- # sakai-info/configuration.rb
2
- # SakaiInfo::Configuration library
3
- #
4
- # Created 2012-02-15 daveadams@gmail.com
5
- # Last updated 2012-02-19 daveadams@gmail.com
6
- #
7
- # https://github.com/daveadams/sakai-info
8
- #
9
- # This software is public domain.
10
- #
11
-
12
- module SakaiInfo
13
- class NoConfigFoundException < SakaiException; end
14
- class AlreadyConfiguredException < SakaiException; end
15
- class InvalidInstanceNameException < SakaiException; end
16
- class InvalidConfigException < SakaiException; end
17
- class UnsupportedConfigException < InvalidConfigException; end
18
- class MultipleConfigException < InvalidConfigException
19
- def initialize
20
- @exceptions = []
21
- end
22
-
23
- def add(instance_name, exception)
24
- @exceptions << [instance_name, exception]
25
- end
26
-
27
- def count
28
- @exceptions.length
29
- end
30
-
31
- def message
32
- "Multiple config exceptions were found:\n " +
33
- @exceptions.collect{ |e| "#{e[0]}: #{e[1].message}" }.join("\n ")
34
- end
35
- end
36
-
37
- # config format assumptions:
38
- # a YAML string containing one of the following options:
39
- # - a single database connection spec
40
- # - eg:
41
- # ---
42
- # dbtype: oracle
43
- # dbsid: PROD
44
- # username: sakai
45
- # password: Sekrit1
46
- # OR:
47
- # - an "instances" key containing a hash of named connection specs
48
- # - with a "default" key naming the spec to use if none is specified
49
- # - eg:
50
- # ---
51
- # default: production
52
- # instances:
53
- # production:
54
- # dbtype: oracle
55
- # service: PROD
56
- # username: sakai
57
- # password: prodpass
58
- # test:
59
- # dbtype: oracle
60
- # service: TEST
61
- # host: testdb.host
62
- # port: 1521
63
- # username: sakai
64
- # password: testpass
65
- # dev:
66
- # dbtype: mysql
67
- # host: dbserver.hostname.int
68
- # port: 3306
69
- # username: sakai
70
- # password: ironchef
71
- # dbname: sakaidev
72
- # localdev:
73
- # dbtype: mysql
74
- # host: localhost
75
- # port: 3306
76
- # username: sakai
77
- # password: ironchef
78
- # dbname: sakailocal
79
- #
80
- #
81
- # NOTES:
82
- # - Oracle connections should use either an alias defined in the
83
- # driver's tnsnames.ora file, or specify the host and port as the
84
- # test instance example above does
85
- #
86
- class Configuration
87
- @@config = nil
88
-
89
- # validate just a single database connection configuration hash
90
- def self.validate_single_connection_config(config)
91
- if config.nil?
92
- raise InvalidConfigException.new("The config provided was nil")
93
- end
94
-
95
- if not config.is_a? Hash
96
- raise InvalidConfigException.new("The config provided must be a Hash")
97
- end
98
-
99
- # we have to have a dbtype value or we can't validate
100
- if config["dbtype"].nil?
101
- raise InvalidConfigException.new("The config does not specify 'dbtype'")
102
- end
103
-
104
- # force lowercase to simplify comparisons
105
- dbtype = config["dbtype"].downcase
106
-
107
- if not %w(oracle mysql).include? dbtype
108
- raise UnsupportedConfigException.new("Database type '#{dbtype}' is not supported.")
109
- end
110
-
111
- # now check per-dbtype requirements
112
- if dbtype == "oracle"
113
- %w(service username password).each do |required_key|
114
- if config[required_key].nil? or config[required_key] == ""
115
- raise InvalidConfigException.new("Oracle config requires values for 'service', 'username', and 'password'.")
116
- end
117
- end
118
- elsif dbtype == "mysql"
119
- %w(host username password dbname).each do |required_key|
120
- if config[required_key].nil? or config[required_key] == ""
121
- raise InvalidConfigException.new("MySQL config requires values for 'host', 'username', 'password', and 'dbname'.")
122
- end
123
- end
124
- else
125
- # we should never have made it here
126
- raise UnsupportedConfigException.new("Database type '#{dbtype}' is not supported.")
127
- end
128
-
129
- # for both types, 'port' is optional but if it exists it must be a valid TCP port
130
- if not config["port"].nil?
131
- begin
132
- port = config["port"].to_i
133
- if port < 1 or port > 65535
134
- raise
135
- end
136
- rescue
137
- raise InvalidConfigException.new("Config value 'port' must be a valid TCP port number.")
138
- end
139
- end
140
-
141
- # if we made it here the config is complete and well-formed
142
- return true
143
- end
144
-
145
- # validate that configuration is complete and well-formed
146
- def self.validate_config(config)
147
- if config.nil?
148
- raise InvalidConfigException.new("The config provided was nil")
149
- end
150
-
151
- if not config.is_a? Hash
152
- raise InvalidConfigException.new("The config provided must be a Hash")
153
- end
154
-
155
- # if 'dbtype' exists, it will be a single database configuration
156
- if config["dbtype"]
157
- self.validate_single_connection_config(config)
158
- else
159
- # otherwise both 'default' and 'instances' keys are required
160
- if config.keys.sort != ["default","instances"]
161
- raise InvalidConfigException.new("The config must specify either 'dbtype' or both 'default' and 'instances'.")
162
- end
163
-
164
- # enforce types on the values of 'default' and 'instances'
165
- if not config["default"].is_a? String
166
- raise InvalidConfigException.new("The value of 'default' must be a String.")
167
- end
168
- if not config["instances"].is_a? Hash
169
- raise InvalidConfigException.new("The value of 'instances' must be a Hash.")
170
- end
171
-
172
- # 'default' must be a string pointing to one of the 'instances' keys
173
- if not config["instances"].keys.include? config["default"]
174
- raise InvalidConfigException.new("The default instance '#{config["default"]}' was not among the instance names given: #{config["instances"].keys.inspect}")
175
- end
176
-
177
- # check the validity of each instance, collecting exceptions as we go
178
- multi_exceptions = nil
179
- config["instances"].keys.each do |instance_name|
180
- begin
181
- self.validate_single_connection_config(config["instances"][instance_name])
182
- rescue InvalidConfigException => e
183
- # create the object if it doesn't already exist
184
- multi_exceptions ||= MultipleConfigException.new
185
-
186
- # add this exception to the list
187
- multi_exceptions.add(instance_name, e)
188
- end
189
- # continue the loop no matter what
190
- end
191
-
192
- # if this object was created, the exception needs to be raised
193
- if not multi_exceptions.nil?
194
- raise multi_exceptions
195
- end
196
- end
197
-
198
- # if we've made it this far, the configuration must be fine
199
- return true
200
- end
201
-
202
- def initialize(config)
203
- begin
204
- if config.is_a? Hash
205
- @config = config
206
- elsif config.is_a? String and File.exist?(config)
207
- # try to parse as a filename first
208
- if File.exist?(config)
209
- @config = YAML::load_file(config)
210
- end
211
- else
212
- # otherwise try to parse it generically
213
- @config = YAML::load(config)
214
- end
215
- rescue Exception => e
216
- raise InvalidConfigException.new("Unable to parse configuration: #{e}")
217
- end
218
-
219
- # check that the configuration specified is well formed
220
- if not Configuration.validate_config(@config)
221
- raise InvalidConfigException.new("Config provided is either incomplete or poorly formed.")
222
- end
223
-
224
- # create instance objects
225
- @instances = {}
226
- if not @config["instances"].nil?
227
- @config["instances"].keys.each do |instance_name|
228
- @instances[instance_name] = Instance.create(@config["instances"][instance_name])
229
- if instance_name == @config["default"]
230
- @instances[:default] = @instances[instance_name]
231
- end
232
- end
233
- else
234
- @instances[:default] = Instance.create(@config)
235
- end
236
- end
237
-
238
- # instance accessibility
239
- def get_instance(instance_name)
240
- @instances[instance_name] or raise InvalidInstanceNameException
241
- end
242
-
243
- def default_instance
244
- @instances[:default]
245
- end
246
-
247
- DEFAULT_CONFIG_FILE = File.expand_path("~/.sakai-info")
248
- # check to see if configuration file exists
249
- # by default ~/.sakai-info
250
- def self.config_file_path
251
- if File.readable? DEFAULT_CONFIG_FILE
252
- DEFAULT_CONFIG_FILE
253
- else
254
- nil
255
- end
256
- end
257
-
258
- # are we already configured?
259
- def self.configured?
260
- not @@config.nil?
261
- end
262
-
263
- # load configuration as a class variable (and return it as well)
264
- def self.load_config(alternate_config_file = nil)
265
- if Configuration.configured?
266
- raise AlreadyConfiguredException
267
- end
268
-
269
- unless(config_file = alternate_config_file || Configuration.config_file_path)
270
- raise NoConfigFoundException
271
- end
272
-
273
- @@config = Configuration.new(config_file)
274
- end
275
-
276
- # return specified database connection configuration
277
- def self.get_instance(instance_name = nil)
278
- Configuration.load_config unless Configuration.configured?
279
-
280
- if instance_name.nil?
281
- @@config.default_instance
282
- else
283
- @@config.get_instance(instance_name)
284
- end
285
- end
286
- end
287
- end
288
-