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.
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
+ }