File: Help.pm

package info (click to toggle)
dbishell 0.8.9-7
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 828 kB
  • ctags: 1,423
  • sloc: perl: 13,353; makefile: 138; sh: 15
file content (521 lines) | stat: -rw-r--r-- 15,777 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
package DBIShell::Help;

#  dbishell: A generic database shell based on the Perl DBI layer
#  Copyright (C) 2000  Vivek Dasmohapatra (vivek@etla.org)

#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.

#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.

#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

use strict;
use Exporter ();

use vars qw($VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS @ISA %HELP);

use constant H_DESCRIBE => <<'HelpDescribe';
describe <target>/

retrieves a description of the target object: the target object may be an unqualified name, or a name in the SCHEMA_OR_DB.NAME format, or, at the specific dr::DATABASE engine's option, any other format it knows how to resolve. The basic dr::DEFAULT engine only knows how to describe tables, since DB engines typically don't have enough in common for anything but this to be implemented generically. Note that the data types that you see in this generic 'describe' are the SQL9x standard names, not the database specific names implemented by various vendors.

see also: show
HelpDescribe

use constant H_VARIABLES => <<'HelpVariables';
variables:

Variables are of the form $NAME or $xxx:NAME, where xxx is one of:
'dbi' or 'env'

Variables are set with the syntax:

$VARIABLE=some value or other/

And are unset as follows:

$!VARIABLE/

variables are implemented in the shell layer, the dr::DATABASE engine
never sees them, and they are _not_ the same as any SQL variables that
your DB vendor might have implemented, thus they can be placed in any part
of a SQL query, even ones where the DB engine does not normall allow
variables.

The escape sequences \n \t \r are recognised, and quotes aren't special
in any way.

Variables are not the same as parameters, but they are related.
[parameters are more restricted, and yet morepowerful in some ways]

****************************************************************************
* NOTE: 
*
* If a variable containing the value undef [ie an unset variable]
* is interpolated into a query, it will strip any quotes immediately
* surrounding it from the query. This is so that you can do things like:
*
*  $!ARGH/
*  update FOO set BAR = '$ARGH' where SOMETHING = 'wibble'/
*
*  And it actually evaluates as:
*
*  update FOO set BAR = NULL where SOMETHING = 'wibble'/
*
****************************************************************************
see also: interpolation parameters formatting environment dbi_attr
HelpVariables


use constant H_ENVIRONMENT => <<'HelpEnv';
environment:

environment variables are gettable/settable as variables with names like
$env:HOME. Other than the namespace indicator, they can be used anywhere
that normal variables can be used, subject to the limitation that they
are stored in the environment, and are therfore bound by the same restrictions
that apply to the environment on your system, whatever they may be.

see also: variables interpolation parameters dbi_attr
HelpEnv

use constant H_DBIATTR => <<'HelpDbiAttr';
dbi_attr:

DBI attributes are accessible as variable of the form:

$dbi:LongTruncOk

Any and all DBI attributes implemented by the DBD driver you are using are
available, common ones include:

$dbi:Warn
$dbi:Active
$dbi:Kids
$dbi:ActiveKids
$dbi:PrintError           *
$dbi:RaiseError
$dbi:ChopBlanks           *
$dbi:LongTruncOk          *
$dbi:LongReadLen          *
$dbi:AutoCommit           *
$dbi:RowcacheSize

The interesting ones have been marked with a '*'. You are referred to the
DBI documentation, but I will note here that AutoCommit controls whether
you need to/are able to issue commits/rollbacks or not.

You may not unset dbi attributes, nor may you bind them as parameters. All
sorts of horrible things would happen if you did. Don't make me come over
there.

see also: variables parameters environment interpolation
HelpDbiAttr

use constant H_PARAMETERS => <<'HelpParameters';
parameters:

You may or may not be familiar with parametrised queries, it is beyond the
scope of this help system to discuss their uses and limitations: I shall
simply say here that they are similar to variabkes, but there insertion is
handled by the SQL engine itself: They are therefore subject to optimisation
by the SQL engine itself, but may not, [usually] be used anywhere where they
would prevent the database from validating the syntax of the query.

[ For example, you may not, in general, parametrise a table or field name
  in a query, as this would prevent the SQL engine from being able to tell
  if all your field names were valid. ]

Sybase and its derivative engines [eg MSSQL Server] impose the further
restriction that only where clause comparison values may be parametrised

dbishell stores its parametes in the same place as its variables: For in
parameters, the value is read from the variable of the same name as the
parameter, and for in/out parameters, the returned value is stored there
too.

In parameters take the form:      $>FOO
and out parameters take the form: $<FOO

parameters need not be [and should not be] quoted: 

eg:
$FOO=arglebargle/
select * from j_random_table where field_foo = $>FOO/

will work just fine. You may not bind DBI attributes as parameters.
Did I mention that you may not bind DBI attributes as parameters? Good.

For drivers that allow it, you may use in/out parameters to catch the return
values of out or in/out parameters from procedure calls.

see also: procedure_calls variables environment dbi_attr
HelpParameters

use constant H_LOGGING => <<'HelpLogging';
logging:

You can log the input, error [info] and output [data, results] streams
into multiple files, independently of one another:

spool error,output /tmp/dbishell.log on/
# error and output go to /tmp/dbishell.log
spool error,output /tmp/dbishell.log off/
# error and output no longer logged

spool input /tmp/dbilog2.txt on/
# input goes to /tmp/dbilog2.txt
spool input,output,error /tmp/dbilog3.txt on/
# all 3 go to /tmp/dbilog3.txt
spool error off/
# all error logging stopped
spool input /tmp/dbilog2.txt off/
# input no longer goes to /tmp/dbilog2.txt
# input,output still going to /tmp/dbilog3.txt

I hope you get the idea...
I intend to add logfile filters/transformations, but I haven't decided on the
exact mechanism/infrastructure yet. more later.
HelpLogging


use constant H_INTERP_ESCP => <<'HelpInterpEscp';
interpolation on
interpolation off
escaping on
escaping off

Thes commands turn on and off the interpolation of variables and the
interpretation of \X style escape sequences by the dbishell: they have no
effect on any \X escaping done/undersood by the SQL engine itself, or any
SQL variables as implemented by the SQL dialect your database speaks

see also: variables parameters environment dbi_attr
HelpInterpEscp

use constant H_DISCONNECT => <<'HelpDisconnect';
disconnect/

disconnects from the database you are currently connected to. Drops you back
to a dr::DEFAULT engine driving a conection to a NullP database [NullP is a
dummy/test SQL engine provided with the perl DBI for testing]

see also: connect
HelpDisconnect

use constant H_CONNECT => <<'HelpConnect';
connect [driver [dsn  [user [pass]]]]/

drops your current connection like a hot rock and connects you [if possible]
to the new DB specified by your parameters. Any parameters omitted will be
collected interactively [and if the password is so collected, it will not
br echoed as you type it]

see also: disconnect
HelpConnect

use constant H_SUBSHELL => <<'HelpSubshell';
!<shell command>/
  
Executes a cmmand in a subshell. If the command is empty, a subshell is
spawned. ^D or 'exit' to et back to dbishell.
HelpSubshell

use constant H_READ => <<'HelpRead';
read <filename>/

Reads and executes the file specified as if each line therein wre entered
manually by you at the prompt. Hooray. Now I have scripts for mysql. Shiny.
HelpRead

use constant HELP_STRING => <<'HelpMessage';

   --driver                 # DBIShell driver
   --dsn                    # dsn [The bit after 'dbi:<DRIVER>:' ]
   --user|u                 # database user name
   --pass|passwd|password|p # database password
   --help|h                 # print the help and exit
   --shell-driver           # real DBIShell driver to use if
                            # using driver=Proxy or driver=ODBC
   --dotdir                 # location of your dbishell dotfiles

All of these are implemented to some extent, some might be problematic...

1) Commands must be terminated with a trailing /
   Or, if you want to, you can configure it by setting the $EOL variable.
   No, it can't default to ';', that would cause problems w. dr::Oracle.
   So stop complaining already. [You know who you are]

2) Tab completion should be available. The mysql tab completer is reasonably
   smart, the Oracle one will be once I get some more work done on it.

3)Special variables:
	  
   $FIELD_SEPARATOR
   
   Contains the character sequence used to separate fields in output.
   If unset, you get '|' as the separator.
   
   $PRESCAN_FORMAT
   
   If true, [cf. Perl "What is truth"] then the whole of the dataset
   returned by all queries is prescanned, and the output formatted accordingly
   This can be helpful when you have large columns which typically hold
   values much shorter than they have the capacity for, since it shrinks
   the display columns down to the size of the largest output value on a per
   column basis. On the other hand, if you're fetching large numbers of rows,
   This may hurt, since you'll be prefetching the whole dataset into memory,
   scanning it, and then printing it. 
   
   $TRUNCATE_COLUMN_NAMES
   
   If false, a column will never be narrower than its name in the output.
   Othewise, column names will be shortened to fit their columns display
   widths [if PRESCAN_ROWS is set]
   
   $CASE_SENSITIVE
   
   Is the DB case sensitive or not? [mainly effects tab completion]
   
   $PAGER 
   
   The command to open a pipe to, to use as a pager. If $PAGER is unset,
   $env:PAGER is tried instead, and if there's nothing there, 'less -S'
   is used instead. If that doesn't work, then bad things probably 
   happen. Like paging not working, and maybe your output disappearing.
   
   $PAGING
   
   If this is true, then output from certain commands [just selects at 
   the moment] will be paged, depending on the value of $PAGE_SIZE and 
   $PRESCAN_FORMAT

   $PAGE_SIZE

   The number of rows above which dbishell will try to page output.
   Paging is decided as follows:

   If $PAGING is true, and $PRESCAN_FORMAT is true, output exceeding
   $PAGE_SIZE [or exceeding the size of the terminal, if $PAGE_SIZE
   is 0 or unset] will be paged.

   If $PRESCAN_FORMAT is false, and $PAGING is true, then output will 
   be paged regardless of the amount of data returned, unless the DBI 
   driver can determine the number of rows before they are all fetched.

   $EOL

   The end of line character used by dbishell to determine when you want
   a command executed. If unset [the default] then '/' is used.
   [except that the '/' that terminates a comment will be ignored].
   Otherwise, whatever you put in $EOL will be scanned for.

4) History:

   Command history is stored in ~/.dbishell/<driver>.history

5) Examples:

dbishell --driver Oracle --dsn host=foobar\;sid=argh        --user=scott
dbishell --driver mysql  --dsn host=narf\;database=argh     --user vivek
dbishell --driver Sybase --dsn hostname=narf\;database=argh --user=sa
dbishell --driver ODBC   --dsn FOO:  --shell-driver=Sybase  --user sa

6) DSN strings

dbishell and DBI have slightly different views of the meaning of the
term 'DSN'.

DBI expects a DSN in the following forms:

  dbi:DriverName:database_name
  dbi:DriverName:database_name@hostname
  dbi:DriverName:database_name~hostname!port
  dbi:DriverName:database=database_name;host=hostname;port=port

(examples from DBI man page).

dbishell requires you to specify the driver seperately, and the 
above examples would be handed as:

  database_name
  database_name@hostname
  database_name~hostname!port
  database_name;host=hostname;port=port

These strings would be arguments to the --dsn parameter, with the
actual database driver to use specified with --driver and --shell-driver.

The 'dbi' string is dropped, as it is implicit that if you are using
dbishell you are connecting to a dbi data source.

7) Help topics:

help
show
read
describe
interpolation
escaping
parameters
dbi_attr
environment
procedure_calls
logging
connect
disconnect
subshell
quit

Vivek Dasmohapatra <vivek@etla.org>


HelpMessage

@ISA         = qw(Exporter);
@EXPORT      = ();
@EXPORT_OK   = qw(HELP_STRING);
%EXPORT_TAGS = ();
$VERSION     = 0.01_11;

%HELP = (
	 interpolation => H_INTERP_ESCP,
	 escaping      => H_INTERP_ESCP,
	 parameters    => H_PARAMETERS,
	 environment   => H_ENVIRONMENT,
	 dbi_attr      => H_DBIATTR,
	 variables     => H_VARIABLES,
	 connect       => H_CONNECT,
	 disconnect    => H_DISCONNECT,
	 subshell      => H_SUBSHELL,
	 read          => H_READ,
	 logging       => H_LOGGING,
	 quit          => "quit/\n\nquits dbishell"
	);

sub help_map ($) { return ref($_[0]) ? $_[0]->{MAP} : \%HELP }

sub help ($$)
{
    my $help     = $_[0];
    my $hcontext = $_[1]; # don't do anything w. this yet...
    my $map      = $help->help_map();
    
    $hcontext =~ /(\S+)/;
    $hcontext =  lc($1);

    if ($map->{$hcontext})
    {
	return join('',$1,":\n",$map->{$hcontext});
    }
    
    return HELP_STRING;
}

sub topics ($$)
{
    my $l;
    my $help  = $_[0];
    my $topic = lc($_[1]);
    my $map   = $help->help_map();
    
    if($l = length($topic))
    {
	return (grep { substr($_, 0, $l) eq $topic } keys(%{$map}));
    }
    else
    {
	return keys(%{$map});
    }
}

sub name ($) { return ref($_[0]) ? $_[0]->{NAME} : __PACKAGE__ }

sub new ($$)
{
    my $help;
    my $db_help;
    my @db_help;
    my $package  = ref($_[0]) || $_[0];
    my $database = $_[1];
    
    $help = { MAP => {} };
    
    push(@db_help, $package);
    
    $db_help = join('::','DBIShell::help',$database);
    $db_help = DBIShell::UTIL::dynaload($db_help);
    push(@db_help, $db_help);
    
    foreach $db_help (grep {$_} @db_help)
    {
	warn("######\nLoading help from $db_help\n#####\n");
	$help->{NAME} = $db_help;
	my $map = $db_help->help_map();
	foreach my $topic (keys(%{$map}))
	{
	    $help->{MAP}{$topic} = $map->{$topic};
	}
    }
    
    return bless($help, $package);
}

__END__
#TLF: Nikola Tesla died for you...

=pod
 
=head1 NAME

DBIShell::Help - DBIShell help messages

=head1 SYNOPSIS

  use DBIShell::Help;

=head1 DESCRIPTION

This module provides help text for dbishell

=head1 METHODS

=head2 DBIShell::Help->new(DATABASE)

Create a new help object, for the specified DATABASE, if possible
[will be loaded from DBIShell::help::<DATABASE> if it is there]

=head2 $help->name()

Return the name of the package from which help is actually being
harvested

=head2 $help->topics(FRAG)

Return a list of topics that match fragment FRAG

=head2 $help->help(TOPIC)

Return the help for topic TOPIC

=head2 help_map

Return a reference to the hash containing the topic -> text map

=head1 SEE ALSO

dbishell

=head1 AUTHOR

Vivek Dasmohapatra <vivek@etla.org>

=cut