Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
be5bfd54
Commit
be5bfd54
authored
Jul 23, 1996
by
Marc G. Fournier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Put in a new FAQ
Merged in Dr. George's src/bin tree (possibly broke monitor/psql in process)
parent
d1724d65
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
386 additions
and
525 deletions
+386
-525
src/bin/Makefile
src/bin/Makefile
+12
-7
src/bin/initdb/initdb.sh
src/bin/initdb/initdb.sh
+4
-10
src/bin/monitor/monitor.c
src/bin/monitor/monitor.c
+2
-2
src/bin/pg4_dump/common.c
src/bin/pg4_dump/common.c
+1
-1
src/bin/pg4_dump/pg4_dump.c
src/bin/pg4_dump/pg4_dump.c
+1
-1
src/bin/pgtclsh/Makefile
src/bin/pgtclsh/Makefile
+3
-3
src/bin/pgtclsh/pgtclAppInit.c
src/bin/pgtclsh/pgtclAppInit.c
+5
-0
src/bin/pgtclsh/pgtkAppInit.c
src/bin/pgtclsh/pgtkAppInit.c
+5
-0
src/bin/psql/psql.c
src/bin/psql/psql.c
+353
-501
No files found.
src/bin/Makefile
View file @
be5bfd54
...
...
@@ -7,24 +7,29 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/Makefile,v 1.
1.1.1 1996/07/09 06:22:11
scrappy Exp $
# $Header: /cvsroot/pgsql/src/bin/Makefile,v 1.
2 1996/07/23 03:01:58
scrappy Exp $
#
#-------------------------------------------------------------------------
MKDIR
=
../mk
-include
$(MKDIR)/../Makefile.global
#
# C programs
#
SUBDIR
=
monitor pg_id pg_version psql pg_dump
ifeq
($(USE_TCL), true)
SUBDIR
+=
pgtclsh
endif
#
# Shell scripts
#
SUBDIR
+=
cleardbdir createdb createuser destroydb destroyuser initdb
#
# TCL/TK programs
#
ifeq
($(USE_TCL), true)
SUBDIR
+=
pgtclsh
endif
include
../mk
/postgres.subdir.mk
include
$(MKDIR)
/postgres.subdir.mk
src/bin/initdb/initdb.sh
View file @
be5bfd54
...
...
@@ -12,7 +12,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.
3 1996/07/20 07:33:36
scrappy Exp $
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.
4 1996/07/23 03:03:19
scrappy Exp $
#
#-------------------------------------------------------------------------
...
...
@@ -33,10 +33,6 @@ FILESDIR=$PGDATA/files
PATH
=
$BINDIR
:
$PATH
export
PATH
# OPENLINK Added an fsync option to postmaster
# REQUIRES: pg95 compiled with -DOPENLINK_PATCHES, see README_OPENLINK
# FSYNC=-F
CMDNAME
=
`
basename
$0
`
# ----------------
...
...
@@ -63,9 +59,9 @@ done
# ----------------
if
test
"
$debug
"
-eq
1
then
BACKENDARGS
=
"-boot -C
$FSYNC
-d"
BACKENDARGS
=
"-boot -C
-F
-d"
else
BACKENDARGS
=
"-boot -C
$FSYNC
-Q"
BACKENDARGS
=
"-boot -C
-F
-Q"
fi
...
...
@@ -220,9 +216,7 @@ then
echo
"vacuuming template1"
fi
echo
"vacuum"
| postgres
$FSYNC
-Q
template1
>
/dev/null
echo
"vacuum"
| postgres
-F
-Q
template1
>
/dev/null
fi
rm
-f
/tmp/create.
$$
sync
src/bin/monitor/monitor.c
View file @
be5bfd54
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/monitor/Attic/monitor.c,v 1.
4 1996/07/23 02:26:41
scrappy Exp $
* $Header: /cvsroot/pgsql/src/bin/monitor/Attic/monitor.c,v 1.
5 1996/07/23 03:03:24
scrappy Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -20,7 +20,7 @@
#ifndef WIN32
#include <unistd.h>
#endif
#if
def PORTNAME_sparc_solaris
#if
defined(PORTNAME_sparc_solaris) || defined(PORTNAME_i386_solaris)
#include <netdb.h>
/* for MAXHOSTNAMELEN on some */
#endif
#include <sys/types.h>
...
...
src/bin/pg4_dump/common.c
View file @
be5bfd54
...
...
@@ -16,7 +16,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/param.h>
/* for MAXHOSTNAMELEN on most */
#if
def PORTNAME_sparc_solaris
#if
defined(PORTNAME_sparc_solaris) || defined(PORTNAME_i386_solaris)
#include <netdb.h>
/* for MAXHOSTNAMELEN on some */
#endif
...
...
src/bin/pg4_dump/pg4_dump.c
View file @
be5bfd54
...
...
@@ -28,7 +28,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/param.h>
/* for MAXHOSTNAMELEN on most */
#if
def PORTNAME_sparc_solaris
#if
defined(PORTNAME_sparc_solaris) || defined(PORTNAME_i386_solaris)
#include <netdb.h>
/* for MAXHOSTNAMELEN on some */
#endif
...
...
src/bin/pgtclsh/Makefile
View file @
be5bfd54
...
...
@@ -7,7 +7,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/pgtclsh/Attic/Makefile,v 1.
1.1.1 1996/07/09 06:22:15
scrappy Exp $
# $Header: /cvsroot/pgsql/src/bin/pgtclsh/Attic/Makefile,v 1.
2 1996/07/23 03:03:36
scrappy Exp $
#
#-------------------------------------------------------------------------
...
...
@@ -15,7 +15,7 @@ MKDIR= ../../mk
include
$(MKDIR)/postgres.mk
include
../Makefile.global
CFLAGS
+=
-I
$(TCL_INCDIR)
-I
$(TK_INCDIR)
CFLAGS
+=
-I
$(TCL_INCDIR)
-I
$(TK_INCDIR)
-I
$(X11_INCDIR)
-I
$(srcdir)
/libpgtcl
# try to find libpgtcl.a in either directory
LIBPGTCL
=
-L
$(srcdir)
/libpgtcl/
$(objdir)
-L
$(LIBDIR)
-lpgtcl
...
...
@@ -26,7 +26,7 @@ pgtclsh: $(objdir)/pgtclAppInit.o
pgtksh
:
$(objdir)/pgtkAppInit.o
$(CC)
$(CDEBUG)
-o
$(objdir)
/
$
(
@F
)
$(objdir)
/pgtkAppInit.o
\
$(LIBPGTCL)
$(LIBPQ)
-L
$(TCL_LIBDIR)
-L
$(TK_LIBDIR)
\
$(LIBPGTCL)
$(LIBPQ)
-L
$(TCL_LIBDIR)
-L
$(TK_LIBDIR)
-L
$(X11_LIBDIR)
\
$(TK_LIB)
$(TCL_LIB)
-lX11
-lm
$(LD_ADD)
install
::
localobj pgtclsh pgtksh
...
...
src/bin/pgtclsh/pgtclAppInit.c
View file @
be5bfd54
...
...
@@ -109,6 +109,11 @@ Tcl_AppInit(interp)
* then no user-specific startup file will be run under any conditions.
*/
#if (TCL_MAJOR_VERSION <= 7) && (TCL_MINOR_VERSION < 5)
tcl_RcFileName
=
"~/.tclshrc"
;
#else
Tcl_SetVar
(
interp
,
"tcl_rcFileName"
,
"~/.tclshrc"
,
TCL_GLOBAL_ONLY
);
#endif
return
TCL_OK
;
}
src/bin/pgtclsh/pgtkAppInit.c
View file @
be5bfd54
...
...
@@ -112,6 +112,11 @@ Tcl_AppInit(interp)
* then no user-specific startup file will be run under any conditions.
*/
#if (TCL_MAJOR_VERSION <= 7) && (TCL_MINOR_VERSION < 5)
tcl_RcFileName
=
"~/.wishrc"
;
#else
Tcl_SetVar
(
interp
,
"tcl_rcFileName"
,
"~/.wishrc"
,
TCL_GLOBAL_ONLY
);
#endif
return
TCL_OK
;
}
src/bin/psql/psql.c
View file @
be5bfd54
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.
5 1996/07/20 08:44:45
scrappy Exp $
* $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.
6 1996/07/23 03:03:43
scrappy Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -16,8 +16,8 @@
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "libpq-fe.h"
#include "stringutils.h"
...
...
@@ -32,57 +32,52 @@ extern char *readline(char *); /* in rlstubs.c */
#include "history.h"
#else
#include <readline/readline.h>
#include <
readline/
history.h>
#include <history.h>
#endif
#endif
#define MAX_QUERY_BUFFER 20000
#define MAX_FIELD_SEP_LENGTH 40
#define COPYBUFSIZ 8192
#define DEFAULT_FIELD_SEP "
|
"
#define DEFAULT_FIELD_SEP "
"
#define DEFAULT_EDITOR "vi"
#define DEFAULT_SHELL "/bin/sh"
typedef
struct
_psqlSettings
{
PGconn
*
db
;
/* connection to backend */
int
echoQuery
;
/* if 1, echo the query before sending it */
int
quiet
;
/* run quietly, no messages, no promt */
int
singleStep
;
/* if 1, prompt for each query */
int
singleLineMode
;
/* if 1, query terminated by newline */
int
useReadline
;
/* use the readline routines or not */
int
printHeader
;
/* print output field headers or not */
int
fillAlign
;
/* fill align the fields */
FILE
*
queryFout
;
/* where to send the query results */
PQprintOpt
opt
;
/* options to be passed to PQprint */
char
*
prompt
;
/* prompt to display */
char
*
gfname
;
/* one-shot file output argument for \g */
bool
notty
;
/* input or output is not a tty */
bool
pipe
;
/* queryFout is from a popen() */
bool
echoQuery
;
/* echo the query before sending it */
bool
quiet
;
/* run quietly, no messages, no promt */
bool
singleStep
;
/* prompt before for each query */
bool
singleLineMode
;
/* query terminated by newline */
bool
useReadline
;
/* use libreadline routines */
char
fieldSep
[
MAX_FIELD_SEP_LENGTH
];
/* field separator */
}
PsqlSettings
;
/* declarations for functions in this file */
static
void
usage
(
char
*
progname
);
static
void
slashUsage
();
static
void
handleCopyOut
(
PGresult
*
res
,
bool
quiet
);
static
void
handleCopyIn
(
PGresult
*
res
,
bool
quiet
);
static
int
tableList
(
P
sqlSettings
*
ps
,
bool
deep_tablelist
);
static
int
tableDesc
(
P
sqlSettings
*
ps
,
char
*
table
);
static
void
handleCopyOut
(
PGresult
*
res
,
int
quiet
);
static
void
handleCopyIn
(
PGresult
*
res
,
int
quiet
);
static
int
tableList
(
P
Gconn
*
conn
,
int
deep_tablelist
);
static
int
tableDesc
(
P
Gconn
*
conn
,
char
*
table
);
char
*
gets_noreadline
(
char
*
prompt
,
FILE
*
source
);
char
*
gets_readline
(
char
*
prompt
,
FILE
*
source
);
char
*
gets_fromFile
(
char
*
prompt
,
FILE
*
source
);
int
listAllDbs
(
PsqlSettings
*
settings
);
int
SendQuery
(
P
sqlSettings
*
settings
,
char
*
query
);
int
HandleSlashCmds
(
P
sqlSettings
*
settings
,
int
listAllDbs
(
P
Gconn
*
db
,
P
sqlSettings
*
settings
);
int
SendQuery
(
P
Gconn
*
db
,
char
*
query
,
PsqlSettings
*
settings
);
int
HandleSlashCmds
(
P
Gconn
**
db_ptr
,
char
*
line
,
char
*
query
);
int
MainLoop
(
PsqlSettings
*
settings
,
FILE
*
source
);
/* probably should move this into libpq */
void
PQprint
(
FILE
*
fp
,
PGresult
*
res
,
PQprintOpt
*
po
);
char
**
prompt_ptr
,
char
*
query
,
PsqlSettings
*
settings
);
int
MainLoop
(
PGconn
**
db_ptr
,
FILE
*
source
,
PsqlSettings
*
settings
);
FILE
*
setFout
(
char
*
fname
);
FILE
*
setFout
(
PsqlSettings
*
ps
,
char
*
fname
);
/*
* usage
...
...
@@ -94,24 +89,22 @@ usage(char* progname)
{
fprintf
(
stderr
,
"Usage: %s [options] [dbname]
\n
"
,
progname
);
fprintf
(
stderr
,
"
\t
-a authsvc set authentication service
\n
"
);
fprintf
(
stderr
,
"
\t
-A turn off
alignment
when printing out attributes
\n
"
);
fprintf
(
stderr
,
"
\t
-A turn off
fill-justification
when printing out attributes
\n
"
);
fprintf
(
stderr
,
"
\t
-c query run single query (slash commands too)
\n
"
);
fprintf
(
stderr
,
"
\t
-d dbName specify database name
\n
"
);
fprintf
(
stderr
,
"
\t
-e echo the query sent to the backend
\n
"
);
fprintf
(
stderr
,
"
\t
-f filename use file as a source of queries
\n
"
);
fprintf
(
stderr
,
"
\t
-F sep set the field separator (default is "
")
\n
"
);
fprintf
(
stderr
,
"
\t
-h
host set database server host
\n
"
);
fprintf
(
stderr
,
"
\t
-H
turn on html3.0 table outpu
t
\n
"
);
fprintf
(
stderr
,
"
\t
-h
help information
\n
"
);
fprintf
(
stderr
,
"
\t
-H
host set database server hos
t
\n
"
);
fprintf
(
stderr
,
"
\t
-l list available databases
\n
"
);
fprintf
(
stderr
,
"
\t
-n don't use readline library
\n
"
);
fprintf
(
stderr
,
"
\t
-o filename send output to filename
or (|pipe)
\n
"
);
fprintf
(
stderr
,
"
\t
-o filename send output to filename
\n
"
);
fprintf
(
stderr
,
"
\t
-p port set port number
\n
"
);
fprintf
(
stderr
,
"
\t
-q run quietly (no messages, no prompts)
\n
"
);
fprintf
(
stderr
,
"
\t
-s single step mode (prompts for each query)
\n
"
);
fprintf
(
stderr
,
"
\t
-S single line mode (i.e. query terminated by newline)
\n
"
);
fprintf
(
stderr
,
"
\t
-t turn off printing of attribute headers
\n
"
);
fprintf
(
stderr
,
"
\t
-T html set html3.0 table command options (cf. -H)
\n
"
);
fprintf
(
stderr
,
"
\t
-x turn on expanded output (field names on left)"
);
fprintf
(
stderr
,
"
\t
-T turn off printing of attribute names
\n
"
);
exit
(
1
);
}
...
...
@@ -120,60 +113,29 @@ usage(char* progname)
* print out usage for the backslash commands
*/
char
*
on
(
bool
f
)
{
return
f
?
"on"
:
"off"
;
}
static
void
slashUsage
(
PsqlSettings
*
ps
)
slashUsage
()
{
fprintf
(
stderr
,
"
\t
\\
a -- toggle field-alignment (currenty %s)
\n
"
,
on
(
ps
->
opt
.
align
));
fprintf
(
stderr
,
"
\t
\\
c [<captn>] -- set html3 caption (currently '%s')
\n
"
,
ps
->
opt
.
caption
?
ps
->
opt
.
caption
:
""
);
fprintf
(
stderr
,
"
\t
\\
C <dbname> -- connect to new database (currently '%s')
\n
"
,
PQdb
(
ps
->
db
));
fprintf
(
stderr
,
"
\t
\\
a -- toggle fill-justification of display of attributes
\n
"
);
fprintf
(
stderr
,
"
\t
\\
d [<table>] -- list tables in database or columns in <table>
\n
"
);
fprintf
(
stderr
,
"
\t
\\
d * -- list tables in database and columns in all tables
\n
"
);
fprintf
(
stderr
,
"
\t
\\
e [<fname>] -- edit the current query buffer or <fname>
\n
"
);
fprintf
(
stderr
,
"
\t
\\
f [<sep>] -- change field separater (currently '%s')
\n
"
,
ps
->
opt
.
fieldSep
);
fprintf
(
stderr
,
"
\t
\\
g [<fname>] -- send query to backend [and place results in <fname>]
\n
"
);
fprintf
(
stderr
,
"
\t
\\
g |<cmd> -- send query to backend and pipe results into <cmd>
\n
"
);
fprintf
(
stderr
,
"
\t
\\
h [<cmd>] -- help on syntax of sql commands
\n
"
);
fprintf
(
stderr
,
"
\t
\\
f <sep> -- change field separator
\n
"
);
fprintf
(
stderr
,
"
\t
\\
g -- query to backend
\n
"
);
fprintf
(
stderr
,
"
\t
\\
h <command> -- help on syntax of sql commands
\n
"
);
fprintf
(
stderr
,
"
\t
\\
h * -- complete description of all sql commands
\n
"
);
fprintf
(
stderr
,
"
\t
\\
H -- toggle html3 output (currently %s)
\n
"
,
on
(
ps
->
opt
.
html3
)
);
fprintf
(
stderr
,
"
\t
\\
i <fname> -- read
and execute
queries from filename
\n
"
);
fprintf
(
stderr
,
"
\t
\\
g -- send query to backend
\n
"
);
fprintf
(
stderr
,
"
\t
\\
i <fname> -- read queries from filename
\n
"
);
fprintf
(
stderr
,
"
\t
\\
l -- list all databases
\n
"
);
fprintf
(
stderr
,
"
\t
\\
o [<fname>] -- send query results to <fname> or stdout
\n
"
);
fprintf
(
stderr
,
"
\t
\\
o |<cmd> -- pipe query results through <cmd>
\n
"
);
fprintf
(
stderr
,
"
\t
\\
o [<fname>] -- send query results file named <fname> or stdout
\n
"
);
fprintf
(
stderr
,
"
\t
\\
p -- print the current query buffer
\n
"
);
fprintf
(
stderr
,
"
\t
\\
q -- quit
\n
"
);
fprintf
(
stderr
,
"
\t
\\
r [<fname>] -- edit <fname> then send contents to backend
\n
"
);
fprintf
(
stderr
,
"
\t
\\
s [<fname>] -- print history or save it in <fname>
\n
"
);
fprintf
(
stderr
,
"
\t
\\
S -- toggle standard sql type-setting (currently %s)
\n
"
,
on
(
ps
->
opt
.
standard
));
fprintf
(
stderr
,
"
\t
\\
t -- toggle table output header (currently %s)
\n
"
,
on
(
ps
->
opt
.
header
));
fprintf
(
stderr
,
"
\t
\\
T [<html>] -- set html3.0 <table ...> options (currently '%s')
\n
"
,
ps
->
opt
.
tableOpt
?
ps
->
opt
.
tableOpt
:
""
);
fprintf
(
stderr
,
"
\t
\\
x -- toggle expanded output (currently %s)
\n
"
,
on
(
ps
->
opt
.
expanded
));
fprintf
(
stderr
,
"
\t
\\
z -- zorch current query buffer (i.e clear it)
\n
"
);
fprintf
(
stderr
,
"
\t
\\
! [<cmd>] -- shell escape or command
\n
"
);
fprintf
(
stderr
,
"
\t
\\
s [<fname>] -- save or print history
\n
"
);
fprintf
(
stderr
,
"
\t
\\
t -- toggle output field headers (defaults to on)
\n
"
);
fprintf
(
stderr
,
"
\t
\\
! [<cmd>] -- shell escape
\n
"
);
fprintf
(
stderr
,
"
\t
\\
? -- help
\n
"
);
}
PGresult
*
PSQLexec
(
PsqlSettings
*
ps
,
char
*
query
)
{
PGresult
*
res
=
PQexec
(
ps
->
db
,
query
);
if
(
!
res
)
fputs
(
PQerrorMessage
(
ps
->
db
),
stderr
);
else
{
if
(
PQresultStatus
(
res
)
==
PGRES_COMMAND_OK
||
PQresultStatus
(
res
)
==
PGRES_TUPLES_OK
)
return
res
;
if
(
!
ps
->
quiet
)
fputs
(
PQerrorMessage
(
ps
->
db
),
stderr
);
PQclear
(
res
);
}
return
NULL
;
}
/*
* listAllDbs
*
...
...
@@ -182,37 +144,50 @@ PSQLexec(PsqlSettings *ps, char *query)
*
*
*/
int
listAllDbs
(
P
sqlSettings
*
p
s
)
listAllDbs
(
P
Gconn
*
db
,
PsqlSettings
*
setting
s
)
{
PGresult
*
results
;
char
*
query
=
"select * from pg_database;"
;
if
(
!
(
results
=
PSQLexec
(
ps
,
query
)))
results
=
PQexec
(
db
,
query
);
if
(
results
==
NULL
)
{
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
db
));
return
1
;
}
if
(
PQresultStatus
(
results
)
!=
PGRES_TUPLES_OK
)
{
fprintf
(
stderr
,
"Unexpected error from executing: %s
\n
"
,
query
);
return
2
;
}
else
{
PQprint
(
ps
->
queryFout
,
results
,
&
ps
->
opt
);
PQdisplayTuples
(
results
,
settings
->
queryFout
,
settings
->
fillAlign
,
settings
->
fieldSep
,
settings
->
printHeader
,
settings
->
quiet
);
PQclear
(
results
);
return
0
;
}
}
/*
* tableList (PGconn* conn)
*
* List The Database Tables
* returns 0 if all went well
*
*/
int
tableList
(
P
sqlSettings
*
ps
,
bool
deep_tablelist
)
tableList
(
P
Gconn
*
conn
,
int
deep_tablelist
)
{
char
listbuf
[
256
];
int
nColumns
;
int
i
;
char
*
ru
;
char
*
rk
;
char
*
rr
;
...
...
@@ -228,8 +203,17 @@ tableList (PsqlSettings *ps, bool deep_tablelist)
add in the int4oideq function */
strcat
(
listbuf
,
" and usesysid = relowner"
);
strcat
(
listbuf
,
" ORDER BY relname "
);
if
(
!
(
res
=
PSQLexec
(
ps
,
listbuf
)))
return
-
1
;
res
=
PQexec
(
conn
,
listbuf
);
if
(
res
==
NULL
)
{
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
conn
));
return
(
-
1
);
}
if
((
PQresultStatus
(
res
)
!=
PGRES_TUPLES_OK
)
||
(
PQntuples
(
res
)
<=
0
))
{
fprintf
(
stderr
,
"No tables found in database %s.
\n
"
,
PQdb
(
conn
));
PQclear
(
res
);
return
(
-
1
);
}
/* first, print out the attribute names */
nColumns
=
PQntuples
(
res
);
...
...
@@ -252,14 +236,14 @@ tableList (PsqlSettings *ps, bool deep_tablelist)
PQclear
(
res
);
for
(
i
=
0
;
i
<
nColumns
;
i
++
)
{
tableDesc
(
ps
,
table
[
i
]);
tableDesc
(
conn
,
table
[
i
]);
}
free
(
table
);
}
else
{
/* Display the information */
printf
(
"
\n
Database = %s
\n
"
,
PQdb
(
ps
->
db
));
printf
(
"
\n
Database = %s
\n
"
,
PQdb
(
conn
));
printf
(
" +------------------+----------------------------------+----------+
\n
"
);
printf
(
" | Owner | Relation | Type |
\n
"
);
printf
(
" +------------------+----------------------------------+----------+
\n
"
);
...
...
@@ -288,7 +272,7 @@ tableList (PsqlSettings *ps, bool deep_tablelist)
}
/*
* Describe a table
* Describe a table
(PGconn* conn, char* table)
*
* Describe the columns in a database table.
* returns 0 if all went well
...
...
@@ -296,7 +280,7 @@ tableList (PsqlSettings *ps, bool deep_tablelist)
*
*/
int
tableDesc
(
P
sqlSettings
*
ps
,
char
*
table
)
tableDesc
(
P
Gconn
*
conn
,
char
*
table
)
{
char
descbuf
[
256
];
int
nColumns
;
...
...
@@ -318,8 +302,16 @@ tableDesc (PsqlSettings *ps, char *table)
strcat
(
descbuf
,
" and a.attrelid = c.oid "
);
strcat
(
descbuf
,
" and a.atttypid = t.oid "
);
strcat
(
descbuf
,
" ORDER BY attnum "
);
if
(
!
(
res
=
PSQLexec
(
ps
,
descbuf
)))
return
-
1
;
res
=
PQexec
(
conn
,
descbuf
);
if
(
res
==
NULL
)
{
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
conn
));
return
(
-
1
);
}
if
((
PQresultStatus
(
res
)
!=
PGRES_TUPLES_OK
)
||
(
PQntuples
(
res
)
<=
0
))
{
fprintf
(
stderr
,
"Couldn't find table %s!
\n
"
,
table
);
PQclear
(
res
);
return
(
-
1
);
}
/* first, print out the attribute names */
nColumns
=
PQntuples
(
res
);
if
(
nColumns
>
0
)
...
...
@@ -329,9 +321,9 @@ tableDesc (PsqlSettings *ps, char *table)
*/
printf
(
"
\n
Table = %s
\n
"
,
table
);
printf
(
"+----------------------------------+----------------------------------+-------
-
+
\n
"
);
printf
(
"| Field | Type | Length
|
\n
"
);
printf
(
"+----------------------------------+----------------------------------+-------
-
+
\n
"
);
printf
(
"+----------------------------------+----------------------------------+-------+
\n
"
);
printf
(
"| Field | Type | Length|
\n
"
);
printf
(
"+----------------------------------+----------------------------------+-------+
\n
"
);
/* next, print out the instances */
for
(
i
=
0
;
i
<
PQntuples
(
res
);
i
++
)
{
...
...
@@ -340,15 +332,15 @@ tableDesc (PsqlSettings *ps, char *table)
rsize
=
atoi
(
PQgetvalue
(
res
,
i
,
3
));
if
(
strcmp
(
rtype
,
"text"
)
==
0
)
{
printf
(
"%-32.32s |"
,
rtype
);
printf
(
"%6s |"
,
"var"
);
printf
(
"%
-
6s |"
,
"var"
);
}
else
if
(
strcmp
(
rtype
,
"bpchar"
)
==
0
)
{
printf
(
"%-32.32s |"
,
"char"
);
printf
(
"%6i |"
,
rsize
>
0
?
rsize
-
4
:
0
);
printf
(
"%
-
6i |"
,
rsize
>
0
?
rsize
-
4
:
0
);
}
else
if
(
strcmp
(
rtype
,
"varchar"
)
==
0
)
{
printf
(
"%-32.32s |"
,
rtype
);
printf
(
"%6i |"
,
rsize
>
0
?
rsize
-
4
:
0
);
printf
(
"%
-
6i |"
,
rsize
>
0
?
rsize
-
4
:
0
);
}
else
{
/* array types start with an underscore */
...
...
@@ -363,13 +355,13 @@ tableDesc (PsqlSettings *ps, char *table)
free
(
newname
);
}
if
(
rsize
>
0
)
printf
(
"
%
6i |"
,
rsize
);
printf
(
"
%-
6i |"
,
rsize
);
else
printf
(
"
%
6s |"
,
"var"
);
printf
(
"
%-
6s |"
,
"var"
);
}
printf
(
"
\n
"
);
}
printf
(
"+----------------------------------+----------------------------------+-------
-
+
\n
"
);
printf
(
"+----------------------------------+----------------------------------+-------+
\n
"
);
PQclear
(
res
);
return
(
0
);
...
...
@@ -404,6 +396,7 @@ gets_readline(char* prompt, FILE* source)
return
(
readline
(
prompt
));
}
/*
* gets_fromFile prompt source
*
...
...
@@ -433,12 +426,14 @@ gets_fromFile(char* prompt, FILE* source)
}
/*
* SendQuery: send the query string to the backend
* SendQuery:
SendQuery: send the query string to the backend
*
* return 0 if the query executed successfully
* returns 1 otherwise
*/
int
SendQuery
(
P
sqlSettings
*
settings
,
char
*
query
)
SendQuery
(
P
Gconn
*
db
,
char
*
query
,
PsqlSettings
*
settings
)
{
PGresult
*
results
;
PGnotify
*
notify
;
...
...
@@ -459,41 +454,20 @@ SendQuery(PsqlSettings *settings, char *query)
gets_fromFile
(
""
,
stdin
);
}
results
=
PQexec
(
settings
->
db
,
query
);
results
=
PQexec
(
db
,
query
);
if
(
results
==
NULL
)
{
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
settings
->
db
));
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
db
));
return
1
;
}
switch
(
PQresultStatus
(
results
))
{
case
PGRES_TUPLES_OK
:
if
(
settings
->
gfname
)
{
PsqlSettings
ps
=*
settings
;
FILE
*
fp
;
ps
.
queryFout
=
stdout
;
fp
=
setFout
(
&
ps
,
settings
->
gfname
);
if
(
!
fp
||
fp
==
stdout
)
{
status
=
1
;
break
;
}
PQprint
(
fp
,
results
,
&
(
settings
->
opt
));
if
(
ps
.
pipe
)
pclose
(
fp
);
else
fclose
(
fp
);
settings
->
gfname
=
NULL
;
break
;
}
else
{
PQprint
(
settings
->
queryFout
,
results
,
&
(
settings
->
opt
));
fflush
(
settings
->
queryFout
);
}
PQdisplayTuples
(
results
,
settings
->
queryFout
,
settings
->
fillAlign
,
settings
->
fieldSep
,
settings
->
printHeader
,
settings
->
quiet
);
PQclear
(
results
);
break
;
case
PGRES_EMPTY_QUERY
:
...
...
@@ -501,7 +475,7 @@ SendQuery(PsqlSettings *settings, char *query)
break
;
case
PGRES_COMMAND_OK
:
if
(
!
settings
->
quiet
)
fprintf
(
stdout
,
"%s
\n
"
,
PQcmdStatus
(
results
));
fprintf
(
stdout
,
"%s
\n
"
,
PQcmdStatus
(
results
));
break
;
case
PGRES_COPY_OUT
:
handleCopyOut
(
results
,
settings
->
quiet
);
...
...
@@ -513,12 +487,13 @@ SendQuery(PsqlSettings *settings, char *query)
case
PGRES_FATAL_ERROR
:
case
PGRES_BAD_RESPONSE
:
status
=
1
;
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
settings
->
db
));
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
db
));
break
;
}
/* check for asynchronous returns */
notify
=
PQnotifies
(
settings
->
db
);
notify
=
PQnotifies
(
db
);
if
(
notify
)
{
fprintf
(
stderr
,
"ASYNC NOTIFY of '%s' from backend pid '%d' received
\n
"
,
notify
->
relname
,
notify
->
be_pid
);
...
...
@@ -529,71 +504,6 @@ SendQuery(PsqlSettings *settings, char *query)
}
void
editFile
(
char
*
fname
)
{
char
*
editorName
;
char
*
sys
;
editorName
=
getenv
(
"EDITOR"
);
if
(
!
editorName
)
editorName
=
DEFAULT_EDITOR
;
sys
=
malloc
(
strlen
(
editorName
)
+
strlen
(
fname
)
+
32
+
1
);
if
(
!
sys
)
{
perror
(
"malloc"
);
exit
(
1
);
}
sprintf
(
sys
,
"exec '%s' '%s'"
,
editorName
,
fname
);
system
(
sys
);
free
(
sys
);
}
bool
toggle
(
PsqlSettings
*
settings
,
bool
*
sw
,
char
*
msg
)
{
*
sw
=
!*
sw
;
if
(
!
settings
->
quiet
)
fprintf
(
stderr
,
"turned %s %s
\n
"
,
on
(
*
sw
),
msg
);
return
*
sw
;
}
char
*
decode
(
char
*
s
)
{
char
*
p
,
*
d
;
bool
esc
=
0
;
for
(
d
=
p
=
s
;
*
p
;
p
++
)
{
char
c
=*
p
;
if
(
esc
)
{
switch
(
*
p
)
{
case
'n'
:
c
=
'\n'
;
break
;
case
'r'
:
c
=
'\r'
;
break
;
case
't'
:
c
=
'\t'
;
break
;
case
'f'
:
c
=
'\f'
;
break
;
}
esc
=
0
;
}
else
if
(
c
==
'\\'
)
{
esc
=
1
;
continue
;
}
*
d
++=
c
;
}
*
d
=
'\0'
;
}
/*
HandleSlashCmds:
...
...
@@ -609,161 +519,189 @@ decode(char *s)
2 - terminate processing of this query entirely
*/
int
HandleSlashCmds
(
P
sqlSettings
*
settings
,
HandleSlashCmds
(
P
Gconn
**
db_ptr
,
char
*
line
,
char
*
query
)
char
**
prompt_ptr
,
char
*
query
,
PsqlSettings
*
settings
)
{
int
status
=
1
;
int
status
=
0
;
PGconn
*
db
=
*
db_ptr
;
char
*
dbname
=
PQdb
(
db
);
char
*
optarg
=
NULL
;
int
len
;
len
=
strlen
(
line
);
if
(
len
>
2
)
{
optarg
=
leftTrim
(
line
+
2
);
decode
(
optarg
);
}
switch
(
line
[
1
])
{
case
'a'
:
/* toggles to align fields on output */
toggle
(
settings
,
&
settings
->
opt
.
align
,
"field alignment"
);
break
;
case
'c'
:
/* define new caption */
if
(
settings
->
opt
.
caption
)
free
(
settings
->
opt
.
caption
);
if
(
!
optarg
)
settings
->
opt
.
caption
=
NULL
;
case
'a'
:
/* toggles to fill fields on output */
if
(
settings
->
fillAlign
)
settings
->
fillAlign
=
0
;
else
if
(
!
(
settings
->
opt
.
caption
=
dupstr
(
optarg
)))
{
perror
(
"malloc"
);
exit
(
1
);
}
settings
->
fillAlign
=
1
;
if
(
!
settings
->
quiet
)
fprintf
(
stderr
,
"turning %s fill-justification
\n
"
,
(
settings
->
fillAlign
)
?
"on"
:
"off"
);
break
;
case
'
C'
:
/* \C
means connect to new database */
case
'
c'
:
/* \c
means connect to new database */
{
char
*
dbname
=
PQdb
(
settings
->
db
);
if
(
!
optarg
)
{
fprintf
(
stderr
,
"
\\
c must be followed by a database name
\n
"
);
status
=
1
;
break
;
}
{
PGconn
*
olddb
=
settings
->
db
;
if
(
strcmp
(
optarg
,
dbname
)
==
0
)
{
fprintf
(
stderr
,
"already connected to %s
\n
"
,
dbname
);
status
=
1
;
break
;
}
else
{
PGconn
*
olddb
;
printf
(
"closing connection to database: %s
\n
"
,
dbname
);
settings
->
db
=
PQsetdb
(
PQhost
(
olddb
),
PQport
(
olddb
),
NULL
,
NULL
,
optarg
);
printf
(
"closing connection to database:%s
\n
"
,
dbname
);
olddb
=
db
;
db
=
PQsetdb
(
PQhost
(
olddb
),
PQport
(
olddb
),
NULL
,
NULL
,
optarg
);
*
db_ptr
=
db
;
printf
(
"connecting to new database: %s
\n
"
,
optarg
);
if
(
PQstatus
(
settings
->
db
)
==
CONNECTION_BAD
)
{
fprintf
(
stderr
,
"%s
\n
"
,
PQerrorMessage
(
settings
->
db
));
if
(
PQstatus
(
db
)
==
CONNECTION_BAD
)
{
fprintf
(
stderr
,
"%s
\n
"
,
PQerrorMessage
(
db
));
printf
(
"reconnecting to %s
\n
"
,
dbname
);
settings
->
db
=
PQsetdb
(
PQhost
(
olddb
),
PQport
(
olddb
),
db
=
PQsetdb
(
PQhost
(
olddb
),
PQport
(
olddb
),
NULL
,
NULL
,
dbname
);
if
(
PQstatus
(
settings
->
db
)
==
CONNECTION_BAD
)
{
*
db_ptr
=
db
;
if
(
PQstatus
(
db
)
==
CONNECTION_BAD
)
{
fprintf
(
stderr
,
"could not reconnect to %s. exiting
\n
"
,
dbname
);
exit
(
2
);
}
status
=
1
;
break
;
}
PQfinish
(
olddb
);
free
(
settings
->
prompt
);
settings
->
prompt
=
malloc
(
strlen
(
PQdb
(
settings
->
db
))
+
10
);
sprintf
(
settings
->
prompt
,
"%s=> "
,
PQdb
(
settings
->
db
));
free
(
*
prompt_ptr
);
*
prompt_ptr
=
malloc
(
strlen
(
optarg
)
+
10
);
sprintf
(
*
prompt_ptr
,
"%s=> "
,
optarg
);
status
=
1
;
break
;
}
}
break
;
case
'd'
:
/* \d describe tables or columns in a table */
{
if
(
!
optarg
)
{
tableList
(
settings
,
0
);
tableList
(
db
,
0
);
status
=
1
;
break
;
}
if
(
strcmp
(
optarg
,
"*"
)
==
0
)
{
tableList
(
settings
,
0
);
tableList
(
settings
,
1
);
if
(
strcmp
(
optarg
,
"*"
)
==
0
)
{
tableList
(
db
,
0
);
tableList
(
db
,
1
);
}
else
{
tableDesc
(
settings
,
optarg
);
tableDesc
(
db
,
optarg
);
}
status
=
1
;
break
;
}
case
'e'
:
{
char
s
[
256
];
int
fd
;
char
tmp
[
64
];
char
*
fname
;
int
cc
;
int
ql
=
strlen
(
query
);
int
f_arg
=
0
;
int
cc
;
if
(
optarg
)
fname
=
optarg
;
{
f_arg
=
1
;
strcpy
(
s
,
optarg
);
}
else
{
sprintf
(
tmp
,
"/tmp/psql.%d.%d"
,
getuid
(),
getpid
());
fname
=
tmp
;
unlink
(
tmp
);
sprintf
(
s
,
"/tmp/psql.%d.%d"
,
geteuid
(),
getpid
());
unlink
(
s
);
if
(
ql
)
{
if
((
fd
=
open
(
tmp
,
O_EXCL
|
O_CREAT
|
O_WRONLY
,
0600
))
==-
1
)
if
((
fd
=
open
(
s
,
O_EXCL
|
O_CREAT
|
O_WRONLY
,
0600
))
==-
1
)
{
perror
(
tmp
);
perror
(
s
);
break
;
}
if
(
query
[
ql
-
1
]
!=
'\n'
)
strcat
(
query
,
"
\n
"
);
if
(
write
(
fd
,
query
,
ql
)
!=
ql
)
{
perror
(
tmp
);
perror
(
s
);
close
(
fd
);
unlink
(
tmp
);
unlink
(
s
);
break
;
}
close
(
fd
);
}
}
editFile
(
fname
);
if
((
fd
=
open
(
fname
,
O_RDONLY
))
==-
1
)
{
perror
(
fname
);
if
(
!
optarg
)
unlink
(
fname
);
char
sys
[
256
];
char
*
editorName
;
editorName
=
getenv
(
"EDITOR"
);
if
(
editorName
==
NULL
)
editorName
=
DEFAULT_EDITOR
;
sprintf
(
sys
,
"exec %s %s"
,
editorName
,
s
);
system
(
sys
);
}
if
((
fd
=
open
(
s
,
O_RDONLY
))
==-
1
)
{
if
(
!
f_arg
)
unlink
(
s
);
break
;
}
if
((
cc
=
read
(
fd
,
query
,
MAX_QUERY_BUFFER
))
==-
1
)
{
perror
(
fname
);
perror
(
s
);
close
(
fd
);
if
(
!
opt
arg
)
unlink
(
fname
);
if
(
!
f_
arg
)
unlink
(
s
);
break
;
}
query
[
cc
]
=
'\0'
;
close
(
fd
);
if
(
!
opt
arg
)
unlink
(
fname
);
if
(
!
f_
arg
)
unlink
(
s
);
rightTrim
(
query
);
if
(
query
[
strlen
(
query
)
-
1
]
==
';'
)
return
0
;
break
;
}
case
'f'
:
{
char
*
fs
=
DEFAULT_FIELD_SEP
;
if
(
optarg
)
fs
=
optarg
;
if
(
settings
->
opt
.
fieldSep
);
free
(
settings
->
opt
.
fieldSep
);
if
(
!
(
settings
->
opt
.
fieldSep
=
dupstr
(
fs
)))
strcpy
(
settings
->
fieldSep
,
optarg
);
else
strcpy
(
settings
->
fieldSep
,
DEFAULT_FIELD_SEP
);
break
;
case
'g'
:
/* \g means send query */
status
=
0
;
break
;
case
'i'
:
/* \i is include file */
{
perror
(
"malloc"
);
exit
(
1
);
FILE
*
fd
;
if
(
!
optarg
)
{
fprintf
(
stderr
,
"
\\
i must be followed by a file name
\n
"
);
status
=
1
;
break
;
}
if
(
!
settings
->
quiet
)
fprintf
(
stderr
,
"field separater changed to '%s'
\n
"
,
settings
->
opt
.
fieldSep
);
if
(
(
fd
=
fopen
(
optarg
,
"r"
))
==
NULL
)
{
fprintf
(
stderr
,
"file named %s could not be opened
\n
"
,
optarg
);
status
=
1
;
break
;
}
case
'g'
:
/* \g means send query */
settings
->
gfname
=
optarg
;
status
=
0
;
MainLoop
(
&
db
,
fd
,
settings
);
fclose
(
fd
)
;
status
=
1
;
break
;
}
case
'h'
:
{
char
*
cmd
;
...
...
@@ -789,7 +727,7 @@ HandleSlashCmds(PsqlSettings *settings,
numCmds
=
numCmds
-
1
;
if
(
strcmp
(
cmd
,
"*"
)
==
0
)
{
if
(
strcmp
(
cmd
,
"*"
)
==
0
)
{
all_help
=
1
;
}
...
...
@@ -810,143 +748,74 @@ HandleSlashCmds(PsqlSettings *settings,
if
(
i
==
numCmds
&&
!
all_help
)
printf
(
"command not found, try
\\
h with no arguments to see available help
\n
"
);
}
break
;
}
case
'i'
:
/* \i is include file */
{
FILE
*
fd
;
if
(
!
optarg
)
{
fprintf
(
stderr
,
"
\\
i must be followed by a file name
\n
"
);
break
;
}
if
((
fd
=
fopen
(
optarg
,
"r"
))
==
NULL
)
{
fprintf
(
stderr
,
"file named %s could not be opened
\n
"
,
optarg
);
break
;
}
MainLoop
(
settings
,
fd
);
fclose
(
fd
);
status
=
1
;
break
;
}
case
'l'
:
/* \l is list database */
listAllDbs
(
settings
);
break
;
case
'H'
:
if
(
toggle
(
settings
,
&
settings
->
opt
.
html3
,
"HTML3.0 tablular output"
))
settings
->
opt
.
standard
=
0
;
listAllDbs
(
db
,
settings
);
status
=
1
;
break
;
case
'o'
:
set
Fout
(
settings
,
optarg
);
set
tings
->
queryFout
=
setFout
(
optarg
);
break
;
case
'p'
:
if
(
query
)
{
fputs
(
query
,
stdout
);
fputc
(
'\n'
,
stdout
);
status
=
1
;
}
break
;
case
'q'
:
/* \q is quit */
status
=
2
;
break
;
case
'r'
:
{
FILE
*
fd
;
static
char
*
lastfile
;
struct
stat
st
,
st2
;
if
(
optarg
)
{
if
(
lastfile
)
free
(
lastfile
);
lastfile
=
malloc
(
strlen
(
optarg
+
1
));
if
(
!
lastfile
)
{
perror
(
"malloc"
);
exit
(
1
);
}
strcpy
(
lastfile
,
optarg
);
}
else
if
(
!
lastfile
)
{
fprintf
(
stderr
,
"
\\
r must be followed by a file name initially
\n
"
);
break
;
}
stat
(
lastfile
,
&
st
);
editFile
(
lastfile
);
if
((
stat
(
lastfile
,
&
st2
)
==
-
1
)
||
((
fd
=
fopen
(
lastfile
,
"r"
))
==
NULL
))
{
perror
(
lastfile
);
query
[
0
]
=
'\0'
;
status
=
1
;
break
;
}
if
(
st2
.
st_mtime
==
st
.
st_mtime
)
{
if
(
!
settings
->
quiet
)
fprintf
(
stderr
,
"warning: %s not modified. query not executed
\n
"
,
lastfile
);
fclose
(
fd
);
case
's'
:
/* \s is save history to a file */
{
char
*
fname
;
if
(
!
optarg
)
{
fprintf
(
stderr
,
"
\\
s must be followed by a file name
\n
"
);
status
=
1
;
break
;
}
MainLoop
(
settings
,
fd
);
fclose
(
fd
);
break
;
fname
=
optarg
;
if
(
write_history
(
fname
)
!=
0
)
{
fprintf
(
stderr
,
"cannot write history to %s
\n
"
,
fname
);
}
case
's'
:
/* \s is save history to a file */
if
(
!
optarg
)
optarg
=
"/dev/tty"
;
if
(
write_history
(
optarg
)
!=
0
)
fprintf
(
stderr
,
"cannot write history to %s
\n
"
,
optarg
);
status
=
1
;
break
;
case
'S'
:
/* standard SQL output */
if
(
toggle
(
settings
,
&
settings
->
opt
.
standard
,
"standard SQL separaters and padding"
))
{
settings
->
opt
.
html3
=
settings
->
opt
.
expanded
=
0
;
settings
->
opt
.
align
=
settings
->
opt
.
header
=
1
;
free
(
settings
->
opt
.
fieldSep
);
settings
->
opt
.
fieldSep
=
dupstr
(
"|"
);
if
(
!
settings
->
quiet
)
fprintf
(
stderr
,
"field separater changed to '%s'
\n
"
,
settings
->
opt
.
fieldSep
);
}
else
{
free
(
settings
->
opt
.
fieldSep
);
settings
->
opt
.
fieldSep
=
dupstr
(
DEFAULT_FIELD_SEP
);
if
(
!
settings
->
quiet
)
fprintf
(
stderr
,
"field separater changed to '%s'
\n
"
,
settings
->
opt
.
fieldSep
);
}
break
;
case
't'
:
/* toggle headers */
toggle
(
settings
,
&
settings
->
opt
.
header
,
"output headers"
);
break
;
case
'T'
:
/* define html <table ...> option */
if
(
settings
->
opt
.
tableOpt
)
free
(
settings
->
opt
.
tableOpt
);
if
(
!
optarg
)
settings
->
opt
.
tableOpt
=
NULL
;
case
't'
:
if
(
settings
->
printHeader
)
settings
->
printHeader
=
0
;
else
if
(
!
(
settings
->
opt
.
tableOpt
=
dupstr
(
optarg
)))
{
perror
(
"malloc"
);
exit
(
1
);
}
break
;
case
'x'
:
toggle
(
settings
,
&
settings
->
opt
.
expanded
,
"expanded table representation"
);
break
;
case
'z'
:
/* zorch buffer */
query
[
0
]
=
'\0'
;
if
(
!
settings
->
quiet
)
fprintf
(
stderr
,
"zorched current query buffer
\n
"
);
settings
->
printHeader
=
1
;
if
(
!
settings
->
quiet
)
fprintf
(
stderr
,
"turning %s printing of field headers
\n
"
,
(
settings
->
printHeader
)
?
"on"
:
"off"
);
break
;
case
'!'
:
if
(
!
optarg
)
{
char
*
sys
;
char
sys
[
256
]
;
char
*
shellName
;
shellName
=
getenv
(
"SHELL"
);
if
(
shellName
==
NULL
)
shellName
=
DEFAULT_SHELL
;
sys
=
malloc
(
strlen
(
shellName
)
+
16
);
if
(
!
sys
)
{
perror
(
"malloc"
);
exit
(
1
);
}
if
(
shellName
==
NULL
)
shellName
=
DEFAULT_SHELL
;
sprintf
(
sys
,
"exec %s"
,
shellName
);
system
(
sys
);
free
(
sys
);
}
else
system
(
optarg
);
}
else
system
(
optarg
);
break
;
default:
case
'?'
:
/* \? is help */
slashUsage
(
settings
);
slashUsage
();
status
=
1
;
break
;
}
return
status
;
...
...
@@ -961,14 +830,19 @@ HandleSlashCmds(PsqlSettings *settings,
*db_ptr must be initialized and set
*/
int
MainLoop
(
PsqlSettings
*
settings
,
FILE
*
source
)
MainLoop
(
PGconn
**
db_ptr
,
FILE
*
source
,
PsqlSettings
*
settings
)
{
char
*
prompt
;
/* readline prompt */
char
*
line
;
/* line of input*/
int
len
;
/* length of the line */
char
query
[
MAX_QUERY_BUFFER
];
/* multi-line query storage */
PGconn
*
db
=
*
db_ptr
;
char
*
dbname
=
PQdb
(
db
);
int
exitStatus
=
0
;
int
slashCmdStatus
=
0
;
/* slashCmdStatus can be:
0 - send currently constructed query to backend (i.e. we got a \g)
...
...
@@ -976,21 +850,18 @@ MainLoop(PsqlSettings *settings, FILE* source)
2 - terminate processing of this query entirely
*/
bool
sendQuery
=
0
;
bool
querySent
=
0
;
bool
interactive
;
int
send_query
=
0
;
int
interactive
;
READ_ROUTINE
GetNextLine
;
interactive
=
(
(
source
==
stdin
)
&&
!
settings
->
notty
);
#define PROMPT "=> "
interactive
=
(
source
==
stdin
);
if
(
interactive
)
{
if
(
settings
->
prompt
)
free
(
settings
->
prompt
);
settings
->
prompt
=
malloc
(
strlen
(
PQdb
(
settings
->
db
))
+
strlen
(
PROMPT
)
+
1
);
prompt
=
malloc
(
strlen
(
dbname
)
+
10
);
if
(
settings
->
quiet
)
settings
->
prompt
[
0
]
=
'\0'
;
prompt
[
0
]
=
'\0'
;
else
sprintf
(
settings
->
prompt
,
"%s%s"
,
PQdb
(
settings
->
db
),
PROMPT
);
sprintf
(
prompt
,
"%s=> "
,
dbname
);
if
(
settings
->
useReadline
)
{
using_history
();
GetNextLine
=
gets_readline
;
...
...
@@ -1004,7 +875,7 @@ MainLoop(PsqlSettings *settings, FILE* source)
query
[
0
]
=
'\0'
;
/* main loop for getting queries and executing them */
while
((
line
=
GetNextLine
(
settings
->
prompt
,
source
))
!=
NULL
)
while
((
line
=
GetNextLine
(
prompt
,
source
))
!=
NULL
)
{
exitStatus
=
0
;
line
=
rightTrim
(
line
);
/* remove whitespaces on the right, incl. \n's */
...
...
@@ -1024,11 +895,6 @@ MainLoop(PsqlSettings *settings, FILE* source)
free
(
line
);
continue
;
}
if
(
line
[
0
]
!=
'\\'
&&
querySent
)
{
query
[
0
]
=
'\0'
;
querySent
=
0
;
}
len
=
strlen
(
line
);
...
...
@@ -1037,31 +903,34 @@ MainLoop(PsqlSettings *settings, FILE* source)
/* do the query immediately if we are doing single line queries
or if the last character is a semicolon */
send
Q
uery
=
settings
->
singleLineMode
||
(
line
[
len
-
1
]
==
';'
)
;
send
_q
uery
=
settings
->
singleLineMode
||
(
line
[
len
-
1
]
==
';'
)
;
/* normally, \ commands have to be start the line,
but for backwards compatibility with monitor,
check for \g at the end of line */
if
(
len
>
2
&&
!
send
Q
uery
)
if
(
len
>
2
&&
!
send
_q
uery
)
{
if
(
line
[
len
-
1
]
==
'g'
&&
line
[
len
-
2
]
==
'\\'
)
{
send
Q
uery
=
1
;
send
_q
uery
=
1
;
line
[
len
-
2
]
=
'\0'
;
}
}
/* slash commands have to be on their own line */
if
(
line
[
0
]
==
'\\'
)
{
slashCmdStatus
=
HandleSlashCmds
(
settings
,
slashCmdStatus
=
HandleSlashCmds
(
db_ptr
,
line
,
query
);
&
prompt
,
query
,
settings
);
db
=
*
db_ptr
;
/* in case \c changed the database */
if
(
slashCmdStatus
==
1
)
continue
;
if
(
slashCmdStatus
==
2
)
break
;
if
(
slashCmdStatus
==
0
)
send
Q
uery
=
1
;
send
_q
uery
=
1
;
}
else
if
(
strlen
(
query
)
+
len
>
MAX_QUERY_BUFFER
)
...
...
@@ -1077,16 +946,16 @@ MainLoop(PsqlSettings *settings, FILE* source)
else
strcpy
(
query
,
line
);
if
(
send
Q
uery
&&
query
[
0
]
!=
'\0'
)
if
(
send
_q
uery
&&
query
[
0
]
!=
'\0'
)
{
/* echo the line read from the file,
unless we are in single_step mode, because single_step mode
will echo anyway */
if
(
!
interactive
&&
!
settings
->
singleStep
&&
!
settings
->
quiet
)
fprintf
(
stderr
,
"%s
\n
"
,
query
);
if
(
!
interactive
&&
!
settings
->
singleStep
)
fprintf
(
stderr
,
"%s
\n
"
,
query
);
exitStatus
=
SendQuery
(
settings
,
query
);
querySent
=
1
;
exitStatus
=
SendQuery
(
db
,
query
,
settings
);
query
[
0
]
=
'\0'
;
}
free
(
line
);
/* free storage malloc'd by GetNextLine */
...
...
@@ -1098,8 +967,9 @@ int
main
(
int
argc
,
char
**
argv
)
{
extern
char
*
optarg
;
extern
int
optind
;
extern
int
optind
,
opterr
;
PGconn
*
db
;
char
*
dbname
=
NULL
;
char
*
host
=
NULL
;
char
*
port
=
NULL
;
...
...
@@ -1110,27 +980,31 @@ main(int argc, char** argv)
char
*
singleQuery
=
NULL
;
bool
listDatabases
=
0
;
int
listDatabases
=
0
;
int
exitStatus
=
0
;
bool
singleSlashCmd
=
0
;
int
singleSlashCmd
=
0
;
int
c
;
memset
(
&
settings
,
0
,
sizeof
settings
);
settings
.
opt
.
align
=
1
;
settings
.
opt
.
header
=
1
;
settings
.
queryFout
=
stdout
;
settings
.
opt
.
fieldSep
=
dupstr
(
DEFAULT_FIELD_SEP
);
if
(
!
isatty
(
0
)
||
!
isatty
(
1
))
settings
.
quiet
=
settings
.
notty
=
1
;
else
#ifndef NOREADLINE
#ifdef NOREADLINE
settings
.
useReadline
=
0
;
#else
settings
.
useReadline
=
1
;
#endif
while
((
c
=
getopt
(
argc
,
argv
,
"Aa:c:d:ef:F:lhH:nso:p:qStTx"
))
!=
EOF
)
{
settings
.
quiet
=
0
;
settings
.
fillAlign
=
1
;
settings
.
printHeader
=
1
;
settings
.
echoQuery
=
0
;
settings
.
singleStep
=
0
;
settings
.
singleLineMode
=
0
;
settings
.
queryFout
=
stdout
;
strcpy
(
settings
.
fieldSep
,
DEFAULT_FIELD_SEP
);
while
((
c
=
getopt
(
argc
,
argv
,
"Aa:c:d:ef:F:lhH:nso:p:qST"
))
!=
EOF
)
{
switch
(
c
)
{
case
'A'
:
settings
.
opt
.
a
lign
=
0
;
settings
.
fillA
lign
=
0
;
break
;
case
'a'
:
fe_setauthsvc
(
optarg
,
errbuf
);
...
...
@@ -1151,22 +1025,19 @@ main(int argc, char** argv)
qfilename
=
optarg
;
break
;
case
'F'
:
settings
.
opt
.
fieldSep
=
dupstr
(
optarg
);
strncpy
(
settings
.
fieldSep
,
optarg
,
MAX_FIELD_SEP_LENGTH
);
break
;
case
'l'
:
listDatabases
=
1
;
break
;
case
'h'
:
host
=
optarg
;
break
;
case
'H'
:
settings
.
opt
.
html3
=
1
;
host
=
optarg
;
break
;
case
'n'
:
settings
.
useReadline
=
0
;
break
;
case
'o'
:
setFout
(
&
settings
,
optarg
);
settings
.
queryFout
=
setFout
(
optarg
);
break
;
case
'p'
:
port
=
optarg
;
...
...
@@ -1180,15 +1051,10 @@ main(int argc, char** argv)
case
'S'
:
settings
.
singleLineMode
=
1
;
break
;
case
't'
:
settings
.
opt
.
header
=
0
;
break
;
case
'T'
:
settings
.
opt
.
tableOpt
=
dupstr
(
optarg
);
break
;
case
'x'
:
settings
.
opt
.
expanded
=
0
;
settings
.
printHeader
=
0
;
break
;
case
'h'
:
default:
usage
(
argv
[
0
]);
break
;
...
...
@@ -1201,16 +1067,16 @@ main(int argc, char** argv)
if
(
listDatabases
)
dbname
=
"template1"
;
settings
.
db
=
PQsetdb
(
host
,
port
,
NULL
,
NULL
,
dbname
);
dbname
=
PQdb
(
settings
.
db
);
db
=
PQsetdb
(
host
,
port
,
NULL
,
NULL
,
dbname
);
dbname
=
PQdb
(
db
);
if
(
PQstatus
(
settings
.
db
)
==
CONNECTION_BAD
)
{
if
(
PQstatus
(
db
)
==
CONNECTION_BAD
)
{
fprintf
(
stderr
,
"Connection to database '%s' failed.
\n
"
,
dbname
);
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
settings
.
db
));
fprintf
(
stderr
,
"%s"
,
PQerrorMessage
(
db
));
exit
(
1
);
}
if
(
listDatabases
)
{
exit
(
listAllDbs
(
&
settings
));
exit
(
listAllDbs
(
db
,
&
settings
));
}
if
(
!
settings
.
quiet
&&
!
singleQuery
&&
!
qfilename
)
{
...
...
@@ -1226,6 +1092,7 @@ main(int argc, char** argv)
/* read in a file full of queries instead of reading in queries
interactively */
char
*
line
;
char
prompt
[
100
];
if
(
singleSlashCmd
)
{
/* Not really a query, but "Do what I mean, not what I say." */
...
...
@@ -1235,25 +1102,24 @@ main(int argc, char** argv)
line
=
malloc
(
strlen
(
qfilename
)
+
5
);
sprintf
(
line
,
"
\\
i %s"
,
qfilename
);
}
HandleSlashCmds
(
&
settings
,
line
,
""
);
HandleSlashCmds
(
&
db
,
line
,
(
char
**
)
prompt
,
""
,
&
settings
);
}
else
{
if
(
singleQuery
)
{
exitStatus
=
SendQuery
(
&
settings
,
singleQuery
);
exitStatus
=
SendQuery
(
db
,
singleQuery
,
&
settings
);
}
else
exitStatus
=
MainLoop
(
&
settings
,
stdin
);
exitStatus
=
MainLoop
(
&
db
,
stdin
,
&
settings
);
}
PQfinish
(
settings
.
db
);
PQfinish
(
db
);
return
exitStatus
;
}
#define COPYBUFSIZ 8192
static
void
handleCopyOut
(
PGresult
*
res
,
bool
quiet
)
handleCopyOut
(
PGresult
*
res
,
int
quiet
)
{
bool
copydone
=
false
;
char
copybuf
[
COPYBUFSIZ
];
...
...
@@ -1287,7 +1153,7 @@ handleCopyOut(PGresult *res, bool quiet)
static
void
handleCopyIn
(
PGresult
*
res
,
bool
quiet
)
handleCopyIn
(
PGresult
*
res
,
int
quiet
)
{
bool
copydone
=
false
;
bool
firstload
;
...
...
@@ -1346,38 +1212,24 @@ handleCopyIn(PGresult *res, bool quiet)
PQendcopy
(
res
->
conn
);
}
/* try to open fname and return a FILE*,
if it fails, use stdout, instead */
FILE
*
setFout
(
PsqlSettings
*
ps
,
char
*
fname
)
setFout
(
char
*
fname
)
{
if
(
ps
->
queryFout
&&
ps
->
queryFout
!=
stdout
)
{
if
(
ps
->
pipe
)
pclose
(
ps
->
queryFout
);
else
fclose
(
ps
->
queryFout
);
}
FILE
*
queryFout
;
if
(
!
fname
)
ps
->
queryFout
=
stdout
;
else
{
if
(
*
fname
==
'|'
)
{
signal
(
SIGPIPE
,
SIG_IGN
);
ps
->
queryFout
=
popen
(
fname
+
1
,
"w"
);
ps
->
pipe
=
1
;
}
else
{
ps
->
queryFout
=
fopen
(
fname
,
"w"
);
ps
->
pipe
=
0
;
}
if
(
!
ps
->
queryFout
)
{
queryFout
=
stdout
;
else
{
queryFout
=
fopen
(
fname
,
"w"
);
if
(
!
queryFout
)
{
perror
(
fname
);
ps
->
queryFout
=
stdout
;
queryFout
=
stdout
;
}
}
return
ps
->
queryFout
;
return
queryFout
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment