📄 pg_dump.c
字号:
{ int c; const char *progname; const char *filename = NULL; const char *dbname = NULL; const char *pghost = NULL; const char *pgport = NULL; char *tablename = NULL; bool oids = false; TableInfo *tblinfo; int numTables; char connect_string[512] = ""; char tmp_string[128]; char username[100]; char password[100]; bool use_password = false; g_verbose = false; force_quotes = true; dropSchema = false; strcpy(g_comment_start, "-- "); g_comment_end[0] = '\0'; strcpy(g_opaque_type, "opaque"); dataOnly = schemaOnly = dumpData = attrNames = false; progname = *argv; while ((c = getopt(argc, argv, "acdDf:h:nNop:st:uvxz")) != EOF) { switch (c) { case 'a': /* Dump data only */ dataOnly = true; break; case 'c': /* clean (i.e., drop) schema prior to * create */ dropSchema = true; break; case 'd': /* dump data as proper insert strings */ dumpData = true; break; case 'D': /* dump data as proper insert strings with * attr names */ dumpData = true; attrNames = true; break; case 'f': /* output file name */ filename = optarg; break; case 'h': /* server host */ pghost = optarg; break; case 'n': /* Do not force double-quotes on * identifiers */ force_quotes = false; break; case 'N': /* Force double-quotes on identifiers */ force_quotes = true; break; case 'o': /* Dump oids */ oids = true; break; case 'p': /* server port */ pgport = optarg; break; case 's': /* dump schema only */ schemaOnly = true; break; case 't': /* Dump data for this table only */ { int i; tablename = strdup(optarg); /* * quoted string? Then strip quotes and preserve * case... */ if (tablename[0] == '"') { strcpy(tablename, &tablename[1]); if (*(tablename + strlen(tablename) - 1) == '"') *(tablename + strlen(tablename) - 1) = '\0'; } /* otherwise, convert table name to lowercase... */ else { for (i = 0; tablename[i]; i++) if (isascii((unsigned char) tablename[i]) && isupper(tablename[i])) tablename[i] = tolower(tablename[i]); } } break; case 'u': use_password = true; break; case 'v': /* verbose */ g_verbose = true; break; case 'x': /* skip ACL dump */ aclsSkip = true; break; case 'z': /* Old ACL option bjm 1999/05/27 */ fprintf(stderr, "%s: The -z option(dump ACLs) is now the default, continuing.\n", progname); break; default: usage(progname); break; } } if (dumpData == true && oids == true) { fprintf(stderr, "%s: INSERT's can not set oids, so INSERT and OID options can not be used together.\n", progname); exit(2); } /* open the output file */ if (filename == NULL) g_fout = stdout; else {#ifndef __CYGWIN32__ g_fout = fopen(filename, "w");#else g_fout = fopen(filename, "wb");#endif if (g_fout == NULL) { fprintf(stderr, "%s: could not open output file named %s for writing\n", progname, filename); exit(2); } } /* find database */ if (!(dbname = argv[optind]) && !(dbname = getenv("DATABASE"))) { fprintf(stderr, "%s: no database name specified\n", progname); exit(2); } /* g_conn = PQsetdb(pghost, pgport, NULL, NULL, dbname); */ if (pghost != NULL) { sprintf(tmp_string, "host=%s ", pghost); strcat(connect_string, tmp_string); } if (pgport != NULL) { sprintf(tmp_string, "port=%s ", pgport); strcat(connect_string, tmp_string); } if (dbname != NULL) { sprintf(tmp_string, "dbname=%s ", dbname); strcat(connect_string, tmp_string); } if (use_password) { prompt_for_password(username, password); strcat(connect_string, "authtype=password "); sprintf(tmp_string, "user=%s ", username); strcat(connect_string, tmp_string); sprintf(tmp_string, "password=%s ", password); strcat(connect_string, tmp_string); MemSet(tmp_string, 0, sizeof(tmp_string)); MemSet(password, 0, sizeof(password)); } g_conn = PQconnectdb(connect_string); MemSet(connect_string, 0, sizeof(connect_string)); /* check to see that the backend connection was successfully made */ if (PQstatus(g_conn) == CONNECTION_BAD) { fprintf(stderr, "Connection to database '%s' failed.\n", dbname); fprintf(stderr, "%s\n", PQerrorMessage(g_conn)); exit_nicely(g_conn); } /* * Start serializable transaction to dump consistent data */ { PGresult *res; res = PQexec(g_conn, "begin"); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "BEGIN command failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn)); exit_nicely(g_conn); } PQclear(res); res = PQexec(g_conn, "set transaction isolation level serializable"); if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) { fprintf(stderr, "SET TRANSACTION command failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn)); exit_nicely(g_conn); } PQclear(res); } g_last_builtin_oid = findLastBuiltinOid(); if (oids == true) setMaxOid(g_fout); if (!dataOnly) { if (g_verbose) fprintf(stderr, "%s last builtin oid is %u %s\n", g_comment_start, g_last_builtin_oid, g_comment_end); tblinfo = dumpSchema(g_fout, &numTables, tablename, aclsSkip); } else tblinfo = dumpSchema(NULL, &numTables, tablename, aclsSkip); if (!schemaOnly) dumpClasses(tblinfo, numTables, g_fout, tablename, oids); if (!dataOnly) /* dump indexes and triggers at the end * for performance */ { dumpSchemaIdx(g_fout, tablename, tblinfo, numTables); dumpTriggers(g_fout, tablename, tblinfo, numTables); dumpRules(g_fout, tablename, tblinfo, numTables); } fflush(g_fout); if (g_fout != stdout) fclose(g_fout); clearTableInfo(tblinfo, numTables); PQfinish(g_conn); exit(0);}/* * getTypes: * read all base types in the system catalogs and return them in the * TypeInfo* structure * * numTypes is set to the number of types read in * */TypeInfo *getTypes(int *numTypes){ PGresult *res; int ntups; int i; char query[MAX_QUERY_SIZE]; TypeInfo *tinfo; int i_oid; int i_typowner; int i_typname; int i_typlen; int i_typprtlen; int i_typinput; int i_typoutput; int i_typreceive; int i_typsend; int i_typelem; int i_typdelim; int i_typdefault; int i_typrelid; int i_typbyval; int i_usename; /* find all base types */ /* * we include even the built-in types because those may be used as * array elements by user-defined types */ /* * we filter out the built-in types when we dump out the types */ sprintf(query, "SELECT pg_type.oid, typowner,typname, typlen, typprtlen, " "typinput, typoutput, typreceive, typsend, typelem, typdelim, " "typdefault, typrelid,typbyval, usename from pg_type, pg_user " "where typowner = usesysid"); res = PQexec(g_conn, query); if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "getTypes(): SELECT failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn)); exit_nicely(g_conn); } ntups = PQntuples(res); tinfo = (TypeInfo *) malloc(ntups * sizeof(TypeInfo)); i_oid = PQfnumber(res, "oid"); i_typowner = PQfnumber(res, "typowner"); i_typname = PQfnumber(res, "typname"); i_typlen = PQfnumber(res, "typlen"); i_typprtlen = PQfnumber(res, "typprtlen"); i_typinput = PQfnumber(res, "typinput"); i_typoutput = PQfnumber(res, "typoutput"); i_typreceive = PQfnumber(res, "typreceive"); i_typsend = PQfnumber(res, "typsend"); i_typelem = PQfnumber(res, "typelem"); i_typdelim = PQfnumber(res, "typdelim"); i_typdefault = PQfnumber(res, "typdefault"); i_typrelid = PQfnumber(res, "typrelid"); i_typbyval = PQfnumber(res, "typbyval"); i_usename = PQfnumber(res, "usename"); for (i = 0; i < ntups; i++) { tinfo[i].oid = strdup(PQgetvalue(res, i, i_oid)); tinfo[i].typowner = strdup(PQgetvalue(res, i, i_typowner)); tinfo[i].typname = strdup(PQgetvalue(res, i, i_typname)); tinfo[i].typlen = strdup(PQgetvalue(res, i, i_typlen)); tinfo[i].typprtlen = strdup(PQgetvalue(res, i, i_typprtlen)); tinfo[i].typinput = strdup(PQgetvalue(res, i, i_typinput)); tinfo[i].typoutput = strdup(PQgetvalue(res, i, i_typoutput)); tinfo[i].typreceive = strdup(PQgetvalue(res, i, i_typreceive)); tinfo[i].typsend = strdup(PQgetvalue(res, i, i_typsend)); tinfo[i].typelem = strdup(PQgetvalue(res, i, i_typelem)); tinfo[i].typdelim = strdup(PQgetvalue(res, i, i_typdelim)); tinfo[i].typdefault = strdup(PQgetvalue(res, i, i_typdefault)); tinfo[i].typrelid = strdup(PQgetvalue(res, i, i_typrelid)); tinfo[i].usename = strdup(PQgetvalue(res, i, i_usename)); if (strcmp(PQgetvalue(res, i, i_typbyval), "f") == 0) tinfo[i].passedbyvalue = 0; else tinfo[i].passedbyvalue = 1; /* * check for user-defined array types, omit system generated ones */ if ((strcmp(tinfo[i].typelem, "0") != 0) && tinfo[i].typname[0] != '_') tinfo[i].isArray = 1; else tinfo[i].isArray = 0; } *numTypes = ntups; PQclear(res); return tinfo;}/* * getOperators: * read all operators in the system catalogs and return them in the * OprInfo* structure * * numOprs is set to the number of operators read in * * */OprInfo *getOperators(int *numOprs){ PGresult *res; int ntups; int i; char query[MAX_QUERY_SIZE]; OprInfo *oprinfo; int i_oid; int i_oprname; int i_oprkind; int i_oprcode; int i_oprleft; int i_oprright; int i_oprcom; int i_oprnegate; int i_oprrest; int i_oprjoin; int i_oprcanhash; int i_oprlsortop; int i_oprrsortop; int i_usename; /* * find all operators, including builtin operators, filter out * system-defined operators at dump-out time */ sprintf(query, "SELECT pg_operator.oid, oprname, oprkind, oprcode, " "oprleft, oprright, oprcom, oprnegate, oprrest, oprjoin, " "oprcanhash, oprlsortop, oprrsortop, usename " "from pg_operator, pg_user " "where oprowner = usesysid"); res = PQexec(g_conn, query); if (!res || PQresultStatus(res) != PGRES_TUPLES_OK) { fprintf(stderr, "getOperators(): SELECT failed. Explanation from backend: '%s'.\n", PQerrorMessage(g_conn)); exit_nicely(g_conn); } ntups = PQntuples(res); *numOprs = ntups; oprinfo = (OprInfo *) malloc(ntups * sizeof(OprInfo)); i_oid = PQfnumber(res, "oid"); i_oprname = PQfnumber(res, "oprname"); i_oprkind = PQfnumber(res, "oprkind"); i_oprcode = PQfnumber(res, "oprcode"); i_oprleft = PQfnumber(res, "oprleft"); i_oprright = PQfnumber(res, "oprright"); i_oprcom = PQfnumber(res, "oprcom"); i_oprnegate = PQfnumber(res, "oprnegate"); i_oprrest = PQfnumber(res, "oprrest"); i_oprjoin = PQfnumber(res, "oprjoin"); i_oprcanhash = PQfnumber(res, "oprcanhash"); i_oprlsortop = PQfnumber(res, "oprlsortop"); i_oprrsortop = PQfnumber(res, "oprrsortop"); i_usename = PQfnumber(res, "usename"); for (i = 0; i < ntups; i++) { oprinfo[i].oid = strdup(PQgetvalue(res, i, i_oid)); oprinfo[i].oprname = strdup(PQgetvalue(res, i, i_oprname)); oprinfo[i].oprkind = strdup(PQgetvalue(res, i, i_oprkind)); oprinfo[i].oprcode = strdup(PQgetvalue(res, i, i_oprcode)); oprinfo[i].oprleft = strdup(PQgetvalue(res, i, i_oprleft)); oprinfo[i].oprright = strdup(PQgetvalue(res, i, i_oprright)); oprinfo[i].oprcom = strdup(PQgetvalue(res, i, i_oprcom)); oprinfo[i].oprnegate = strdup(PQgetvalue(res, i, i_oprnegate)); oprinfo[i].oprrest = strdup(PQgetvalue(res, i, i_oprrest)); oprinfo[i].oprjoin = strdup(PQgetvalue(res, i, i_oprjoin)); oprinfo[i].oprcanhash = strdup(PQgetvalue(res, i, i_oprcanhash)); oprinfo[i].oprlsortop = strdup(PQgetvalue(res, i, i_oprlsortop)); oprinfo[i].oprrsortop = strdup(PQgetvalue(res, i, i_oprrsortop)); oprinfo[i].usename = strdup(PQgetvalue(res, i, i_usename)); } PQclear(res); return oprinfo;}voidclearTypeInfo(TypeInfo *tp, int numTypes){ int i; for (i = 0; i < numTypes; ++i) { if (tp[i].oid) free(tp[i].oid); if (tp[i].typowner) free(tp[i].typowner); if (tp[i].typname) free(tp[i].typname); if (tp[i].typlen) free(tp[i].typlen); if (tp[i].typprtlen) free(tp[i].typprtlen); if (tp[i].typinput) free(tp[i].typinput); if (tp[i].typoutput) free(tp[i].typoutput); if (tp[i].typreceive) free(tp[i].typreceive); if (tp[i].typsend) free(tp[i].typsend); if (tp[i].typelem) free(tp[i].typelem); if (tp[i].typdelim) free(tp[i].typdelim); if (tp[i].typdefault) free(tp[i].typdefault); if (tp[i].typrelid) free(tp[i].typrelid); if (tp[i].usename) free(tp[i].usename); } free(tp);}voidclearFuncInfo(FuncInfo *fun, int numFuncs){ int i, a; if (!fun) return; for (i = 0; i < numFuncs; ++i) { if (fun[i].oid) free(fun[i].oid); if (fun[i].proname) free(fun[i].proname); if (fun[i].usename) free(fun[i].usename); for (a = 0; a < 8; ++a) if (fun[i].argtypes[a]) free(fun[i].argtypes[a]); if (fun[i].prorettype) free(fun[i].prorettype); if (fun[i].prosrc) free(fun[i].prosrc); if (fun[i].probin) free(fun[i].probin); } free(fun);}static void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -