teradata-cli 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # $Id: standalone.rb 994 2004-12-08 15:16:41Z aamine $
4
+ #
5
+ # Stand-alone server based on WEBrick
6
+ #
7
+
8
+ $KCODE = 'UTF-8' unless defined?(Encoding)
9
+ $LOAD_PATH.push '.' unless $LOAD_PATH.include?('.')
10
+
11
+ require 'tdwalker'
12
+ require 'teradata'
13
+ require 'bitweb'
14
+ require 'bitdao'
15
+ require 'bitdao/teradata'
16
+ require 'webrick'
17
+ require 'optparse'
18
+ require 'logger'
19
+
20
+ def main
21
+ @port = 10080
22
+ @host = 'localhost'
23
+ @appdir = File.expand_path(File.dirname($0))
24
+ @logon_string = nil
25
+ @debug = false
26
+
27
+ parser = OptionParser.new
28
+ parser.banner = "#{$0} [--port=NUM] [--debug]"
29
+ parser.on('-p', '--port=NUM', 'Listening port number') {|num|
30
+ @port = num.to_i
31
+ }
32
+ parser.on('-h', '--hostname=NAME', 'Server host name') {|name|
33
+ @host = name
34
+ }
35
+ parser.on('-l', '--logon-string=STR', 'Teradata logon string') {|str|
36
+ @logon_string = str
37
+ }
38
+ parser.on('--[no-]debug', 'Debug mode') {|flag|
39
+ @debug = flag
40
+ }
41
+ parser.on('--help', 'Prints this message and quit') {
42
+ puts parser.help
43
+ exit 0
44
+ }
45
+ begin
46
+ parser.parse!
47
+ unless @logon_string
48
+ $stderr.puts "--logon-string option is mandatory"
49
+ exit 1
50
+ end
51
+ rescue OptionParser::ParseError => err
52
+ $stderr.puts err.message
53
+ $stderr.puts parser.help
54
+ exit 1
55
+ end
56
+ start_server
57
+ end
58
+
59
+ def start_server
60
+ server = WEBrick::HTTPServer.new(
61
+ :Port => @port,
62
+ :AccessLog => [
63
+ [ $stderr, WEBrick::AccessLog::COMMON_LOG_FORMAT ],
64
+ [ $stderr, WEBrick::AccessLog::REFERER_LOG_FORMAT ],
65
+ [ $stderr, WEBrick::AccessLog::AGENT_LOG_FORMAT ],
66
+ ],
67
+ :Logger => WEBrick::Log.new($stderr, WEBrick::Log::DEBUG)
68
+ )
69
+ server.mount '/', BitWeb::WEBrickServlet, request_handler()
70
+ server.mount '/htdocs/', WEBrick::HTTPServlet::FileHandler, "#{@appdir}/htdocs"
71
+ trap(:INT) { server.shutdown }
72
+ server.start
73
+ end
74
+
75
+ def request_handler
76
+ log = Logger.new($stderr)
77
+ TDWalker::RequestHandler.new(
78
+ log,
79
+ TDWalker::ViewManager.new(
80
+ log,
81
+ "#{@appdir}/template",
82
+ "#{@appdir}/messages",
83
+ "http://#{@host}:#{@port}"
84
+ ),
85
+ TDWalker::Models.new(
86
+ TDWalker::DAO.new(
87
+ log,
88
+ Teradata.connect(@logon_string)
89
+ )
90
+ )
91
+ )
92
+ end
93
+
94
+ main
@@ -0,0 +1,42 @@
1
+ require 'bitweb'
2
+ require 'bitdao'
3
+
4
+ module TDWalker
5
+
6
+ class RequestHandler < BitWeb::RequestHandler; end
7
+
8
+ Models = BitWeb::Models.new(:dao)
9
+
10
+ ViewManager = BitWeb::ViewManager
11
+
12
+ class Screen < BitWeb::TemplateScreen
13
+ def database_url(name)
14
+ url("/database/show?name=#{name}")
15
+ end
16
+ end
17
+
18
+ class Controller < BitWeb::Controller; end
19
+
20
+ class DatabaseController < Controller
21
+ depends :dao
22
+
23
+ ShowScreen = Screen.new_class(:database)
24
+
25
+ def handle_show(req)
26
+ name = req.get('name') {|val|
27
+ val.must_string
28
+ val.string.strip
29
+ }
30
+ @views.new(ShowScreen, @dao.database(name))
31
+ end
32
+ end
33
+
34
+ class DAO < BitDAO
35
+ def database(name)
36
+ @connection.database(name)
37
+ end
38
+ end
39
+
40
+ class Error < ::StandardError; end
41
+
42
+ end
@@ -0,0 +1,56 @@
1
+ .include header
2
+ <title>database <%= string database.name %></title>
3
+ </head>
4
+ <body>
5
+
6
+ <div id="header">
7
+ <h1>database <%= string database.name %></h1>
8
+ </div>
9
+
10
+ <ol class="topicpath">
11
+ <% database.parents.reverse_each do |parent| %>
12
+ <li><a href="<%= database_url(parent.name) %>"><%= string parent.name %></a></li>
13
+ <% end %>
14
+ <li><%= string database.name %></li>
15
+ </ol>
16
+
17
+ <h2>ディスク容量</h2>
18
+ <table id="perms">
19
+ <tr><th>Own Current Perm</th><td><%= int database.current_perm %></td></tr>
20
+ <tr><th>Own Max Perm</th> <td><%= int database.max_perm %></td></tr>
21
+ <tr><th>Own Peak Perm</th> <td><%= int database.peak_perm %></td></tr>
22
+ <tr><th>Total Current Perm</th><td><%= int database.total_current_perm %></td></tr>
23
+ <tr><th>Total Max Perm</th> <td><%= int database.total_max_perm %></td></tr>
24
+ <tr><th>Total Peak Perm</th> <td><%= int database.total_peak_perm %></td></tr>
25
+ </table>
26
+
27
+ <h2>子データベース</h2>
28
+
29
+ <ul>
30
+ <% database.children.sort_by {|c| c.name.downcase }.each do |child| %>
31
+ <li><a href="<%= database_url(child.name) %>"><%= string child.name %></a></li>
32
+ <% end %>
33
+ </ul>
34
+
35
+ <h2>テーブル</h2>
36
+
37
+ <table id="tables">
38
+ <thead>
39
+ <tr>
40
+ <th>テーブル名</th>
41
+ <th>Current Perm</th>
42
+ <th>Peak Perm</th>
43
+ </tr>
44
+ </thead>
45
+ <tbody>
46
+ <% database.tables.sort_by {|t| t.unqualified_name }.each do |table| %>
47
+ <tr>
48
+ <td><%= string table.unqualified_name %></td>
49
+ <td><%= int table.current_perm %></td>
50
+ <td><%= int table.peak_perm %></td>
51
+ </tr>
52
+ <% end %>
53
+ </tbody>
54
+ </table>
55
+
56
+ .include footer
@@ -0,0 +1,2 @@
1
+ </body>
2
+ </html>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
5
+ <head>
6
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
7
+ <meta http-equiv="Content-Style-Type" content="text/css" />
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Dispatches non-SELECT DML or DDL.
4
+ #
5
+ # Usage:
6
+ # $ export LOGON_STRING=dbc/user,pass
7
+ # $ ruby example/update.rb 'CREATE TABLE x (x INTEGER)'
8
+ #
9
+
10
+ require 'teradata'
11
+ require 'logger'
12
+ require 'pp'
13
+
14
+ logon_string = ENV['LOGON_STRING']
15
+ unless logon_string
16
+ $stderr.puts "set environment variable LOGON_STRING"
17
+ exit 1
18
+ end
19
+
20
+ sql = ARGV[0]
21
+ unless sql
22
+ $stderr.puts "Usage: ruby #{File.basename($0)} QUERY"
23
+ exit 1
24
+ end
25
+
26
+ log = Logger.new($stderr)
27
+ log.sev_threshold = $DEBUG ? Logger::DEBUG : Logger::INFO
28
+
29
+ Teradata.connect(logon_string, :logger => log) {|conn|
30
+ pp conn.update(sql)
31
+ }
@@ -0,0 +1,363 @@
1
+ /*
2
+ * $Id: cli.c 629 2010-02-17 01:46:11Z aamine $
3
+ *
4
+ * Copyright (C) 2009,2010 Teradata Japan, LTD.
5
+ *
6
+ * This program is free software.
7
+ * You can distribute/modify this program under the terms of
8
+ * the GNU LGPL2, Lesser General Public License version 2.
9
+ */
10
+
11
+ #include <ruby.h>
12
+ #include <stdio.h>
13
+ #include <stdlib.h>
14
+ #include <string.h>
15
+ #include <signal.h>
16
+ #include <sys/types.h>
17
+
18
+ #include <coptypes.h>
19
+ #include <coperr.h>
20
+ #include <dbcarea.h>
21
+ #include <parcel.h>
22
+
23
+ static VALUE CLI;
24
+ static VALUE CLIError;
25
+
26
+ struct rb_cli {
27
+ VALUE initialized; // bool
28
+ VALUE logging_on; // bool
29
+ char session_charset[36];
30
+ #define CHARSET_BUFSIZE 32
31
+ struct DBCAREA dbcarea;
32
+ };
33
+
34
+ static VALUE cli_initialized = Qfalse;
35
+
36
+ static struct rb_cli * get_cli(VALUE self);
37
+ static void cli_free(struct rb_cli *p);
38
+ static void logon(struct rb_cli *p, char *logon_string);
39
+ static void logoff(struct rb_cli *p, VALUE force);
40
+ static void dispatch(struct rb_cli *p, Int32 func);
41
+ static char* status_name(Int32 status);
42
+ static char* flavor_name(Int32 flavor);
43
+
44
+ static struct rb_cli *
45
+ check_cli(VALUE self)
46
+ {
47
+ Check_Type(self, T_DATA);
48
+ if (RDATA(self)->dfree != (RUBY_DATA_FUNC)cli_free) {
49
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected CLI)",
50
+ rb_class2name(CLASS_OF(self)));
51
+ }
52
+ return DATA_PTR(self);
53
+ }
54
+
55
+ static struct rb_cli *
56
+ get_cli(VALUE self)
57
+ {
58
+ struct rb_cli *p = check_cli(self);
59
+ if (!p || !p->initialized) {
60
+ rb_raise(rb_eRuntimeError, "uninitialized CLI object");
61
+ }
62
+ return p;
63
+ }
64
+
65
+ static VALUE
66
+ cli_s_allocate(VALUE klass)
67
+ {
68
+ struct rb_cli* p;
69
+
70
+ p = ALLOC_N(struct rb_cli, 1);
71
+ p->dbcarea.total_len = sizeof(struct DBCAREA);
72
+ p->initialized = Qfalse;
73
+ p->logging_on = Qfalse;
74
+ return Data_Wrap_Struct(klass, NULL, cli_free, p);
75
+ }
76
+
77
+ static void
78
+ cli_free(struct rb_cli *p)
79
+ {
80
+ if (p->logging_on) {
81
+ logoff(p, Qtrue);
82
+ }
83
+ }
84
+
85
+ static VALUE
86
+ cli_initialize(VALUE self, VALUE logon_string, VALUE session_charset)
87
+ {
88
+ struct rb_cli *p;
89
+ Int32 status;
90
+ char dummy[4] = {0,0,0,0};
91
+
92
+ p = check_cli(self);
93
+ if (p->initialized) {
94
+ rb_raise(rb_eRuntimeError, "already initialized CLI object");
95
+ }
96
+
97
+ StringValue(logon_string);
98
+ StringValue(session_charset);
99
+
100
+ DBCHINI(&status, dummy, &p->dbcarea);
101
+ if (status != EM_OK) {
102
+ rb_raise(CLIError, "CLI error: [%s] %s",
103
+ status_name(status), p->dbcarea.msg_text);
104
+ }
105
+ cli_initialized = Qtrue;
106
+
107
+ p->dbcarea.change_opts = 'Y';
108
+ p->dbcarea.wait_for_resp = 'Y'; // Complete response and return.
109
+ p->dbcarea.keep_resp = 'N'; // We do not rewind.
110
+ p->dbcarea.wait_across_crash = 'Y'; // CLI returns when DBC is not available.
111
+ p->dbcarea.tell_about_crash = 'Y';
112
+ p->dbcarea.use_presence_bits = 'N'; // We do not send data by record
113
+ p->dbcarea.var_len_req = 'N';
114
+ p->dbcarea.var_len_fetch = 'N';
115
+ p->dbcarea.loc_mode = 'Y'; // Locate mode (not move mode)
116
+ p->dbcarea.parcel_mode = 'Y';
117
+ p->dbcarea.save_resp_buf = 'N'; // free response buffer
118
+ p->dbcarea.two_resp_bufs = 'N'; // disable double buffering
119
+ p->dbcarea.ret_time = 'N';
120
+ p->dbcarea.resp_mode = 'I'; // Indicator mode
121
+ p->dbcarea.req_proc_opt = 'B'; // process request and return response,
122
+ // with column names and EXPLAIN data.
123
+
124
+ p->dbcarea.charset_type = 'N'; // multibyte character set
125
+ snprintf(p->session_charset, CHARSET_BUFSIZE,
126
+ "%-30s", StringValueCStr(session_charset));
127
+ p->dbcarea.inter_ptr = p->session_charset;
128
+
129
+ logon(p, StringValueCStr(logon_string));
130
+ p->initialized = Qtrue;
131
+
132
+ return Qnil;
133
+ }
134
+
135
+ static void
136
+ logon(struct rb_cli *p, char *logon_string)
137
+ {
138
+ if (p->logging_on) {
139
+ rb_raise(CLIError, "already logged on");
140
+ }
141
+ p->dbcarea.logon_ptr = logon_string;
142
+ p->dbcarea.logon_len = strlen(logon_string);
143
+ dispatch(p, DBFCON);
144
+ p->dbcarea.i_sess_id = p->dbcarea.o_sess_id;
145
+ p->dbcarea.i_req_id = p->dbcarea.o_req_id;
146
+ p->logging_on = Qtrue;
147
+ }
148
+
149
+ static VALUE
150
+ cli_logoff(VALUE self)
151
+ {
152
+ struct rb_cli *p = get_cli(self);
153
+ if (! p->logging_on) {
154
+ rb_raise(CLIError, "is already logged off");
155
+ }
156
+ logoff(p, Qfalse);
157
+ return Qnil;
158
+ }
159
+
160
+ static void
161
+ logoff(struct rb_cli *p, VALUE force)
162
+ {
163
+ Int32 status;
164
+ char dummy[4] = {0, 0, 0, 0};
165
+
166
+ p->dbcarea.func = DBFDSC;
167
+ DBCHCL(&status, dummy, &p->dbcarea);
168
+ if (!force && status != EM_OK) {
169
+ rb_raise(CLIError, "CLI error: [%s] %s",
170
+ status_name(status), p->dbcarea.msg_text);
171
+ }
172
+ p->logging_on = Qfalse;
173
+ }
174
+
175
+ static VALUE
176
+ cli_logging_on_p(VALUE self)
177
+ {
178
+ struct rb_cli *p = get_cli(self);
179
+ return p->logging_on;
180
+ }
181
+
182
+ /* must be called only once in process, at the finalize step. */
183
+ static VALUE
184
+ cli_cleanup(VALUE mod)
185
+ {
186
+ Int32 status;
187
+ char dummy[4];
188
+
189
+ DBCHCLN(&status, dummy);
190
+ if (status != EM_OK) {
191
+ rb_raise(CLIError, "CLI cleanup failed");
192
+ }
193
+ return Qnil;
194
+ }
195
+
196
+ static VALUE
197
+ cli_session_charset(VALUE self)
198
+ {
199
+ struct rb_cli *p = get_cli(self);
200
+ return rb_str_new2(p->session_charset);
201
+ }
202
+
203
+ static VALUE
204
+ cli_send_request(VALUE self, VALUE sql_value)
205
+ {
206
+ struct rb_cli *p = get_cli(self);
207
+ StringValue(sql_value);
208
+ p->dbcarea.req_ptr = RSTRING_PTR(sql_value);
209
+ p->dbcarea.req_len = RSTRING_LEN(sql_value);
210
+ dispatch(p, DBFIRQ);
211
+ p->dbcarea.i_sess_id = p->dbcarea.o_sess_id;
212
+ p->dbcarea.i_req_id = p->dbcarea.o_req_id;
213
+ return Qnil;
214
+ }
215
+
216
+ static VALUE
217
+ cli_end_request(VALUE self)
218
+ {
219
+ struct rb_cli *p = get_cli(self);
220
+ dispatch(p, DBFERQ);
221
+ return Qnil;
222
+ }
223
+
224
+ static VALUE
225
+ cli_fetch(VALUE self)
226
+ {
227
+ struct rb_cli *p = get_cli(self);
228
+ dispatch(p, DBFFET);
229
+ return Qnil;
230
+ }
231
+
232
+ static VALUE
233
+ cli_message(VALUE self)
234
+ {
235
+ struct rb_cli *p = get_cli(self);
236
+ return rb_str_new2(p->dbcarea.msg_text);
237
+ }
238
+
239
+ static VALUE
240
+ cli_data(VALUE self)
241
+ {
242
+ struct rb_cli *p = get_cli(self);
243
+ return rb_str_new(p->dbcarea.fet_data_ptr, p->dbcarea.fet_ret_data_len);
244
+ }
245
+
246
+ static void
247
+ dispatch(struct rb_cli *p, Int32 func)
248
+ {
249
+ Int32 status;
250
+ char dummy[4] = {0, 0, 0, 0};
251
+
252
+ p->dbcarea.func = func;
253
+ DBCHCL(&status, dummy, &p->dbcarea);
254
+ if (status != EM_OK) {
255
+ rb_raise(CLIError, "CLI error: [%s] %s",
256
+ status_name(status), p->dbcarea.msg_text);
257
+ }
258
+ }
259
+
260
+ static char*
261
+ status_name(Int32 status)
262
+ {
263
+ switch (status) {
264
+ case EM_OK: return "EM_OK";
265
+ case EM_BUFSIZE: return "EM_BUFSIZE";
266
+ case EM_FUNC: return "EM_FUNC";
267
+ case EM_NETCONN: return "EM_NETCONN";
268
+ case EM_NOTIDLE: return "EM_NOTIDLE";
269
+ case EM_REQID: return "EM_REQID";
270
+ case EM_NOTACTIVE: return "EM_NOTACTIVE";
271
+ case EM_NODATA: return "EM_NODATA";
272
+ case EM_DATAHERE: return "EM_DATAHERE";
273
+ case EM_ERRPARCEL: return "EM_ERRPARCEL";
274
+ case EM_CONNECT: return "EM_CONNECT";
275
+ case EM_BUFOVERFLOW: return "EM_BUFOVERFLOW";
276
+ case EM_TIMEOUT: return "EM_TIMEOUT";
277
+ case EM_BREAK: return "EM_BREAK";
278
+ case SESSOVER: return "SESSOVER";
279
+ case NOREQUEST: return "NOREQUEST";
280
+ case BADPARCEL: return "BADPARCEL";
281
+ case REQEXHAUST: return "REQEXHAUST";
282
+ case BUFOVFLOW: return "BUFOVFLOW";
283
+ default:
284
+ {
285
+ static char buf[64];
286
+ sprintf(buf, "EM_%d", status);
287
+ return buf;
288
+ }
289
+ }
290
+ }
291
+
292
+ static VALUE
293
+ cli_flavor_name(VALUE self)
294
+ {
295
+ struct rb_cli *p = get_cli(self);
296
+ return rb_str_new2(flavor_name(p->dbcarea.fet_parcel_flavor));
297
+ }
298
+
299
+ static char*
300
+ flavor_name(Int32 flavor)
301
+ {
302
+ switch (flavor) {
303
+ case PclREQ: return "PclREQ";
304
+ case PclRUNSTARTUP: return "PclRUNSTARTUP";
305
+ case PclDATA: return "PclDATA";
306
+ case PclRESP: return "PclRESP";
307
+ case PclKEEPRESP: return "PclKEEPRESP";
308
+ case PclABORT: return "PclABORT";
309
+ case PclCANCEL: return "PclCANCEL";
310
+ case PclSUCCESS: return "PclSUCCESS";
311
+ case PclFAILURE: return "PclFAILURE";
312
+ case PclERROR: return "PclERROR";
313
+ case PclRECORD: return "PclRECORD";
314
+ case PclENDSTATEMENT: return "PclENDSTATEMENT";
315
+ case PclENDREQUEST: return "PclENDREQUEST";
316
+ case PclFMREQ: return "PclFMREQ";
317
+ case PclFMRUNSTARTUP: return "PclFMRUNSTARTUP";
318
+ case PclVALUE: return "PclVALUE";
319
+ case PclNULLVALUE: return "PclNULLVALUE";
320
+ case PclOK: return "PclOK";
321
+ case PclFIELD: return "PclFIELD";
322
+ case PclNULLFIELD: return "PclNULLFIELD";
323
+ case PclLOGON: return "PclLOGON";
324
+ case PclLOGOFF: return "PclLOGOFF";
325
+ case PclDATAINFO: return "PclDATAINFO";
326
+ case PclOPTIONS: return "PclOPTIONS";
327
+ case PclPREPINFO: return "PclPREPINFO";
328
+ case PclPREPINFOX: return "PclPREPINFOX";
329
+ case PclXDIX: return "PclDATAINFOX";
330
+ default:
331
+ {
332
+ static char buf[64];
333
+ sprintf(buf, "flavor_%d", flavor);
334
+ return buf;
335
+ }
336
+ }
337
+ }
338
+
339
+ void
340
+ Init_cli(void)
341
+ {
342
+ VALUE Teradata, Teradata_Error;
343
+
344
+ Teradata = rb_define_module("Teradata");
345
+ Teradata_Error = rb_const_get(Teradata, rb_intern("Error"));
346
+
347
+ CLI = rb_define_class_under(Teradata, "CLI", rb_cObject);
348
+ rb_define_const(CLI, "Id", rb_str_new2("$Id: cli.c 629 2010-02-17 01:46:11Z aamine $"));
349
+ rb_define_singleton_method(CLI, "cleanup", cli_cleanup, 0);
350
+ rb_define_alloc_func(CLI, cli_s_allocate);
351
+ rb_define_private_method(CLI, "initialize", cli_initialize, 2);
352
+ rb_define_method(CLI, "logoff", cli_logoff, 0);
353
+ rb_define_method(CLI, "logging_on?", cli_logging_on_p, 0);
354
+ rb_define_method(CLI, "session_charset", cli_session_charset, 0);
355
+ rb_define_method(CLI, "fetch", cli_fetch, 0);
356
+ rb_define_method(CLI, "send_request", cli_send_request, 1);
357
+ rb_define_method(CLI, "end_request", cli_end_request, 0);
358
+ rb_define_method(CLI, "message", cli_message, 0);
359
+ rb_define_method(CLI, "data", cli_data, 0);
360
+ rb_define_method(CLI, "flavor_name", cli_flavor_name, 0);
361
+
362
+ CLIError = rb_define_class_under(Teradata, "CLIError", Teradata_Error);
363
+ }