pampa_workers 0.0.38

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.
@@ -0,0 +1,128 @@
1
+ module BlackStack
2
+
3
+ # no maneja conexion a la base de datos.
4
+ # ejecuta un loop mientras el metodo canRun? retorne true.
5
+ class MyRemoteProcess < BlackStack::MyChildProcess
6
+ #
7
+ attr_accessor :worker
8
+
9
+ # update worker configuration in the division
10
+ def updateWorker()
11
+ #
12
+ self.worker = BlackStack::RemoteWorker.new
13
+ # me notifico a la central. obtengo asignacion si ya la tenia
14
+ url = "#{BlackStack::Pampa::api_url}/api1.3/pampa/get.json"
15
+ res = BlackStack::Netting::call_post(url, {
16
+ 'api_key' => BlackStack::Pampa::api_key,
17
+ 'name' => self.fullWorkerName }.merge( BlackStack::RemoteHost.new.poll )
18
+ )
19
+ parsed = JSON.parse(res.body)
20
+ if (parsed['status'] != BlackStack::Netting::SUCCESS)
21
+ raise parsed['status'].to_s
22
+ else
23
+ self.worker.id = parsed['id']
24
+ self.worker.assigned_process = parsed['assigned_process']
25
+ self.worker.id_object = parsed['id_object']
26
+ self.worker.id_division = parsed['id_division']
27
+ self.worker.division_name = parsed['division_name']
28
+ self.worker.ws_url = parsed['ws_url']
29
+ self.worker.ws_port = parsed['ws_port']
30
+ self.worker.division = BlackStack::RemoteDivision.new
31
+ self.worker.division.name = parsed['division_name']
32
+ end
33
+ end
34
+
35
+ #
36
+ def run()
37
+ super
38
+
39
+ # creo el objeto logger
40
+ self.logger = RemoteLogger.new(
41
+ "#{self.fullWorkerName}.log",
42
+ BlackStack::Pampa::api_protocol,
43
+ BlackStack::Pampa::api_domain,
44
+ BlackStack::Pampa::api_port,
45
+ BlackStack::Pampa::api_key
46
+ )
47
+
48
+ logger.log "Remote process is alive!"
49
+
50
+ # actualiza parametros de la central
51
+ logger.logs "Update from central (1)... "
52
+ self.get
53
+ logger.done
54
+
55
+ # actualizo los datos de este worker (parent process)
56
+ logger.logs "Update worker (1)... "
57
+ self.updateWorker
58
+ logger.done
59
+
60
+ while (self.canRun?)
61
+
62
+ # reseteo en contador nested del logger
63
+ self.logger.reset()
64
+
65
+ # announcing my in the log
66
+ logger.log "Going to Run Remote"
67
+ logger.log "Process: #{self.assigned_process.to_s}."
68
+ logger.log "Object: #{(self.id_object.to_s.size==0)? 'n/a' : self.id_object.to_s}."
69
+
70
+ # obtengo la hora de inicio
71
+ start_time = Time.now
72
+
73
+ begin
74
+ # libero recursos
75
+ logger.logs "Release resources... "
76
+ GC.start
77
+ #DB.disconnect
78
+ logger.done
79
+
80
+ # envia senial a la central.
81
+ # si tiene asignada una division, envia senial a la division.
82
+ logger.logs "Ping... "
83
+ self.ping()
84
+ logger.done
85
+
86
+ # envia senial a la central.
87
+ # si tiene asignada una division, envia senial a la division.
88
+ logger.logs "Notify to Division... "
89
+ self.notify()
90
+ logger.done
91
+
92
+ # corro el procesamiento
93
+ self.process(ARGV)
94
+
95
+ rescue => e
96
+ puts ""
97
+ logger.log "Remote Process Error: " + e.to_s + "\r\n" + e.backtrace.join("\r\n").to_s
98
+ end
99
+
100
+ # actualiza parametros de la central
101
+ logger.logs "Update from central (2)... "
102
+ self.get
103
+ logger.done
104
+
105
+ # actualizo los datos de este worker (parent process)
106
+ logger.logs "Update worker (2)... "
107
+ self.updateWorker
108
+ logger.done
109
+
110
+ # sleep
111
+ logger.logs "Sleep... "
112
+ self.doSleep(start_time)
113
+ logger.done
114
+
115
+ logger.log "-------------------------------------------"
116
+
117
+ GC.start
118
+ #DB.disconnect
119
+
120
+ end # main while
121
+
122
+ #
123
+ logger.log self.whyCantRun()
124
+
125
+ end # run
126
+ end # class MyRemoteProcess
127
+
128
+ end # module BlackStack
@@ -0,0 +1,41 @@
1
+ require_relative './division'
2
+ require_relative './params'
3
+ require_relative './worker'
4
+ require_relative './client'
5
+ require_relative './timezone'
6
+ require_relative './user'
7
+ require_relative './login'
8
+ require_relative './role'
9
+ require_relative './userdivision'
10
+ require_relative './userrole'
11
+
12
+ # funciones auxiliares
13
+ def guid()
14
+ DB['SELECT NEWID() AS [id]'].map(:id)[0]
15
+ end
16
+
17
+ def now()
18
+ # La llamada a GETDATE() desde ODBC no retorna precision de milisegundos, que es necesaria para los registros de log.
19
+ # La llamada a SYSDATETIME() retorna un valor de alta precision que no es compatible para pegar en los campos del tipo DATATIME.
20
+ # La linea de abajo obtiene la hora en formato de SYSDATE y le trunca los ultimos digitos para hacer que el valor sea compatible con los campos DATETIME.
21
+ (DB['SELECT SYSDATETIME() AS [now]'].map(:now)[0]).to_s[0..22]
22
+ end
23
+
24
+ def diff(unit, t0, t1)
25
+ # La llamada a GETDATE() desde ODBC no retorna precision de milisegundos, que es necesaria para los registros de log.
26
+ # La llamada a SYSDATETIME() retorna un valor de alta precision que no es compatible para pegar en los campos del tipo DATATIME.
27
+ # La linea de abajo obtiene la hora en formato de SYSDATE y le trunca los ultimos digitos para hacer que el valor sea compatible con los campos DATETIME.
28
+ (DB["SELECT DATEDIFF(#{unit}, '#{t0.to_s}', '#{t1.to_s}') AS [diff]"].map(:diff)[0]).to_i
29
+ end
30
+
31
+ def before(n) # n minutes
32
+ DB["SELECT DATEADD(mi, -#{n.to_s}, GETDATE()) AS [now]"].map(:now).to_s[0]
33
+ end
34
+
35
+ def monthsFromNow(n) # n months
36
+ DB["SELECT DATEADD(mm, +#{n.to_s}, GETDATE()) AS [now]"].map(:now).to_s[0]
37
+ end
38
+
39
+ def daysFromNow(n) # n days
40
+ DB["SELECT DATEADD(dd, +#{n.to_s}, GETDATE()) AS [now]"].map(:now).to_s[0]
41
+ end
data/lib/pampa.rb ADDED
@@ -0,0 +1,261 @@
1
+ require 'blackstack_commons'
2
+ require 'simple_command_line_parser'
3
+ require 'simple_cloud_logging'
4
+ require 'simple_host_monitoring'
5
+ require 'socket'
6
+ require 'time'
7
+ require 'uri'
8
+ require 'net/http'
9
+ require 'json'
10
+ require 'openssl'
11
+ require 'tiny_tds'
12
+ require 'sequel'
13
+
14
+ #require './lib/base'
15
+ #require './config.rb'
16
+
17
+ require_relative './baseworker'
18
+ require_relative './basedivision'
19
+
20
+ require_relative './remoteworker'
21
+ require_relative './remotedivision'
22
+
23
+ require_relative './myprocess'
24
+ require_relative './mychildprocess'
25
+ require_relative './mylocalprocess'
26
+ require_relative './myparentprocess'
27
+ require_relative './myremoteprocess'
28
+ require_relative './mybotprocess'
29
+ require_relative './mycrawlprocess'
30
+ require_relative './remoteworker'
31
+ require_relative './remotedivision'
32
+
33
+ module BlackStack
34
+
35
+ module Pampa
36
+
37
+ #
38
+ @@division_name = nil
39
+
40
+ def self.division_name()
41
+ @@division_name
42
+ end
43
+
44
+ #
45
+ def self.set_division_name(s)
46
+ @@division_name = s
47
+ end
48
+
49
+ # Api-key of the client who will be the owner of a process.
50
+ @@api_key = nil
51
+
52
+ def self.api_key()
53
+ @@api_key
54
+ end
55
+
56
+ # Protocol, HTTP or HTTPS, of the BlackStack server where this process will be registered.
57
+ @@api_protocol = nil
58
+
59
+ #
60
+ def self.api_protocol
61
+ @@api_protocol
62
+ end
63
+
64
+ # Domain of the BlackStack server where this process will be registered.
65
+ @@api_domain = nil
66
+
67
+ #
68
+ def self.api_domain
69
+ @@api_domain
70
+ end
71
+
72
+ # Port of the BlackStack server where this process will be registered.
73
+ @@api_port = nil
74
+
75
+ #
76
+ def self.api_port
77
+ @@api_port
78
+ end
79
+
80
+ # get the full URL of the worker api server
81
+ def self.api_url()
82
+ "#{BlackStack::Pampa::api_protocol}://#{BlackStack::Pampa::api_domain}:#{BlackStack::Pampa::api_port}"
83
+ end
84
+
85
+ #
86
+ def self.set_api_key(s)
87
+ @@api_key = s
88
+ end
89
+
90
+ #
91
+ def self.set_api_url(h)
92
+ @@api_key = h[:api_key]
93
+ @@api_protocol = h[:api_protocol]
94
+ @@api_domain = h[:api_domain]
95
+ @@api_port = h[:api_port]
96
+ end
97
+
98
+ # path where you will store the data of each client
99
+ @@storage_folder = nil
100
+ @@storage_sub_folders = []
101
+
102
+ #
103
+ def self.storage_folder()
104
+ @@storage_folder
105
+ end
106
+ def self.storage_sub_folders(a)
107
+ @@storage_sub_folder = a
108
+ end
109
+
110
+ #
111
+ def self.set_storage_folder(path)
112
+ @@storage_folder = path
113
+ end
114
+ def self.set_storage_sub_folders(a)
115
+ @@storage_sub_folders = a
116
+ end
117
+
118
+
119
+ #
120
+ # default timezome for any new user
121
+ #
122
+ #
123
+ @@id_timezone_default = nil
124
+
125
+ #
126
+ def self.id_timezone_default()
127
+ @@id_timezone_default
128
+ end
129
+
130
+ #
131
+ def self.set_id_timezone_default(id)
132
+ @@id_timezone_default = id
133
+ end
134
+
135
+ # Array of external IP addresses of the servers where farms are running.
136
+ # If you have many servers running behind a NAT server, only add the IP
137
+ # of the external gateway here. This array is used to know if a worker
138
+ # is running inside your farm datacenter, or it is running in the computer
139
+ # of someone else.
140
+ @@farm_external_ip_addresses = []
141
+
142
+ #
143
+ def self.farm_external_ip_addresses()
144
+ @@farm_external_ip_addresses
145
+ end
146
+
147
+ #
148
+ def self.set_farm_external_ip_addresses(a)
149
+ @@farm_external_ip_addresses = a
150
+ end
151
+
152
+ #
153
+ def self.get_guid
154
+ res = BlackStack::Netting::call_post(
155
+ "#{self.api_url}/api1.4/get_guid.json",
156
+ {'api_key' => @@api_key}
157
+ )
158
+ parsed = JSON.parse(res.body)
159
+ parsed['value']
160
+ end
161
+
162
+ # Central database connection parameters
163
+ @@db_url = nil
164
+ @@db_port = nil
165
+ @@db_name = nil
166
+ @@db_user = nil
167
+ @@db_password = nil
168
+
169
+ #
170
+ def self.db_url
171
+ @@db_url
172
+ end
173
+
174
+ #
175
+ def self.db_port
176
+ @@db_port
177
+ end
178
+
179
+ #
180
+ def self.db_name
181
+ @@db_name
182
+ end
183
+
184
+ #
185
+ def self.db_user
186
+ @@db_user
187
+ end
188
+
189
+ #
190
+ def self.db_password
191
+ @@db_password
192
+ end
193
+
194
+ # Set connection params to the central database
195
+ def self.set_db_params(h)
196
+ @@db_url = h[:db_url]
197
+ @@db_port = h[:db_port]
198
+ @@db_name = h[:db_name]
199
+ @@db_user = h[:db_user]
200
+ @@db_password = h[:db_password]
201
+ end
202
+
203
+ # TODO: doc me!
204
+ def self.connection_descriptor()
205
+ ret = nil
206
+
207
+ # validar que el formato no sea nulo
208
+ if (self.division_name.to_s.length == 0)
209
+ raise "Division name expected."
210
+ end
211
+
212
+ if (self.division_name == "local")
213
+ ret = {
214
+ :adapter => 'tinytds',
215
+ :dataserver => BlackStack::Pampa::db_url, # IP or hostname
216
+ :port => BlackStack::Pampa::db_port, # Required when using other that 1433 (default)
217
+ :database => BlackStack::Pampa::db_name,
218
+ :user => BlackStack::Pampa::db_user,
219
+ :password => BlackStack::Pampa::db_password
220
+ }
221
+ else
222
+ url = "#{BlackStack::Pampa::api_url}/api1.2/division/get.json"
223
+ res = BlackStack::Netting::call_post(url, {
224
+ 'api_key' => BlackStack::Pampa::api_key,
225
+ 'dname' => "#{self.division_name}",
226
+ })
227
+ parsed = JSON.parse(res.body)
228
+
229
+ if (parsed["status"] != BlackStack::Netting::SUCCESS)
230
+ raise "Error getting connection string: #{parsed["status"]}"
231
+ else
232
+ wid = parsed["value"]
233
+
234
+ ret = {
235
+ :adapter => 'tinytds',
236
+ :dataserver => parsed["db_url"], # IP or hostname
237
+ :port => parsed["db_port"], # only required if port is different than 1433
238
+ :database => parsed["db_name"],
239
+ :user => parsed["db_user"],
240
+ :password => parsed["db_password"]
241
+ }
242
+ end
243
+ end
244
+
245
+ ret
246
+ end # connectionDescriptor
247
+
248
+ #
249
+ def self.db_connection()
250
+ Sequel.connect(BlackStack::Pampa::connection_descriptor)
251
+ end
252
+
253
+ #
254
+ def self.require_db_classes()
255
+ # You have to load all the Sinatra classes after connect the database.
256
+ require_relative '../lib/pampa-local.rb'
257
+ end
258
+
259
+ end # module Pampa
260
+
261
+ end # module BlackStack
data/lib/params.rb ADDED
@@ -0,0 +1,50 @@
1
+ module BlackStack
2
+
3
+ class Params < Sequel::Model(:params)
4
+ Params.dataset = Params.dataset.disable_insert_output
5
+
6
+ def self.getValue(s)
7
+ param = Params.where(:name=>s).first
8
+ if (param == nil)
9
+ raise "Unknown parameter name (#{s.to_s})"
10
+ else
11
+ if param.type == PARAM_TYPE_VARCHAR
12
+ return param.value_varchar.to_s
13
+ elsif param.type == PARAM_TYPE_NUMERIC
14
+ return param.value_numeric.to_i
15
+ elsif param.type == PARAM_TYPE_DATETIME
16
+ return param.value_datetime
17
+ elsif param.type == PARAM_TYPE_BIT
18
+ return param.value_bit
19
+ else
20
+ raise "Unknown parameter type (#{param.type.to_s})."
21
+ end # if param.type
22
+ end # if (param == nil)
23
+ end # def self.getValue
24
+
25
+ def self.setValue(s, v) # TODO: Testear este metodo
26
+ param = Params.where(:name=>s).first
27
+ if (param == nil)
28
+ raise "Unknown parameter name (#{s.to_s})"
29
+ else
30
+ if param.type == PARAM_TYPE_VARCHAR
31
+ param.value_varchar = v
32
+ param.save()
33
+ elsif param.type == PARAM_TYPE_NUMERIC
34
+ param.value_numeric = v
35
+ param.save()
36
+ elsif param.type == PARAM_TYPE_DATETIME
37
+ param.value_datetime = v
38
+ param.save()
39
+ elsif param.type == PARAM_TYPE_BIT
40
+ param.value_bit = v
41
+ param.save()
42
+ else
43
+ raise "Unknown parameter type (#{param.type.to_s})."
44
+ end # if param.type
45
+ end # if (param == nil)
46
+ end # def self.getValue
47
+
48
+ end # class
49
+
50
+ end # module BlackStack
@@ -0,0 +1,8 @@
1
+ module BlackStack
2
+
3
+ class RemoteDivision
4
+ attr_accessor :name
5
+ include BlackStack::BaseDivision
6
+ end # RemoteDivision
7
+
8
+ end # module BlackStack
@@ -0,0 +1,8 @@
1
+ module BlackStack
2
+
3
+ class RemoteWorker
4
+ attr_accessor :id, :process, :last_ping_time, :name, :active, :id_division, :assigned_process, :id_object, :division_name, :ws_url, :ws_port, :division
5
+ include BlackStack::BaseWorker
6
+ end # Remote Worker
7
+
8
+ end # module BlackStack
data/lib/role.rb ADDED
@@ -0,0 +1,8 @@
1
+ module BlackStack
2
+ class Role < Sequel::Model(:role)
3
+ BlackStack::Role.dataset = BlackStack::Role.dataset.disable_insert_output
4
+
5
+ ROLE_PRISMA_USER = "prisma.user"
6
+
7
+ end
8
+ end # module BlackStack
data/lib/timezone.rb ADDED
@@ -0,0 +1,151 @@
1
+ module BlackStack
2
+ class Timezone < Sequel::Model(:timezone)
3
+ BlackStack::Timezone.dataset = BlackStack::Timezone.dataset.disable_insert_output
4
+
5
+ # Recibe un string con formato "+HH:MM".
6
+ # Retorna la cantidad de horas como un numero real, con decimales.
7
+ def self.descToFloat(s)
8
+ sign = s[0]
9
+ if (sign=="+")
10
+ n = 1.0
11
+ else
12
+ n = -1.0
13
+ end
14
+ hours = s[1..2]
15
+ minutes = s[4..5]
16
+ int_part = hours.to_f
17
+ dec_part = minutes.to_f / 60.00
18
+ ret = n*(int_part + dec_part)
19
+ return ret.to_f
20
+ end
21
+
22
+ # Recibe la cantidad de horas como un numero real, con decimales.
23
+ # Retorna un string con formato "+HH:MM".
24
+ def self.floatToDesc(x)
25
+ int_part = x.to_i
26
+ dec_part = (x-int_part.to_f).round(2).abs
27
+ hours = int_part
28
+ minutes = (dec_part * 60.00).to_i
29
+ if (hours<0)
30
+ desc = "%03d" % hours
31
+ else
32
+ desc = "+" + "%02d" % hours
33
+ end
34
+ desc += ":" + "%02d" % minutes
35
+ return desc
36
+ end
37
+
38
+ # Example: '-03:00'
39
+ # Example: ' 08:00'
40
+ def self.getDatabaseOffset()
41
+ dbtime = DB["select SYSDATETIMEOFFSET() AS o"].first[:o].to_s
42
+ #puts ""
43
+ #puts ""
44
+ #puts "dbtime:#{dbtime.to_s}:."
45
+ #puts ""
46
+ #puts ""
47
+ ret = "#{dbtime[-5..-3]}:#{dbtime[-2..-1]}"
48
+ ret[0] = '+' if ret[0]!='-'
49
+ #puts ""
50
+ #puts ""
51
+ #puts "dbtime:#{ret.to_s}:."
52
+ #puts ""
53
+ #puts ""
54
+ return ret
55
+ end
56
+
57
+ # Convierte el atributo offset en un string con formato de hora.
58
+ # Ejemplos: 5.0 => 05:00, 5.5 => 05:30, -5.75 => -05:45
59
+ def offsetDescription()
60
+ return BlackStack::Timezone.floatToDesc(self.offset.to_f)
61
+ end
62
+
63
+ # Convierte una hora almacenada en el servidor de bases de datos, a la hora en esta zona horaria.
64
+ # Recibe un string con formato "+HH:MM".
65
+ # Retorna un string con formato "+HH:MM".
66
+ def convertFromThisTimeZoneToDatabaseTime(s_time_in_client_timezone)
67
+ f_time_in_client_timezone = BlackStack::Timezone.descToFloat(s_time_in_client_timezone)
68
+ s = BlackStack::Timezone.getDatabaseOffset()
69
+ x = BlackStack::Timezone.descToFloat(s) # database offset
70
+ y = self.offset # client offset
71
+ z = y - x
72
+ return BlackStack::Timezone.floatToDesc((f_time_in_client_timezone.to_f + z.to_f).modulo(24))
73
+ end
74
+
75
+ # Convierte una hora almacenada en el servidor de bases de datos, a la hora en esta zona horaria.
76
+ # Recibe un string con formato "+HH:MM".
77
+ # Retorna un string con formato "+HH:MM".
78
+ def convertFromDatabaseTimeToThisTimeZone(s_time_in_database)
79
+ f_time_in_database = BlackStack::Timezone.descToFloat(s_time_in_database)
80
+ s = BlackStack::Timezone.getDatabaseOffset()
81
+ x = BlackStack::Timezone.descToFloat(s) # database offset
82
+ y = self.offset # client offset
83
+ z = y - x
84
+ return BlackStack::Timezone.floatToDesc((f_time_in_database.to_f - z.to_f).modulo(24))
85
+ end
86
+
87
+ # Convierte una fecha-hora almacenada en el servidor de bases de datos, a la hora en esta zona horaria.
88
+ # Recibe un string con formato "YYYY-MM-DD HH:MM:SS".
89
+ # Retorna un string con formato "YYYY-MM-DD HH:MM:SS".
90
+ def convertFromDatabaseDateTimeToThisTimeZone(s_datetime_in_database)
91
+ s = BlackStack::Timezone.getDatabaseOffset() # Example: '-03:00'
92
+ #puts ""
93
+ #puts ""
94
+ #puts "s:#{s.to_s}:."
95
+ #puts ""
96
+ #puts ""
97
+ x = BlackStack::Timezone.descToFloat(s) # database offset. Number of hours, with decimals
98
+ #puts ""
99
+ #puts ""
100
+ #puts "x:#{x.to_s}:."
101
+ #puts ""
102
+ #puts ""
103
+ y = self.offset # client offset
104
+ #puts ""
105
+ #puts ""
106
+ #puts "y:#{y.to_s}:."
107
+ #puts ""
108
+ #puts ""
109
+ z = y - x
110
+ #puts ""
111
+ #puts ""
112
+ #puts "z:#{z.to_s}:."
113
+ #puts ""
114
+ #puts ""
115
+ ret = DB["SELECT DATEADD(HH, #{z.to_s}, '#{s_datetime_in_database}') AS o"].first[:o].to_s[0..18]
116
+ #puts ""
117
+ #puts ""
118
+ #puts "convertFromDatabaseDateTimeToThisTimeZone:#{ret}:."
119
+ #puts ""
120
+ #puts ""
121
+
122
+ return ret
123
+ end
124
+
125
+ #
126
+ def get_now()
127
+ datetime1 = DB["SELECT GETDATE() AS o"].first[:o].to_s[0..18]
128
+ datetime2 = self.convertFromDatabaseDateTimeToThisTimeZone(datetime1)
129
+ #puts ""
130
+ #puts ""
131
+ #puts "timezone:#{self.large_description}:."
132
+ #puts "datetime1:#{datetime1}:."
133
+ #puts "datetime2:#{datetime2}:."
134
+ #puts ""
135
+ #puts ""
136
+ yy = datetime2[0..3] # yyyy-mm-dd hh:mi:ss
137
+ mm = datetime2[5..6]
138
+ dd = datetime2[8..9]
139
+ hh = datetime2[11..12]
140
+ mi = datetime2[14..15]
141
+ ss = datetime2[17..18]
142
+ #puts ""
143
+ #puts ""
144
+ #puts "get_now:#{yy}-#{mm}-#{dd} #{hh}:#{mi}:#{ss}:."
145
+ #puts ""
146
+ #puts ""
147
+ return Time.new(yy,mm,dd,hh,mi,ss)
148
+ end
149
+
150
+ end
151
+ end # module BlackStack
data/lib/user.rb ADDED
@@ -0,0 +1,25 @@
1
+ module BlackStack
2
+ class User < Sequel::Model(:user)
3
+ BlackStack::User.dataset = BlackStack::User.dataset.disable_insert_output
4
+ many_to_one :client, :class=>:'BlackStack::Client', :key=>:id_client
5
+ one_to_many :user_roles, :class=>:'BlackStack::UserRole', :key=>:id_user
6
+
7
+ # TODO: agregar todos los arrays de un usuario
8
+ # => one_to_many :searches, :class=>:Search, :key=>:id_user
9
+ # => one_to_many :emlist, :class=>:EmList, :key=>:id_user
10
+ # => one_to_many :emlist, :class=>:EmList, :key=>:id_user
11
+ # => etc.
12
+
13
+ # retorna la primera division habilitada a la que pertenezca este usuario
14
+ def division
15
+ row = DB[
16
+ "SELECT d.id " +
17
+ "FROM division d WITH (NOLOCK) " +
18
+ "JOIN user_division ud WITH (NOLOCK) ON (d.id=ud.id_division AND ud.id_user='#{self.id}') " +
19
+ "WHERE ISNULL(d.available,0) = 1 "
20
+ ].first
21
+ return nil if row.nil?
22
+ return BlackStack::Division.where(:id=>row[:id]).first if !row.nil?
23
+ end
24
+ end # class User
25
+ end # module BlackStack
@@ -0,0 +1,5 @@
1
+ module BlackStack
2
+ class UserDivision < Sequel::Model(:user_division)
3
+ BlackStack::UserDivision.dataset = BlackStack::UserDivision.dataset.disable_insert_output
4
+ end
5
+ end # module BlackStack
data/lib/userrole.rb ADDED
@@ -0,0 +1,8 @@
1
+ module BlackStack
2
+ class UserRole < Sequel::Model(:user_role)
3
+ BlackStack::UserRole.dataset = BlackStack::UserRole.dataset.disable_insert_output
4
+ many_to_one :user, :class=>:'BlackStack::User', :key=>:id_user
5
+ many_to_one :role, :class=>:'BlackStack::Role', :key=>:id_role
6
+
7
+ end
8
+ end # module BlackStack