teradata-cli 0.0.1

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,23 @@
1
+ # $Id: bitdao.rb 184 2009-08-12 08:46:22Z aamine $
2
+
3
+ require 'teradata'
4
+
5
+ module Teradata
6
+ class Error
7
+ include ::BitDAO::Error
8
+ end
9
+
10
+ class SQLError
11
+ include ::BitDAO::Error
12
+ end
13
+
14
+ class Connection # reopen
15
+ def error_class
16
+ Error
17
+ end
18
+
19
+ def sql_error_class
20
+ SQLError
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,575 @@
1
+ # $Id: bitweb.rb 158 2009-05-22 10:13:19Z aamine $
2
+
3
+ require 'webrick/cgi'
4
+ require 'webrick/httpservlet/abstract'
5
+ require 'webrick/httpstatus'
6
+ begin
7
+ require 'fcgi'
8
+ rescue LoadError
9
+ end
10
+ require 'erb'
11
+ require 'yaml'
12
+
13
+ Socket.do_not_reverse_lookup = true
14
+
15
+ module BitWeb
16
+
17
+ class Error < StandardError; end
18
+ class RequestError < Error; end
19
+
20
+ class ValidationError < RequestError
21
+ def initialize(key, message)
22
+ super message
23
+ @key = key
24
+ end
25
+
26
+ attr_reader :key
27
+ end
28
+
29
+
30
+ class Interface
31
+
32
+ def initialize(webrick_conf = {})
33
+ @webrick_conf = webrick_conf
34
+ @handler = ($webinterface_context_cache ||= yield)
35
+ end
36
+
37
+ # for WEBrick servlet
38
+ def get_instance(server)
39
+ WEBrickServlet.new(server, @handler)
40
+ end
41
+
42
+ def main
43
+ if fastcgi?
44
+ FCGI.new(@webrick_conf).main(@handler)
45
+ else
46
+ # CGI, mod_ruby
47
+ CGI.new(@webrick_conf).main(@handler)
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def fastcgi?
54
+ defined?(::FCGI) and ::FCGI.fastcgi?
55
+ end
56
+
57
+ def mod_ruby?
58
+ false # FIXME
59
+ end
60
+
61
+ end
62
+
63
+ class CGI < ::WEBrick::CGI
64
+ def main(handler)
65
+ @handler = handler
66
+ start
67
+ end
68
+
69
+ def do_GET(wreq, wres)
70
+ @handler.handle(wreq).update wres
71
+ end
72
+
73
+ alias do_POST do_GET
74
+ end
75
+
76
+ class FCGI < CGI
77
+ def main(handler)
78
+ @handler = handler
79
+ ::FCGI.each_cgi_request do |req|
80
+ start req.env, req.in, req.out
81
+ end
82
+ end
83
+ end
84
+
85
+ class WEBrickServlet < ::WEBrick::HTTPServlet::AbstractServlet
86
+ def do_GET(wreq, wres)
87
+ @options.first.handle(wreq).update wres
88
+ end
89
+
90
+ alias do_POST do_GET
91
+ end
92
+
93
+
94
+ module HTMLUtils
95
+
96
+ private
97
+
98
+ ESC = {
99
+ '&' => '&amp;',
100
+ '"' => '&quot;',
101
+ '<' => '&lt;',
102
+ '>' => '&gt;'
103
+ }
104
+
105
+ def escape_html(str)
106
+ table = ESC # optimize
107
+ str.gsub(/[&"<>]/) {|s| table[s] }
108
+ end
109
+
110
+ ESCrev = ESC.invert
111
+
112
+ def unescape_html(str)
113
+ table = ESCrev # optimize
114
+ str.gsub(/&\w+;/) {|s| table[s] }
115
+ end
116
+
117
+ end
118
+
119
+
120
+ module ClassUtils
121
+
122
+ private
123
+
124
+ def find_class_from_current_context(name)
125
+ eval("#{current_class_path}::#{name}")
126
+ rescue NameError => err
127
+ raise RequestError, "unknown screen: #{id.inspect}"
128
+ end
129
+
130
+ def current_class_path
131
+ path = self.class.name.split('::')[0..-2]
132
+ path.empty? ? '' : "::#{path.join('::')}"
133
+ end
134
+
135
+ end
136
+
137
+
138
+ class RequestHandler
139
+
140
+ include ClassUtils
141
+
142
+ def initialize(log, views, models)
143
+ @log = log
144
+ @views = views
145
+ @models = models
146
+ @log.info(self.class) { "application started" }
147
+ end
148
+
149
+ def handle(webrick_req)
150
+ respond_to(Request.new(webrick_req))
151
+ rescue WEBrick::HTTPStatus::Status
152
+ raise
153
+ rescue => err
154
+ @log.error(self.class) { "#{err.class}: #{err.message}" }
155
+ return Response.new(ErrorScreen.new(err))
156
+ end
157
+
158
+ private
159
+
160
+ def respond_to(req)
161
+ @log.info(self.class) {
162
+ "new request [#{req.controller.inspect}/#{req.command.inspect}]"
163
+ }
164
+ ctl = controller_class(req.controller).new(@log, @views, @models)
165
+ res = Response.new(ctl.handle(req))
166
+ @log.debug(self.class) { "controller returned" }
167
+ res
168
+ end
169
+
170
+ def controller_class(id)
171
+ find_class_from_current_context("#{id.capitalize}Controller")
172
+ end
173
+
174
+ end
175
+
176
+
177
+ class Controller
178
+
179
+ def self.depends(*names)
180
+ ivar_list = names.map {|n| "@#{n}" }.join(', ')
181
+ sym_list = names.map {|n| ":#{n}" }.join(', ')
182
+ module_eval(<<-End, __FILE__, __LINE__ + 1)
183
+ def initialize(log, views, models)
184
+ super log, views
185
+ #{ivar_list}, * = models.values_at(#{sym_list})
186
+ end
187
+ End
188
+ end
189
+ private_class_method :depends
190
+
191
+ def initialize(log, views)
192
+ @log = log
193
+ @views = views
194
+ end
195
+
196
+ def handle(req)
197
+ mid = "handle_#{req.command}"
198
+ unless respond_to?(mid, true)
199
+ @log.error(self.class) { "unknown command: #{req.command.inspect}" }
200
+ raise RequestError, "unknown command: #{req.command.inspect}"
201
+ end
202
+ @log.debug(self.class) { "dispatch: #{self.class}\##{mid}" }
203
+ __send__(mid, req)
204
+ end
205
+
206
+ end
207
+
208
+
209
+ class Request
210
+
211
+ def initialize(wreq)
212
+ @wreq = wreq
213
+ end
214
+
215
+ def peer_ipaddr
216
+ @peer_ipaddr ||= @wreq.peeraddr[2]
217
+ end
218
+
219
+ def peer_hostname
220
+ @peer_hostname ||= getnameinfo(peer_ipaddr).host
221
+ end
222
+
223
+ def getnameinfo(addr)
224
+ NameInfo.new(*Socket.getnameinfo([Socket::AF_UNSPEC, nil, addr]))
225
+ end
226
+ private :getnameinfo
227
+
228
+ NameInfo = Struct.new(:host, :port)
229
+
230
+ def controller
231
+ path_components[0] or
232
+ raise RequestError, "controller name did not given"
233
+ end
234
+
235
+ def command
236
+ path_components[1] or
237
+ raise RequestError, "command name did not given"
238
+ end
239
+
240
+ def path_components
241
+ @wreq.path_info.sub(%r<\A/>, '').split('/')
242
+ end
243
+
244
+ def [](name)
245
+ get(name)
246
+ end
247
+
248
+ def get(name)
249
+ val = @wreq.query[name]
250
+ s = (val && val.to_s)
251
+ if block_given?
252
+ yield(Parameter.new(name, s))
253
+ else
254
+ s
255
+ end
256
+ end
257
+
258
+ def parameters(*keys)
259
+ h = {}
260
+ keys.each do |k|
261
+ h[k] = get(k)
262
+ end
263
+ h
264
+ end
265
+
266
+ class Parameter
267
+ def initialize(name, val)
268
+ @name = name
269
+ @value = val
270
+ end
271
+
272
+ def raw_value
273
+ @value
274
+ end
275
+
276
+ def string
277
+ @value.to_s
278
+ end
279
+
280
+ def time
281
+ Time.parse(@value.to_s)
282
+ rescue ArgumentError => err
283
+ validation_error "bad time format"
284
+ end
285
+
286
+ def date
287
+ Time.parse(@value.to_s)
288
+ rescue ArgumentError => err
289
+ validation_error "bad date format"
290
+ end
291
+
292
+ def must_date
293
+ unless %r<\A\d{4}[\-/]\d{1,2}[\-/]\d{1,2}\z> =~ @value
294
+ validation_error "bad date format"
295
+ end
296
+ end
297
+
298
+ def must_exist
299
+ unless @value
300
+ validation_error "not exist"
301
+ end
302
+ end
303
+
304
+ def must_string
305
+ must_exist
306
+ end
307
+
308
+ def must_not_empty
309
+ must_string
310
+ if @value.strip.empty?
311
+ validation_error "is empty"
312
+ end
313
+ end
314
+
315
+ def must_match(re)
316
+ unless re =~ @value
317
+ validation_error "bad format"
318
+ end
319
+ end
320
+
321
+ def must(msg = 'bad value')
322
+ unless yield(@value)
323
+ validation_error msg
324
+ end
325
+ end
326
+
327
+ def validation_error(msg)
328
+ raise ValidationError.new(@name, msg)
329
+ end
330
+ end
331
+
332
+ end
333
+
334
+
335
+ class Response
336
+
337
+ def initialize(screen)
338
+ @screen = screen
339
+ end
340
+
341
+ def update(wres)
342
+ wres.status = @screen.status if @screen.status
343
+ wres['Content-Type'] = @screen.content_type
344
+ body = @screen.body
345
+ wres['Content-Length'] = body.length
346
+ wres.body = body
347
+ end
348
+
349
+ end
350
+
351
+
352
+ class ViewManager
353
+
354
+ def initialize(log, template_dir, message_file, base_url, app_base_url = base_url)
355
+ @log = log
356
+ @template_dir = template_dir
357
+ @messages = Messages.load(message_file)
358
+ @base_url = base_url
359
+ @app_base_url = app_base_url
360
+ end
361
+
362
+ def new(screen_class, *args)
363
+ screen_class.new(@log, self, *args)
364
+ end
365
+
366
+ def run(id, binding)
367
+ erb = ERB.new(load(id))
368
+ erb.filename = id + '.erb'
369
+ erb.result(binding)
370
+ end
371
+
372
+ def load(id)
373
+ preproc(File.read("#{@template_dir}/#{id}"))
374
+ end
375
+
376
+ def preproc(template)
377
+ template.gsub(/^\.include ([\w\-]+)/) { load($1.untaint) }.untaint
378
+ end
379
+ private :preproc
380
+
381
+ def translate_message(key)
382
+ @messages[key]
383
+ end
384
+
385
+ def application_url(rel)
386
+ "#{@app_base_url}#{rel}"
387
+ end
388
+
389
+ def css_url(rel)
390
+ "#{@base_url}/css/#{rel}"
391
+ end
392
+
393
+ def js_url(rel)
394
+ "#{@base_url}/js/#{rel}"
395
+ end
396
+
397
+ def image_url(rel)
398
+ "#{@base_url}/images/#{rel}"
399
+ end
400
+
401
+ end
402
+
403
+
404
+ class Messages
405
+ def Messages.load(path)
406
+ new(YAML.load_file(path))
407
+ end
408
+
409
+ def initialize(h)
410
+ @messages = h
411
+ end
412
+
413
+ def [](key)
414
+ @messages[key] || key
415
+ end
416
+ end
417
+
418
+
419
+ class Screen
420
+
421
+ def status
422
+ nil
423
+ end
424
+
425
+ end
426
+
427
+
428
+ class ErrorScreen < Screen
429
+
430
+ include HTMLUtils
431
+
432
+ def initialize(error)
433
+ @error = error
434
+ end
435
+
436
+ def status
437
+ 500
438
+ end
439
+
440
+ def content_type
441
+ # IE does not support XHTML, do not return "application/xhtml+xml".
442
+ 'text/html'
443
+ end
444
+
445
+ def body
446
+ <<-EndHTML
447
+ <html>
448
+ <head><title>Error</title></head>
449
+ <body>
450
+ <h1>Error</h1>
451
+ <pre>#{escape_html(@error.message)} (#{escape_html(@error.class.name)})
452
+ #{@error.backtrace.map {|s| escape_html(s) }.join("\n")}</pre>
453
+ </body>
454
+ </html>
455
+ EndHTML
456
+ end
457
+
458
+ end
459
+
460
+
461
+ class TemplateScreen < Screen
462
+
463
+ def TemplateScreen.new_class(*attrs)
464
+ c = Class.new(self)
465
+ c.attributes(*attrs)
466
+ c
467
+ end
468
+
469
+ def TemplateScreen.attributes(*attrs)
470
+ ivar_list = attrs.map {|a| "@#{a}" }.join(', ')
471
+ param_list = attrs.join(', ')
472
+ module_eval(<<-End, __FILE__, __LINE__ + 1)
473
+ def initialize(log, views, #{attrs.join(', ')})
474
+ super log, views
475
+ #{ivar_list} = #{param_list}
476
+ end
477
+ End
478
+ module_eval {
479
+ attrs.each do |a|
480
+ attr_reader a
481
+ end
482
+ }
483
+ end
484
+
485
+ include HTMLUtils
486
+
487
+ def initialize(log, views)
488
+ @log = log
489
+ @views = views
490
+ end
491
+
492
+ def content_type
493
+ # IE does not support XHTML, do not return "application/xhtml+xml".
494
+ "text/html"
495
+ end
496
+
497
+ def body
498
+ @log.debug(self.class) { "running template: #{template_id}" }
499
+ @views.run(template_id, binding)
500
+ end
501
+
502
+ private
503
+
504
+ def template_id
505
+ c, s = self.class.name.split('::')[-2,2]
506
+ c.downcase.sub(/controller\z/, '') + '/' + s.downcase.sub(/screen\z/, '')
507
+ end
508
+
509
+ def _(key)
510
+ @views.translate_message(key)
511
+ end
512
+
513
+ def app_url(rel)
514
+ @views.application_url(rel)
515
+ end
516
+
517
+ def url(rel)
518
+ string(app_url(rel))
519
+ end
520
+
521
+ def css_url(rel)
522
+ @views.css_url(rel)
523
+ end
524
+
525
+ def css(rel)
526
+ string(css_url(rel))
527
+ end
528
+
529
+ def js_url(rel)
530
+ @views.js_url(rel)
531
+ end
532
+
533
+ def js(rel)
534
+ string(js_url(rel))
535
+ end
536
+
537
+ def image_url(rel)
538
+ @views.image_url(rel)
539
+ end
540
+
541
+ def img(rel)
542
+ string(image_url(rel))
543
+ end
544
+
545
+ def int(value)
546
+ value.to_i.to_s
547
+ end
548
+
549
+ def string(value)
550
+ escape_html(value.to_s)
551
+ end
552
+
553
+ alias h string
554
+
555
+ def multiline(value)
556
+ value.to_s.lines.map {|s| escape_html(s.strip) }.join('<br />')
557
+ end
558
+
559
+ def date(t)
560
+ t.strftime('%Y-%m-%d')
561
+ end
562
+
563
+ def timestamp(t)
564
+ t.strftime('%Y-%m-%d %H:%M:%S')
565
+ end
566
+ end
567
+
568
+
569
+ class Models < Struct
570
+ def values_at(*keys)
571
+ keys.map {|k| self[k] }
572
+ end
573
+ end
574
+
575
+ end