summaryrefslogtreecommitdiff
path: root/contrib/pg_dumplo/lo_export.c
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2000-06-15 19:05:22 +0000
committerBruce Momjian <bruce@momjian.us>2000-06-15 19:05:22 +0000
commit5683e704d09caaa29f7a76f0d93ca8fc5f8c0e75 (patch)
tree3ae68795e6580e8ca4e464d8416cfc42d1b1bc49 /contrib/pg_dumplo/lo_export.c
parentf7f177d372750e4f766ccefdf20e1b30d66cba0a (diff)
downloadpostgresql-5683e704d09caaa29f7a76f0d93ca8fc5f8c0e75.tar.gz
Add missing /contrib files to CVS.
Diffstat (limited to 'contrib/pg_dumplo/lo_export.c')
-rw-r--r--contrib/pg_dumplo/lo_export.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/contrib/pg_dumplo/lo_export.c b/contrib/pg_dumplo/lo_export.c
new file mode 100644
index 0000000000..80d401902c
--- /dev/null
+++ b/contrib/pg_dumplo/lo_export.c
@@ -0,0 +1,176 @@
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <time.h>
+
+#include <libpq-fe.h>
+#include <libpq/libpq-fs.h>
+
+#include "pg_dumplo.h"
+
+extern int errno;
+
+#define LOAD_LOLIST_QUERY "\
+ SELECT c.relname, a.attname \
+ FROM pg_class c, pg_attribute a, pg_type t \
+ WHERE a.attnum > 0 \
+ AND a.attrelid = c.oid \
+ AND a.atttypid = t.oid \
+ AND t.typname = 'oid' \
+ AND c.relname NOT LIKE 'pg_%'"
+
+
+void
+load_lolist( LODumpMaster *pgLO )
+{
+ LOlist *ll;
+ int i;
+ int n;
+
+ /* ----------
+ * Now find any candidate tables who have columns of type oid (the
+ * column oid is ignored, as it has attnum < 1)
+ * ----------
+ */
+ if (!(pgLO->res = PQexec(pgLO->conn, LOAD_LOLIST_QUERY))) {
+
+ fprintf(stderr, "%s: Select from pg_class failed.\n", progname);
+ exit(RE_ERROR);
+ }
+
+ if ((n = PQntuples(pgLO->res)) == 0) {
+
+ fprintf(stderr, "%s: No large objects in the database.\n", progname);
+ exit(RE_ERROR);
+ }
+
+ pgLO->lolist = (LOlist *) malloc((n + 1) * sizeof(LOlist));
+
+ if (!pgLO->lolist) {
+ fprintf(stderr, "%s: can't allocate memory\n", progname);
+ exit(RE_ERROR);
+ }
+
+ for (i = 0, ll = pgLO->lolist; i < n; i++, ll++) {
+ ll->lo_table = strdup(PQgetvalue(pgLO->res, i, 0));
+ ll->lo_attr = strdup(PQgetvalue(pgLO->res, i, 1));
+ }
+
+ PQclear(pgLO->res);
+ ll++;
+ ll->lo_table = ll->lo_attr = (char *) NULL;
+}
+
+void
+pglo_export(LODumpMaster *pgLO)
+{
+ LOlist *ll;
+ int tuples;
+ char path[BUFSIZ],
+ Qbuff[QUERY_BUFSIZ];
+
+ if (pgLO->action != ACTION_SHOW) {
+ time_t t;
+ time(&t);
+ fprintf(pgLO->index, "#\n# This is the PostgreSQL large object dump index\n#\n");
+ fprintf(pgLO->index, "#\tDate: %s", ctime(&t));
+ fprintf(pgLO->index, "#\tHost: %s\n", pgLO->host);
+ fprintf(pgLO->index, "#\tDatabase: %s\n", pgLO->db);
+ fprintf(pgLO->index, "#\tUser: %s\n", pgLO->user);
+ fprintf(pgLO->index, "#\n# oid\ttable\tattribut\tinfile\n#\n");
+ }
+
+ pgLO->counter = 0;
+
+ for(ll=pgLO->lolist; ll->lo_table != NULL; ll++) {
+
+ /* ----------
+ * Query
+ * ----------
+ */
+ sprintf(Qbuff, "SELECT x.%s FROM %s x, pg_class c WHERE x.%s = c.oid and c.relkind = 'l'",
+ ll->lo_attr, ll->lo_table, ll->lo_attr);
+
+ /* puts(Qbuff); */
+
+ pgLO->res = PQexec(pgLO->conn, Qbuff);
+
+ if ((tuples = PQntuples(pgLO->res)) == 0) {
+
+ if (!pgLO->quiet && pgLO->action == ACTION_EXPORT_ATTR)
+ printf("%s: not large objets in '%s'\n", progname, ll->lo_table);
+ continue;
+
+ } else if (check_res(pgLO)) {
+
+ int t;
+ char *val;
+
+ /* ----------
+ * Create DIR/FILE
+ * ----------
+ */
+ if (tuples && pgLO->action != ACTION_SHOW) {
+
+ sprintf(path, "%s/%s/%s", pgLO->space, pgLO->db, ll->lo_table);
+
+ if (mkdir(path, DIR_UMASK) == -1) {
+ if (errno != EEXIST) {
+ perror(path);
+ exit(RE_ERROR);
+ }
+ }
+
+ sprintf(path, "%s/%s", path, ll->lo_attr);
+
+ if (mkdir(path, DIR_UMASK) == -1) {
+ if (errno != EEXIST) {
+ perror(path);
+ exit(RE_ERROR);
+ }
+ }
+
+ if (!pgLO->quiet)
+ printf("dump %s.%s (%d lagre obj)\n",
+ ll->lo_table, ll->lo_attr, tuples);
+ }
+
+ pgLO->counter += tuples;
+
+ for(t=0; t<tuples; t++) {
+
+ Oid lo = (Oid) 0;
+
+ val = PQgetvalue(pgLO->res, t, 0);
+
+ if (!val)
+ continue;
+ else
+ lo = (Oid) atol(val);
+
+ if (pgLO->action == ACTION_SHOW) {
+ printf("%s.%s: %ld\n", ll->lo_table,
+ ll->lo_attr, (long) lo);
+ continue;
+ }
+
+ sprintf(path, "%s/%s/%s/%s/%s", pgLO->space,
+ pgLO->db, ll->lo_table, ll->lo_attr, val);
+
+ if (lo_export(pgLO->conn, lo, path) < 0)
+ fprintf(stderr, "%s: %s\n", PQerrorMessage(pgLO->conn), progname);
+
+ else
+ fprintf(pgLO->index, "%s\t%s\t%s\t%s/%s/%s/%s\n", val,
+ ll->lo_table, ll->lo_attr, pgLO->db, ll->lo_table, ll->lo_attr, val);
+ }
+ }
+ }
+ }
+