@@ -67,10 +67,20 @@ static int process_global_sql_commands(PGconn *conn, const char *dumpdirpath,
67
67
const char * outfile );
68
68
static void copy_or_print_global_file (const char * outfile , FILE * pfile );
69
69
static int get_dbnames_list_to_restore (PGconn * conn ,
70
- SimpleOidStringList * dbname_oid_list ,
70
+ SimplePtrList * dbname_oid_list ,
71
71
SimpleStringList db_exclude_patterns );
72
72
static int get_dbname_oid_list_from_mfile (const char * dumpdirpath ,
73
- SimpleOidStringList * dbname_oid_list );
73
+ SimplePtrList * dbname_oid_list );
74
+
75
+ /*
76
+ * Stores a database OID and the corresponding name.
77
+ */
78
+ typedef struct DbOidName
79
+ {
80
+ Oid oid ;
81
+ char str [FLEXIBLE_ARRAY_MEMBER ]; /* null-terminated string here */
82
+ } DbOidName ;
83
+
74
84
75
85
int
76
86
main (int argc , char * * argv )
@@ -927,7 +937,7 @@ read_one_statement(StringInfo inBuf, FILE *pfile)
927
937
*/
928
938
static int
929
939
get_dbnames_list_to_restore (PGconn * conn ,
930
- SimpleOidStringList * dbname_oid_list ,
940
+ SimplePtrList * dbname_oid_list ,
931
941
SimpleStringList db_exclude_patterns )
932
942
{
933
943
int count_db = 0 ;
@@ -943,21 +953,22 @@ get_dbnames_list_to_restore(PGconn *conn,
943
953
* Process one by one all dbnames and if specified to skip restoring, then
944
954
* remove dbname from list.
945
955
*/
946
- for (SimpleOidStringListCell * db_cell = dbname_oid_list -> head ;
956
+ for (SimplePtrListCell * db_cell = dbname_oid_list -> head ;
947
957
db_cell ; db_cell = db_cell -> next )
948
958
{
959
+ DbOidName * dbidname = (DbOidName * ) db_cell -> ptr ;
949
960
bool skip_db_restore = false;
950
961
PQExpBuffer db_lit = createPQExpBuffer ();
951
962
952
- appendStringLiteralConn (db_lit , db_cell -> str , conn );
963
+ appendStringLiteralConn (db_lit , dbidname -> str , conn );
953
964
954
965
for (SimpleStringListCell * pat_cell = db_exclude_patterns .head ; pat_cell ; pat_cell = pat_cell -> next )
955
966
{
956
967
/*
957
968
* If there is an exact match then we don't need to try a pattern
958
969
* match
959
970
*/
960
- if (pg_strcasecmp (db_cell -> str , pat_cell -> val ) == 0 )
971
+ if (pg_strcasecmp (dbidname -> str , pat_cell -> val ) == 0 )
961
972
skip_db_restore = true;
962
973
/* Otherwise, try a pattern match if there is a connection */
963
974
else if (conn )
@@ -972,7 +983,7 @@ get_dbnames_list_to_restore(PGconn *conn,
972
983
if (dotcnt > 0 )
973
984
{
974
985
pg_log_error ("improper qualified name (too many dotted names): %s" ,
975
- db_cell -> str );
986
+ dbidname -> str );
976
987
PQfinish (conn );
977
988
exit_nicely (1 );
978
989
}
@@ -982,7 +993,7 @@ get_dbnames_list_to_restore(PGconn *conn,
982
993
if ((PQresultStatus (res ) == PGRES_TUPLES_OK ) && PQntuples (res ))
983
994
{
984
995
skip_db_restore = true;
985
- pg_log_info ("database \"%s\" matches exclude pattern: \"%s\"" , db_cell -> str , pat_cell -> val );
996
+ pg_log_info ("database \"%s\" matches exclude pattern: \"%s\"" , dbidname -> str , pat_cell -> val );
986
997
}
987
998
988
999
PQclear (res );
@@ -1001,8 +1012,8 @@ get_dbnames_list_to_restore(PGconn *conn,
1001
1012
*/
1002
1013
if (skip_db_restore )
1003
1014
{
1004
- pg_log_info ("excluding database \"%s\"" , db_cell -> str );
1005
- db_cell -> oid = InvalidOid ;
1015
+ pg_log_info ("excluding database \"%s\"" , dbidname -> str );
1016
+ dbidname -> oid = InvalidOid ;
1006
1017
}
1007
1018
else
1008
1019
{
@@ -1024,13 +1035,14 @@ get_dbnames_list_to_restore(PGconn *conn,
1024
1035
* Returns, total number of database names in map.dat file.
1025
1036
*/
1026
1037
static int
1027
- get_dbname_oid_list_from_mfile (const char * dumpdirpath , SimpleOidStringList * dbname_oid_list )
1038
+ get_dbname_oid_list_from_mfile (const char * dumpdirpath , SimplePtrList * dbname_oid_list )
1028
1039
{
1040
+ StringInfoData linebuf ;
1029
1041
FILE * pfile ;
1030
1042
char map_file_path [MAXPGPATH ];
1031
- char line [MAXPGPATH ];
1032
1043
int count = 0 ;
1033
1044
1045
+
1034
1046
/*
1035
1047
* If there is only global.dat file in dump, then return from here as
1036
1048
* there is no database to restore.
@@ -1049,32 +1061,43 @@ get_dbname_oid_list_from_mfile(const char *dumpdirpath, SimpleOidStringList *dbn
1049
1061
if (pfile == NULL )
1050
1062
pg_fatal ("could not open \"%s\": %m" , map_file_path );
1051
1063
1064
+ initStringInfo (& linebuf );
1065
+
1052
1066
/* Append all the dbname/db_oid combinations to the list. */
1053
- while (( fgets ( line , MAXPGPATH , pfile )) != NULL )
1067
+ while (pg_get_line_buf ( pfile , & linebuf ) )
1054
1068
{
1055
1069
Oid db_oid = InvalidOid ;
1056
- char db_oid_str [MAXPGPATH + 1 ] = "" ;
1057
1070
char * dbname ;
1071
+ DbOidName * dbidname ;
1072
+ int namelen ;
1073
+ char * p = linebuf .data ;
1058
1074
1059
1075
/* Extract dboid. */
1060
- sscanf (line , "%u" , & db_oid );
1061
- sscanf (line , "%20s" , db_oid_str );
1076
+ while (isdigit (* p ))
1077
+ p ++ ;
1078
+ if (p > linebuf .data && * p == ' ' )
1079
+ {
1080
+ sscanf (linebuf .data , "%u" , & db_oid );
1081
+ p ++ ;
1082
+ }
1062
1083
1063
1084
/* dbname is the rest of the line */
1064
- dbname = line + strlen (db_oid_str ) + 1 ;
1085
+ dbname = p ;
1086
+ namelen = strlen (dbname );
1065
1087
1066
- /* Remove \n from dbname. */
1067
- dbname [strlen (dbname ) - 1 ] = '\0' ;
1088
+ /* Report error and exit if the file has any corrupted data. */
1089
+ if (!OidIsValid (db_oid ) || namelen <= 1 )
1090
+ pg_fatal ("invalid entry in \"%s\" at line: %d" , map_file_path ,
1091
+ count + 1 );
1068
1092
1069
1093
pg_log_info ("found database \"%s\" (OID: %u) in \"%s\"" ,
1070
1094
dbname , db_oid , map_file_path );
1071
1095
1072
- /* Report error and exit if the file has any corrupted data. */
1073
- if (!OidIsValid (db_oid ) || strlen (dbname ) == 0 )
1074
- pg_fatal ("invalid entry in \"%s\" at line : %d" , map_file_path ,
1075
- count + 1 );
1096
+ dbidname = pg_malloc (offsetof(DbOidName , str ) + namelen + 1 );
1097
+ dbidname -> oid = db_oid ;
1098
+ strlcpy (dbidname -> str , dbname , namelen );
1076
1099
1077
- simple_oid_string_list_append (dbname_oid_list , db_oid , dbname );
1100
+ simple_ptr_list_append (dbname_oid_list , dbidname );
1078
1101
count ++ ;
1079
1102
}
1080
1103
@@ -1100,7 +1123,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
1100
1123
SimpleStringList db_exclude_patterns , RestoreOptions * opts ,
1101
1124
int numWorkers )
1102
1125
{
1103
- SimpleOidStringList dbname_oid_list = {NULL , NULL };
1126
+ SimplePtrList dbname_oid_list = {NULL , NULL };
1104
1127
int num_db_restore = 0 ;
1105
1128
int num_total_db ;
1106
1129
int n_errors_total ;
@@ -1116,7 +1139,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
1116
1139
1117
1140
num_total_db = get_dbname_oid_list_from_mfile (dumpdirpath , & dbname_oid_list );
1118
1141
1119
- /* If map.dat has no entry , return after processing global.dat */
1142
+ /* If map.dat has no entries , return after processing global.dat */
1120
1143
if (dbname_oid_list .head == NULL )
1121
1144
return process_global_sql_commands (conn , dumpdirpath , opts -> filename );
1122
1145
@@ -1164,20 +1187,20 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
1164
1187
pg_log_info ("need to restore %d databases out of %d databases" , num_db_restore , num_total_db );
1165
1188
1166
1189
/*
1167
- * Till now, we made a list of databases, those needs to be restored after
1168
- * skipping names of exclude-database. Now we can launch parallel workers
1169
- * to restore these databases.
1190
+ * We have a list of databases to restore after processing the
1191
+ * exclude-database switch(es). Now we can restore them one by one.
1170
1192
*/
1171
- for (SimpleOidStringListCell * db_cell = dbname_oid_list .head ;
1193
+ for (SimplePtrListCell * db_cell = dbname_oid_list .head ;
1172
1194
db_cell ; db_cell = db_cell -> next )
1173
1195
{
1196
+ DbOidName * dbidname = (DbOidName * ) db_cell -> ptr ;
1174
1197
char subdirpath [MAXPGPATH ];
1175
1198
char subdirdbpath [MAXPGPATH ];
1176
1199
char dbfilename [MAXPGPATH ];
1177
1200
int n_errors ;
1178
1201
1179
1202
/* ignore dbs marked for skipping */
1180
- if (db_cell -> oid == InvalidOid )
1203
+ if (dbidname -> oid == InvalidOid )
1181
1204
continue ;
1182
1205
1183
1206
/*
@@ -1197,27 +1220,27 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
1197
1220
* {oid}.dmp file, use it. Otherwise try to use a directory called
1198
1221
* {oid}
1199
1222
*/
1200
- snprintf (dbfilename , MAXPGPATH , "%u.tar" , db_cell -> oid );
1223
+ snprintf (dbfilename , MAXPGPATH , "%u.tar" , dbidname -> oid );
1201
1224
if (file_exists_in_directory (subdirdbpath , dbfilename ))
1202
- snprintf (subdirpath , MAXPGPATH , "%s/databases/%u.tar" , dumpdirpath , db_cell -> oid );
1225
+ snprintf (subdirpath , MAXPGPATH , "%s/databases/%u.tar" , dumpdirpath , dbidname -> oid );
1203
1226
else
1204
1227
{
1205
- snprintf (dbfilename , MAXPGPATH , "%u.dmp" , db_cell -> oid );
1228
+ snprintf (dbfilename , MAXPGPATH , "%u.dmp" , dbidname -> oid );
1206
1229
1207
1230
if (file_exists_in_directory (subdirdbpath , dbfilename ))
1208
- snprintf (subdirpath , MAXPGPATH , "%s/databases/%u.dmp" , dumpdirpath , db_cell -> oid );
1231
+ snprintf (subdirpath , MAXPGPATH , "%s/databases/%u.dmp" , dumpdirpath , dbidname -> oid );
1209
1232
else
1210
- snprintf (subdirpath , MAXPGPATH , "%s/databases/%u" , dumpdirpath , db_cell -> oid );
1233
+ snprintf (subdirpath , MAXPGPATH , "%s/databases/%u" , dumpdirpath , dbidname -> oid );
1211
1234
}
1212
1235
1213
- pg_log_info ("restoring database \"%s\"" , db_cell -> str );
1236
+ pg_log_info ("restoring database \"%s\"" , dbidname -> str );
1214
1237
1215
1238
/* If database is already created, then don't set createDB flag. */
1216
1239
if (opts -> cparams .dbname )
1217
1240
{
1218
1241
PGconn * test_conn ;
1219
1242
1220
- test_conn = ConnectDatabase (db_cell -> str , NULL , opts -> cparams .pghost ,
1243
+ test_conn = ConnectDatabase (dbidname -> str , NULL , opts -> cparams .pghost ,
1221
1244
opts -> cparams .pgport , opts -> cparams .username , TRI_DEFAULT ,
1222
1245
false, progname , NULL , NULL , NULL , NULL );
1223
1246
if (test_conn )
@@ -1226,7 +1249,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
1226
1249
1227
1250
/* Use already created database for connection. */
1228
1251
opts -> createDB = 0 ;
1229
- opts -> cparams .dbname = db_cell -> str ;
1252
+ opts -> cparams .dbname = dbidname -> str ;
1230
1253
}
1231
1254
else
1232
1255
{
@@ -1251,7 +1274,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
1251
1274
if (n_errors )
1252
1275
{
1253
1276
n_errors_total += n_errors ;
1254
- pg_log_warning ("errors ignored on database \"%s\" restore: %d" , db_cell -> str , n_errors );
1277
+ pg_log_warning ("errors ignored on database \"%s\" restore: %d" , dbidname -> str , n_errors );
1255
1278
}
1256
1279
1257
1280
count ++ ;
@@ -1261,7 +1284,7 @@ restore_all_databases(PGconn *conn, const char *dumpdirpath,
1261
1284
pg_log_info ("number of restored databases is %d" , num_db_restore );
1262
1285
1263
1286
/* Free dbname and dboid list. */
1264
- simple_oid_string_list_destroy (& dbname_oid_list );
1287
+ simple_ptr_list_destroy (& dbname_oid_list );
1265
1288
1266
1289
return n_errors_total ;
1267
1290
}
0 commit comments