Author: andreas
Date: 2005-09-29 17:45:58 +0100 (Thu, 29 Sep 2005)
New Revision: 4474

Modified:
   trunk/pgadmin3/xtra/admin81/README.admin81
   trunk/pgadmin3/xtra/admin81/admin81.c
   trunk/pgadmin3/xtra/admin81/admin81.sql.in
Log:
Admin81 for pgsql81

Modified: trunk/pgadmin3/xtra/admin81/README.admin81
===================================================================
--- trunk/pgadmin3/xtra/admin81/README.admin81  2005-09-27 09:09:14 UTC (rev 
4473)
+++ trunk/pgadmin3/xtra/admin81/README.admin81  2005-09-29 16:45:58 UTC (rev 
4474)
@@ -19,19 +19,31 @@
 make
 make install
 
-pgAdmin will look for the functions in the Initial Database specified in the
-connection dialogue for the server. To install the functions in the database,
-either run the admin81.sql script using the pgAdmin SQL tool (and then 
-restart pgAdmin), or run the script using psql, eg:
+pgAdmin will look for the functions in the Maintenance Database (usually 
+"postgres" for 8.1 servers) specified in the connection dialogue for the 
server. 
+To install the functions in the database, either run the admin81.sql script 
using
+the pgAdmin SQL tool (and then close and reopen the connection to the freshly
+instrumented server), or run the script using psql, eg:
 
-psql -u postgres template1 < admin81.sql
+psql -u postgres postgres < admin81.sql
 
 On PostgreSQL 8.1 or above, you should use the admin81.sql script.
 
 Objects implemented (superuser only)
 ====================================
 
-int8 pg_file_write(fname text, data text, append bool)
-bool pg_file_rename(oldname text, newname text)
-bool pg_file_rename(oldname text, newname text, archivname text)
-bool pg_file_unlink(fname text)
+int8 pg_catalog.pg_file_write(fname text, data text, append bool)
+int8 pg_catalog.pg_file_read(fname text, data text, append bool)
+bool pg_catalog.pg_file_rename(oldname text, newname text)
+bool pg_catalog.pg_file_rename(oldname text, newname text, archivname text)
+bool pg_catalog.pg_file_unlink(fname text)
+bigint pg_catalog.pg_file_size(text)
+int4 pg_catalog.pg_logfile_rotate()
+setof record pg_catalog.pg_logdir_ls()
+
+
+These functions implement full instrumentation for PostgreSQL 8.1 servers when
+accessed using pgAdmin III V1.4 and above. For pgAdmin III V1.2, the additional
+view pg_logdir_ls is necessary (available from the admin81.sql script, 
commented
+out in the last section). We recommend omitting this deprecated view, and
+upgrade to pgAdmin III V1.4 instead.

Modified: trunk/pgadmin3/xtra/admin81/admin81.c
===================================================================
--- trunk/pgadmin3/xtra/admin81/admin81.c       2005-09-27 09:09:14 UTC (rev 
4473)
+++ trunk/pgadmin3/xtra/admin81/admin81.c       2005-09-29 16:45:58 UTC (rev 
4474)
@@ -23,6 +23,7 @@
 #include "storage/fd.h"
 #include "catalog/pg_type.h"
 #include "funcapi.h"
+#include "utils/datetime.h"
 
 
 #ifdef WIN32
@@ -39,14 +40,17 @@
 
 extern DLLIMPORT char *DataDir;
 extern DLLIMPORT char *Log_directory;
+extern DLLIMPORT char *Log_filename;
 
 Datum pg_file_write(PG_FUNCTION_ARGS);
 Datum pg_file_rename(PG_FUNCTION_ARGS);
 Datum pg_file_unlink(PG_FUNCTION_ARGS);
+Datum pg_logdir_ls(PG_FUNCTION_ARGS);
 
 PG_FUNCTION_INFO_V1(pg_file_write);
 PG_FUNCTION_INFO_V1(pg_file_rename);
 PG_FUNCTION_INFO_V1(pg_file_unlink);
+PG_FUNCTION_INFO_V1(pg_logdir_ls);
 
 typedef struct 
 {
@@ -280,3 +284,107 @@
        PG_RETURN_BOOL(true);
 }
 
+
+Datum pg_logdir_ls(PG_FUNCTION_ARGS)
+{
+       FuncCallContext *funcctx;
+       struct dirent *de;
+       directory_fctx *fctx;
+
+       if (!superuser()) 
+               ereport(ERROR,
+                               (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+                                (errmsg("only superuser can list the log 
directory"))));
+       
+       if (memcmp(Log_filename, "postgresql-%Y-%m-%d_%H%M%S.log", 30) != 0)
+               ereport(ERROR,
+                               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                                (errmsg("the log_filename parameter must equal 
'postgresql-%%Y-%%m-%%d_%%H%%M%%S.log'"))));
+
+       if (SRF_IS_FIRSTCALL())
+       {
+               MemoryContext oldcontext;
+               TupleDesc tupdesc;
+
+               funcctx=SRF_FIRSTCALL_INIT();
+               oldcontext = 
MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
+
+               fctx = palloc(sizeof(directory_fctx));
+               if (is_absolute_path(Log_directory))
+                   fctx->location = Log_directory;
+               else
+               {
+                       fctx->location = palloc(strlen(DataDir) + 
strlen(Log_directory) +2);
+                       sprintf(fctx->location, "%s/%s", DataDir, 
Log_directory);
+               }
+               tupdesc = CreateTemplateTupleDesc(2, false);
+               TupleDescInitEntry(tupdesc, (AttrNumber) 1, "starttime",
+                                                  TIMESTAMPOID, -1, 0);
+               TupleDescInitEntry(tupdesc, (AttrNumber) 2, "filename",
+                                                  TEXTOID, -1, 0);
+
+               funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
+               
+               fctx->dirdesc = AllocateDir(fctx->location);
+
+               if (!fctx->dirdesc)
+                   ereport(ERROR,
+                                       (errcode_for_file_access(),
+                                        errmsg("%s is not browsable: %m", 
fctx->location)));
+
+               funcctx->user_fctx = fctx;
+               MemoryContextSwitchTo(oldcontext);
+       }
+
+       funcctx=SRF_PERCALL_SETUP();
+       fctx = (directory_fctx*) funcctx->user_fctx;
+
+       if (!fctx->dirdesc)  /* not a readable directory  */
+               SRF_RETURN_DONE(funcctx);
+
+       while ((de = readdir(fctx->dirdesc)) != NULL)
+       {
+               char *values[2];
+               HeapTuple tuple;
+            
+               char            *field[MAXDATEFIELDS];
+               char            lowstr[MAXDATELEN + 1];
+               int             dtype;
+               int             nf, ftype[MAXDATEFIELDS];
+               fsec_t          fsec;
+               int             tz = 0;
+               struct          pg_tm date;
+
+               /*
+                * Default format:
+                *        postgresql-YYYY-MM-DD_HHMMSS.log
+                */
+               if (strlen(de->d_name) != 32
+                   || memcmp(de->d_name, "postgresql-", 11)
+                       || de->d_name[21] != '_'
+                       || strcmp(de->d_name + 28, ".log"))
+                     continue;
+
+               values[1] = palloc(strlen(fctx->location) + strlen(de->d_name) 
+ 2);
+               sprintf(values[1], "%s/%s", fctx->location, de->d_name);
+
+               values[0] = de->d_name + 11;       /* timestamp */
+               values[0][17] = 0;
+
+                    /* parse and decode expected timestamp */
+               if (ParseDateTime(values[0], lowstr, MAXDATELEN, field, ftype, 
MAXDATEFIELDS, &nf))
+                   continue;
+
+               if (DecodeDateTime(field, ftype, nf, &dtype, &date, &fsec, &tz))
+                   continue;
+
+               /* Seems the format fits the expected format; feed it into the 
tuple */
+
+               tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
+
+               SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(tuple));
+       }
+
+       FreeDir(fctx->dirdesc);
+       SRF_RETURN_DONE(funcctx);
+}

Modified: trunk/pgadmin3/xtra/admin81/admin81.sql.in
===================================================================
--- trunk/pgadmin3/xtra/admin81/admin81.sql.in  2005-09-27 09:09:14 UTC (rev 
4473)
+++ trunk/pgadmin3/xtra/admin81/admin81.sql.in  2005-09-29 16:45:58 UTC (rev 
4474)
@@ -4,18 +4,50 @@
 
 /* generic file access functions (genfile.c) */
 
-CREATE FUNCTION pg_file_write(text, text, bool) RETURNS bigint
+CREATE FUNCTION pg_catalog.pg_file_write(text, text, bool) RETURNS bigint
    AS 'MODULE_PATHNAME', 'pg_file_write'
        LANGUAGE C VOLATILE STRICT;
 
-CREATE FUNCTION pg_file_rename(text, text, text) RETURNS bool
+CREATE FUNCTION pg_catalog.pg_file_rename(text, text, text) RETURNS bool
    AS 'MODULE_PATHNAME', 'pg_file_rename'
        LANGUAGE C VOLATILE;
 
-CREATE FUNCTION pg_file_unlink(text) RETURNS bool
+CREATE FUNCTION pg_catalog.pg_file_unlink(text) RETURNS bool
    AS 'MODULE_PATHNAME', 'pg_file_unlink'
        LANGUAGE C VOLATILE STRICT;
 
-CREATE FUNCTION pg_file_rename(text, text) RETURNS bool
+CREATE FUNCTION pg_catalog.pg_file_rename(text, text) RETURNS bool
    AS 'SELECT pg_file_rename($1, $2, NULL); '
        LANGUAGE SQL VOLATILE STRICT;
+
+CREATE FUNCTION pg_catalog.pg_logdir_ls() RETURNS setof record
+   AS 'MODULE_PATHNAME', 'pg_logdir_ls'
+       LANGUAGE C VOLATILE STRICT;
+
+
+/* compatibility redefines */
+
+CREATE FUNCTION pg_catalog.pg_logfile_rotate() RETURNS int4
+  AS 'pg_rotate_logfile'
+   LANGUAGE INTERNAL VOLATILE STRICT;
+
+CREATE FUNCTION pg_catalog.pg_file_read(text, bigint, bigint) RETURNS text
+   AS 'pg_read_file'
+       LANGUAGE INTERNAL VOLATILE STRICT;
+
+CREATE FUNCTION pg_catalog.pg_file_size(text) RETURNS bigint
+   AS 'SELECT size FROM pg_stat_file($1)'
+    LANGUAGE SQL VOLATILE STRICT;
+
+
+/*
+
+-- if running pgAdmin 1.2 against this database, 
+-- this view is used to access log files 
+-- (1.3 and later won't need it).
+CREATE VIEW pg_logdir_ls AS
+       SELECT *
+       FROM pg_logdir_ls() AS A
+       (filetime timestamp, filename text);
+
+*/


---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
       choose an index scan if your joining column's datatypes do not
       match

Reply via email to