+ val = PQgetvalue(res, t, 0);
+ if (!val)
+ continue;
+
+ sprintf(path, "%s/%s/%s/%s/%s", dir, db, ploa->table, ploa->attr, val);
+
+ if (lo_export(conn, (Oid) atol(val), path) < 0)
+ fprintf(stderr, "%s\n", PQerrorMessage(conn));
+ else
+ fprintf(majorfile, "%s\t%s\t%s\t%s/%s/%s/%s\n", val,
+ ploa->table, ploa->attr, db, ploa->table, ploa->attr, val);
+ }
+ }
+ }
+ fclose(majorfile);
+ }
+
+
+/*-----
+ * LO import
+ *-----
+ */
+ void import_lo(PGconn *conn, char *space, char *db, char *prog)
+ {
+ PGresult *res;
+ lo_attr loa;
+ FILE *majorfile;
+ long new_oid;
+ char *dir,
+ tab[128], attr[128],
+ path[BUFSIZ], lo_path[BUFSIZ],
+ Qbuff[QUERY_BUFSIZ];
+
+ dir = space ? space : getenv("PWD");
+ sprintf(path, "%s/%s", dir, db);
+
+ sprintf(path, "%s/lo_dump.index", path);
+ if ((majorfile = fopen(path, "r")) == NULL) {
+ perror(path);
+ exit(RE_ERROR);
+ }
+
+ while(fgets(Qbuff, QUERY_BUFSIZ, majorfile)) {
+
+ if (*Qbuff == '#')
+ continue;
+
+ fprintf(stdout, Qbuff);
+
+ sscanf(Qbuff, "%ld\t%s\t%s\t%s\n", &loa.lo_oid, tab, attr, path);
+ loa.table = tab;
+ loa.attr = attr;
+
+ sprintf(lo_path, "%s/%s", dir, path);
+
+ /* import large obj */
+ if ((new_oid = lo_import(conn, lo_path)) <= 0) {
+ fprintf(stderr, "%s\n",PQerrorMessage(conn));
+ PQexec(conn, "ROLLBACK");
+ fprintf(stderr, "\nROLLBACK\n");
+ exit(RE_ERROR);
+ }
+
+ /* query */
+ sprintf(Qbuff, "UPDATE %s SET %s=%ld WHERE %s=%ld",
+ loa.table, loa.attr, new_oid, loa.attr, loa.lo_oid);
+
+ /*fprintf(stderr, Qbuff);*/
+
+ res = PQexec(conn, Qbuff);
+
+ if (!res && PQresultStatus(res) != PGRES_COMMAND_OK) {
+ fprintf(stderr, "%s\n",PQerrorMessage(conn));
+ PQclear(res);
+ PQexec(conn, "ROLLBACK");
+ fprintf(stderr, "\nROLLBACK\n");
+ exit(RE_ERROR);
+ }
+
+ }
+ fclose(majorfile);
+ }
+
+/*-----
+ * The mother of all C functions
+ *-----
+ */
+int main(int argc, char **argv)
+{
+ PGconn *conn;
+ lo_attr *loa =NULL;
+ char *user =NULL,
+ *pwd =NULL,
+ *db =NULL,
+ *host =NULL,
+ *space =NULL;
+ int import =FALSE;
+
+ /* Parse argv */
+ if (argc) {
+ int arg, l_index=0;
+ extern int optind;
+ typedef enum {
+ ARG_USER,
+ ARG_PWD,
+ ARG_DB,
+ ARG_HELP,
+ ARG_IMPORT,
+ ARG_SPACE,
+ ARG_HOST
+ } _ARG_;
+
+ struct option l_opt[] = {
+ { "help", 0, 0, ARG_HELP },
+ { "user", 1, 0, ARG_USER },
+ { "pwd", 1, 0, ARG_PWD },
+ { "db", 1, 0, ARG_DB },
+ { "host", 1, 0, ARG_HOST },
+ { "space", 1, 0, ARG_SPACE },
+ { "import", 0, 0, ARG_IMPORT },
+ { NULL, 0, 0, 0 }
+ };
+
+ while((arg = getopt_long(argc, argv, "hu:p:d:l:t:is:", l_opt, &l_index)) != -1) {
+ switch(arg) {
+ case ARG_HELP:
+ case 'h':
+ usage();
+ exit(RE_OK);
+ case ARG_USER:
+ case 'u':
+ user = strdup(optarg);
+ break;
+ case ARG_HOST:
+ case 't':
+ host = strdup(optarg);
+ break;
+ case ARG_PWD:
+ case 'p':
+ pwd = strdup(optarg);
+ break;
+ case ARG_DB:
+ case 'd':
+ db = strdup(optarg);
+ break;
+ case ARG_SPACE:
+ case 's':
+ space = strdup(optarg);
+ break;
+ case ARG_IMPORT:
+ case 'i':
+ import = TRUE;
+ break;
+ case 'l':
+ loa = init_loa(argv, argc-1, optind-1);
+ break;
+ }
+ }
+ }
+
+ if (!space && !getenv("PWD")) {
+ fprintf(stderr, "%s: can't set directory (not set '-s' or $PWD).\n", argv[0]);
+ exit(RE_ERROR);
+ }
+
+ /* Make PG connection */
+ conn = PQsetdbLogin(host, NULL, NULL, NULL, db, user, pwd);
+
+ /* check to see that the backend connection was successfully made */
+ if (PQstatus(conn) == CONNECTION_BAD) {
+ fprintf(stderr, "%s\n",PQerrorMessage(conn));
+ exit(RE_ERROR);
+ }
+
+ PQexec(conn, "BEGIN");
+
+ if (import) {
+ /* import obj */
+ import_lo(conn, space, db, argv[0]);
+ } else if (loa) {
+ /* Dump obj */
+ dump_lo(conn, space, loa, db, argv[0]);
+ } else {
+ fprintf(stderr, "%s: ERROR: bad arg!\n", argv[0]);
+ usage();
+ }
+
+ PQexec(conn, "COMMIT");
+
+ /* bye PG */
+ PQfinish(conn);
+ exit(RE_OK);
+}
\ No newline at end of file