Line data Source code
1 : #include "otsdaq/MessageFacility/MessageFacility.h"
2 :
3 : #include <dirent.h>
4 : #include <cassert>
5 : #include <iostream>
6 : #include <map>
7 : #include <memory>
8 : #include <string>
9 :
10 : #include "otsdaq/ConfigurationInterface/ConfigurationInterface.h"
11 : #include "otsdaq/ConfigurationInterface/ConfigurationManagerRW.h"
12 :
13 : // Shared test utilities
14 : #include "otsdaq/Macros/TestUtilities.h"
15 :
16 : /// Updates specific cells in a table by UID and column name, then creates a new version.
17 : /// Optionally assigns a version alias to the newly created version.
18 : ///
19 : /// usage:
20 : /// ots_table_update_cells <tableName> <updates> [--version <version>] [--source-alias <name>] [--alias <aliasName>]
21 : ///
22 : /// where <updates> is a semicolon-separated list of row updates:
23 : /// UID1:col1=val1,col2=val2;UID2:col1=val3
24 : ///
25 : /// options:
26 : /// --version <version> : source version to modify (default: active version)
27 : /// --source-alias <name> : load source version from a version alias
28 : /// --alias <aliasName> : assign a version alias to the newly created version
29 : ///
30 : /// examples:
31 : /// ots_table_update_cells TrackerDTC "dtc0:FirmwareVersion=v3.2,Enabled=1;dtc1:Enabled=0"
32 : /// ots_table_update_cells TrackerDTC "dtc0:FirmwareVersion=v3.2" --version 5
33 : /// ots_table_update_cells TrackerDTC "dtc0:FirmwareVersion=v3.2" --alias MyConfig
34 :
35 : using namespace ots;
36 :
37 : std::map<std::string /*uid*/, std::map<std::string /*colName*/, std::string /*value*/>>
38 0 : parseUpdates(const std::string& updateString)
39 : {
40 0 : std::map<std::string, std::map<std::string, std::string>> updates;
41 :
42 0 : size_t rowStart = 0;
43 0 : while(rowStart < updateString.size())
44 : {
45 0 : size_t rowEnd = updateString.find(';', rowStart);
46 0 : if(rowEnd == std::string::npos)
47 0 : rowEnd = updateString.size();
48 :
49 0 : std::string rowEntry = updateString.substr(rowStart, rowEnd - rowStart);
50 0 : rowStart = rowEnd + 1;
51 :
52 0 : if(rowEntry.empty())
53 0 : continue;
54 :
55 0 : size_t colonPos = rowEntry.find(':');
56 0 : if(colonPos == std::string::npos)
57 : {
58 0 : __SS__ << "Invalid update entry '" << rowEntry
59 0 : << "'. Expected format: UID:col1=val1,col2=val2" << __E__;
60 0 : __SS_THROW__;
61 0 : }
62 :
63 0 : std::string uid = rowEntry.substr(0, colonPos);
64 0 : std::string assignments = rowEntry.substr(colonPos + 1);
65 :
66 0 : size_t assignStart = 0;
67 0 : while(assignStart < assignments.size())
68 : {
69 0 : size_t assignEnd = assignments.find(',', assignStart);
70 0 : if(assignEnd == std::string::npos)
71 0 : assignEnd = assignments.size();
72 :
73 : std::string assignment =
74 0 : assignments.substr(assignStart, assignEnd - assignStart);
75 0 : assignStart = assignEnd + 1;
76 :
77 0 : if(assignment.empty())
78 0 : continue;
79 :
80 0 : size_t eqPos = assignment.find('=');
81 0 : if(eqPos == std::string::npos)
82 : {
83 0 : __SS__ << "Invalid column assignment '" << assignment
84 0 : << "'. Expected format: colName=value" << __E__;
85 0 : __SS_THROW__;
86 0 : }
87 :
88 0 : updates[uid][assignment.substr(0, eqPos)] = assignment.substr(eqPos + 1);
89 0 : }
90 :
91 0 : if(updates[uid].empty())
92 : {
93 0 : __SS__ << "No column assignments found for UID '" << uid << "'." << __E__;
94 0 : __SS_THROW__;
95 0 : }
96 0 : }
97 :
98 0 : return updates;
99 0 : }
100 :
101 0 : void UpdateTableCells(int argc, char* argv[])
102 : {
103 0 : std::cout << "=================================================\n";
104 0 : std::cout << "=================================================\n";
105 0 : std::cout << "=================================================\n";
106 0 : __COUT_INFO__ << "Update Table Cells!" << std::endl;
107 :
108 : std::cout
109 : << "\n\nusage:\n"
110 : << "\t ots_table_update_cells <tableName> <updates> [--version <ver>] [--alias "
111 : "<aliasName>] [--notes <text>]\n\n"
112 : << "\t <updates> format: UID1:col1=val1,col2=val2;UID2:col1=val3\n"
113 : << "\t --version <ver> : source version to modify (default: active "
114 : "version)\n"
115 : << "\t --source-alias <name> : load source version from a version alias\n"
116 : << "\t --alias <alias> : assign version alias to newly created version\n"
117 0 : << "\t --notes <text> : comment/notes to store with the new version\n\n"
118 0 : << std::endl;
119 :
120 0 : std::cout << "argc = " << argc << std::endl;
121 0 : for(int i = 0; i < argc; i++)
122 0 : std::cout << "argv[" << i << "] = " << argv[i] << std::endl;
123 :
124 0 : if(argc < 3)
125 : {
126 : std::cout
127 0 : << "Error! Must provide at least 2 parameters: <tableName> <updates>\n\n"
128 0 : << std::endl;
129 0 : return;
130 : }
131 :
132 : // parse table name (auto-append "Table" suffix if needed)
133 0 : std::string tableName = argv[1];
134 0 : __COUTV__(tableName);
135 0 : auto tablePos = tableName.find("Table");
136 0 : if(tablePos == std::string::npos || tablePos != tableName.size() - strlen("Table"))
137 0 : tableName += "Table";
138 0 : __COUTV__(tableName);
139 :
140 : // parse update string
141 0 : auto cellUpdates = parseUpdates(argv[2]);
142 0 : __COUT_INFO__ << "Parsed " << cellUpdates.size() << " row update(s)." << std::endl;
143 :
144 : // parse optional flags
145 0 : std::string aliasName = "";
146 0 : std::string sourceAlias = "";
147 0 : std::string notes = "";
148 0 : TableVersion sourceVersion; // default = invalid, meaning use active version
149 0 : for(int i = 3; i < argc; i++)
150 : {
151 0 : std::string arg = argv[i];
152 0 : if(arg == "--alias" && i + 1 < argc)
153 : {
154 0 : aliasName = argv[++i];
155 0 : __COUTV__(aliasName);
156 : }
157 0 : else if(arg == "--version" && i + 1 < argc)
158 : {
159 0 : sourceVersion = TableVersion(std::string(argv[++i]));
160 0 : __COUT__ << "Source version: " << sourceVersion << __E__;
161 : }
162 0 : else if(arg == "--source-alias" && i + 1 < argc)
163 : {
164 0 : sourceAlias = argv[++i];
165 0 : __COUTV__(sourceAlias);
166 : }
167 0 : else if(arg == "--notes" && i + 1 < argc)
168 : {
169 0 : notes = argv[++i];
170 0 : __COUTV__(notes);
171 : }
172 : else
173 : {
174 0 : __SS__ << "Unknown option '" << arg
175 : << "'. Expected '--alias <name>', '--version <ver>', "
176 0 : "'--source-alias <name>', or '--notes <text>'."
177 0 : << __E__;
178 0 : __SS_THROW__;
179 0 : }
180 0 : }
181 :
182 : // get kerberos author
183 0 : std::string author = "";
184 : try
185 : {
186 0 : author = __ENV__("OTS_KCACHE_USER");
187 : }
188 0 : catch(...)
189 : {
190 0 : __SS__ << "No valid ots kerberos user found, please kinit and source "
191 0 : "setup_ots.sh or kint_setup.sh."
192 0 : << __E__;
193 0 : __SS_THROW__;
194 0 : }
195 0 : __COUTV__(author);
196 :
197 : //==============================================================================
198 : // initialize configuration manager
199 :
200 0 : __COUT_INFO__ << "Initializing..." << std::endl;
201 :
202 0 : std::string ARTDAQ_DATABASE_URI = __ENV__("ARTDAQ_DATABASE_URI");
203 0 : __COUTV__(ARTDAQ_DATABASE_URI);
204 :
205 0 : ConfigurationManagerRW cfgMgrInst("export_admin");
206 0 : ConfigurationManagerRW* cfgMgr = &cfgMgrInst;
207 :
208 : {
209 0 : std::string accumulatedWarnings;
210 : const std::map<std::string, TableInfo>& allTableInfo =
211 0 : cfgMgr->getAllTableInfo(true /* refresh */,
212 : &accumulatedWarnings,
213 : "" /* errorFilterName */,
214 : false /* getGroupKeys */,
215 : false /* getGroupInfo */,
216 : true /* initializeActiveGroups */);
217 0 : __COUTV__(allTableInfo.size());
218 0 : }
219 :
220 : //==============================================================================
221 : // call the reusable updateTableCells workflow
222 :
223 : TableVersion newVersion = cfgMgr->updateTableCells(
224 0 : tableName, cellUpdates, author, sourceVersion, aliasName, sourceAlias, notes);
225 :
226 0 : __COUT_INFO__ << "Done. New version: " << tableName << "-v" << newVersion
227 0 : << std::endl;
228 :
229 0 : } // end UpdateTableCells()
230 :
231 0 : int main(int argc, char* argv[])
232 : {
233 0 : test::util::check_and_make_envs();
234 :
235 0 : INIT_MF("UpdateTableCells");
236 0 : UpdateTableCells(argc, argv);
237 0 : return 0;
238 : }
|