|
| 1 | +/* |
| 2 | + * src/bin/pgcopydb/config.c |
| 3 | + * Configuration functions for pgcopydb. |
| 4 | + * |
| 5 | + * Licensed under the PostgreSQL License. |
| 6 | + * |
| 7 | + */ |
| 8 | + |
| 9 | +#include <inttypes.h> |
| 10 | +#include <stdbool.h> |
| 11 | +#include <unistd.h> |
| 12 | + |
| 13 | +#include "config.h" |
| 14 | +#include "defaults.h" |
| 15 | +#include "ini_file.h" |
| 16 | +#include "log.h" |
| 17 | +#include "parsing_utils.h" |
| 18 | + |
| 19 | +#define OPTION_PGCOPYDB_DIR(config) \ |
| 20 | + make_strbuf_option("pgcopydb", "dir", "dir", true, MAXCONNINFO, \ |
| 21 | + config->dir) |
| 22 | + |
| 23 | +#define OPTION_PGCOPYDB_SOURCE(config) \ |
| 24 | + make_strbuf_option("pgcopydb", "source", "source", true, MAXCONNINFO, \ |
| 25 | + config->source_pguri) |
| 26 | + |
| 27 | +#define OPTION_PGCOPYDB_TARGET(config) \ |
| 28 | + make_strbuf_option("pgcopydb", "target", "source", true, MAXCONNINFO, \ |
| 29 | + config->target_pguri) |
| 30 | + |
| 31 | +#define OPTION_PGCOPYDB_TABLE_JOBS(config) \ |
| 32 | + make_int_option_default("pgcopydb", "table-jobs", "table-jobs", \ |
| 33 | + true, &(config->tableJobs), \ |
| 34 | + DEFAULT_TABLE_JOBS) |
| 35 | + |
| 36 | +#define OPTION_PGCOPYDB_INDEX_JOBS(config) \ |
| 37 | + make_int_option_default("pgcopydb", "index-jobs", "index-jobs", \ |
| 38 | + true, &(config->indexJobs), \ |
| 39 | + DEFAULT_INDEX_JOBS) |
| 40 | + |
| 41 | +#define SET_INI_OPTIONS_ARRAY(config) \ |
| 42 | + { \ |
| 43 | + OPTION_PGCOPYDB_DIR(config), \ |
| 44 | + OPTION_PGCOPYDB_SOURCE(config), \ |
| 45 | + OPTION_PGCOPYDB_TARGET(config), \ |
| 46 | + OPTION_PGCOPYDB_TABLE_JOBS(config), \ |
| 47 | + OPTION_PGCOPYDB_INDEX_JOBS(config), \ |
| 48 | + INI_OPTION_LAST \ |
| 49 | + } |
| 50 | + |
| 51 | + |
| 52 | +/* |
| 53 | + * config_init initializes a CopyDBOptions with the default values. |
| 54 | + */ |
| 55 | +void |
| 56 | +config_init(CopyDBOptions *config) |
| 57 | +{ |
| 58 | + IniOption options[] = SET_INI_OPTIONS_ARRAY(config); |
| 59 | + |
| 60 | + log_trace("config_init"); |
| 61 | + |
| 62 | + if (!ini_validate_options(options)) |
| 63 | + { |
| 64 | + log_error("Please review your setup options per above messages"); |
| 65 | + exit(EXIT_CODE_BAD_CONFIG); |
| 66 | + } |
| 67 | +} |
| 68 | + |
| 69 | + |
| 70 | +/* |
| 71 | + * config_read_file overrides values in given CopyDBOptions with whatever |
| 72 | + * values are read from given configuration filename. |
| 73 | + */ |
| 74 | +bool |
| 75 | +config_read_file(CopyDBOptions *config, const char *filename) |
| 76 | +{ |
| 77 | + IniOption options[] = SET_INI_OPTIONS_ARRAY(config); |
| 78 | + |
| 79 | + log_debug("Reading configuration from %s", filename); |
| 80 | + |
| 81 | + if (!read_ini_file(filename, options)) |
| 82 | + { |
| 83 | + log_error("Failed to parse configuration file \"%s\"", filename); |
| 84 | + return false; |
| 85 | + } |
| 86 | + |
| 87 | + return true; |
| 88 | +} |
| 89 | + |
| 90 | + |
| 91 | +/* |
| 92 | + * config_write_file writes the current values in given CopyDBOptions to |
| 93 | + * filename. |
| 94 | + */ |
| 95 | +bool |
| 96 | +config_write_file(CopyDBOptions *config, const char *filename) |
| 97 | +{ |
| 98 | + log_trace("config_write_file \"%s\"", filename); |
| 99 | + |
| 100 | + FILE *fileStream = fopen_with_umask(filename, "w", FOPEN_FLAGS_W, 0644); |
| 101 | + if (fileStream == NULL) |
| 102 | + { |
| 103 | + /* errors have already been logged */ |
| 104 | + return false; |
| 105 | + } |
| 106 | + |
| 107 | + bool success = config_write(fileStream, config); |
| 108 | + |
| 109 | + if (fclose(fileStream) == EOF) |
| 110 | + { |
| 111 | + log_error("Failed to write file \"%s\"", filename); |
| 112 | + return false; |
| 113 | + } |
| 114 | + |
| 115 | + return success; |
| 116 | +} |
| 117 | + |
| 118 | + |
| 119 | +/* |
| 120 | + * config_write write the current config to given STREAM. |
| 121 | + */ |
| 122 | +bool |
| 123 | +config_write(FILE *stream, CopyDBOptions *config) |
| 124 | +{ |
| 125 | + IniOption options[] = SET_INI_OPTIONS_ARRAY(config); |
| 126 | + |
| 127 | + return write_ini_to_stream(stream, options); |
| 128 | +} |
| 129 | + |
| 130 | + |
| 131 | +/* |
| 132 | + * config_to_json populates given jsRoot object with the INI configuration |
| 133 | + * sections as JSON objects, and the options as keys to those objects. |
| 134 | + */ |
| 135 | +bool |
| 136 | +config_to_json(CopyDBOptions *config, JSON_Value *js) |
| 137 | +{ |
| 138 | + JSON_Object *jsRoot = json_value_get_object(js); |
| 139 | + IniOption options[] = SET_INI_OPTIONS_ARRAY(config); |
| 140 | + |
| 141 | + return ini_to_json(jsRoot, options); |
| 142 | +} |
| 143 | + |
| 144 | + |
| 145 | +/* |
| 146 | + * config_log_settings outputs a DEBUG line per each config parameter in the |
| 147 | + * given CopyDBOptions. |
| 148 | + */ |
| 149 | +void |
| 150 | +config_log_settings(CopyDBOptions *config) |
| 151 | +{ |
| 152 | + log_debug("pgcopydb.dir: %s", config->dir); |
| 153 | + log_debug("pgcopydb.source_pguri: %s", config->source_pguri); |
| 154 | + log_debug("pgcopydb.target_pguri: %s", config->target_pguri); |
| 155 | + |
| 156 | + log_debug("pgcopydb.table-jobs: %d", config->tableJobs); |
| 157 | + log_debug("pgcopydb.index-jobs: %d", config->indexJobs); |
| 158 | +} |
| 159 | + |
| 160 | + |
| 161 | +/* |
| 162 | + * config_get_setting returns the current value of the given option "path" |
| 163 | + * (thats a section.option string). The value is returned in the pre-allocated |
| 164 | + * value buffer of size size. |
| 165 | + */ |
| 166 | +bool |
| 167 | +config_get_setting(CopyDBOptions *config, |
| 168 | + const char *filename, |
| 169 | + const char *path, |
| 170 | + char *value, size_t size) |
| 171 | +{ |
| 172 | + IniOption options[] = SET_INI_OPTIONS_ARRAY(config); |
| 173 | + |
| 174 | + return ini_get_setting(filename, options, path, value, size); |
| 175 | +} |
| 176 | + |
| 177 | + |
| 178 | +/* |
| 179 | + * config_set_setting sets the setting identified by "path" (section.option) to |
| 180 | + * the given value. The value is passed in as a string, which is going to be |
| 181 | + * parsed if necessary. |
| 182 | + */ |
| 183 | +bool |
| 184 | +config_set_setting(CopyDBOptions *config, |
| 185 | + const char *filename, |
| 186 | + const char *path, |
| 187 | + char *value) |
| 188 | +{ |
| 189 | + IniOption options[] = SET_INI_OPTIONS_ARRAY(config); |
| 190 | + |
| 191 | + log_trace("config_set_setting: %s = %s", path, value); |
| 192 | + |
| 193 | + if (!ini_set_setting(filename, options, path, value)) |
| 194 | + { |
| 195 | + /* errors have already been logged */ |
| 196 | + return false; |
| 197 | + } |
| 198 | + |
| 199 | + return true; |
| 200 | +} |
| 201 | + |
| 202 | + |
| 203 | +/* |
| 204 | + * config_merge_options merges any option setup in options into config. Its |
| 205 | + * main use is to override configuration file settings with command line |
| 206 | + * options. |
| 207 | + */ |
| 208 | +bool |
| 209 | +config_merge_options(CopyDBOptions *config, CopyDBOptions *options, |
| 210 | + const char *filename) |
| 211 | +{ |
| 212 | + IniOption configOptions[] = SET_INI_OPTIONS_ARRAY(config); |
| 213 | + IniOption optionsOptions[] = SET_INI_OPTIONS_ARRAY(options); |
| 214 | + |
| 215 | + log_trace("config_merge_options"); |
| 216 | + |
| 217 | + if (ini_merge(configOptions, optionsOptions)) |
| 218 | + { |
| 219 | + return config_write_file(config, filename); |
| 220 | + } |
| 221 | + |
| 222 | + return false; |
| 223 | +} |
0 commit comments