RdbmsCatalogue.cpp 186 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * The CERN Tape Archive (CTA) project
 * Copyright (C) 2015  CERN
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

19
#include "catalogue/ArchiveFileRow.hpp"
20
#include "catalogue/RdbmsArchiveFileItorImpl.hpp"
21
#include "catalogue/RdbmsCatalogue.hpp"
22
#include "catalogue/retryOnLostConnection.hpp"
23
#include "catalogue/SqliteCatalogueSchema.hpp"
24
#include "common/dataStructures/TapeFile.hpp"
25
#include "common/exception/Exception.hpp"
26
#include "common/exception/UserError.hpp"
27
#include "common/make_unique.hpp"
28
#include "common/threading/MutexLocker.hpp"
29
#include "common/Timer.hpp"
30
#include "common/utils/utils.hpp"
31
#include "rdbms/AutoRollback.hpp"
32

33
#include <ctype.h>
34
35
#include <memory>
#include <time.h>
36
#include <common/exception/LostDatabaseConnection.hpp>
37

38
39
40
namespace cta {
namespace catalogue {

41
42
43
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
44
RdbmsCatalogue::RdbmsCatalogue(
45
  log::Logger &log,
46
  const rdbms::Login &login,
47
  const uint64_t nbConns,
48
49
  const uint64_t nbArchiveFileListingConns,
  const uint32_t maxTriesToConnect):
50
  m_log(log),
51
  m_connPool(login, nbConns),
52
  m_archiveFileListingConnPool(login, nbArchiveFileListingConns),
Steven Murray's avatar
Steven Murray committed
53
54
55
56
  m_maxTriesToConnect(maxTriesToConnect),
  m_tapeCopyToPoolCache(10),
  m_groupMountPolicyCache(10),
  m_userMountPolicyCache(10),
57
58
  m_expectedNbArchiveRoutesCache(10),
  m_isAdminCache(10) {
59
60
61
62
63
}

//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
64
RdbmsCatalogue::~RdbmsCatalogue() {
65
66
67
68
69
}

//------------------------------------------------------------------------------
// createAdminUser
//------------------------------------------------------------------------------
70
void RdbmsCatalogue::createAdminUser(
Steven Murray's avatar
Steven Murray committed
71
  const common::dataStructures::SecurityIdentity &admin,
72
  const std::string &username,
73
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
74
  try {
75
    auto conn = m_connPool.getConn();
76
    if (adminUserExists(conn, username)) {
77
      throw exception::UserError(std::string("Cannot create admin user " + username +
78
79
        " because an admin user with the same name already exists"));
    }
80
    const uint64_t now = time(nullptr);
Steven Murray's avatar
Steven Murray committed
81
82
83
84
85
86
87
88
89
90
91
92
93
    const char *const sql =
      "INSERT INTO ADMIN_USER("
        "ADMIN_USER_NAME,"

        "USER_COMMENT,"

        "CREATION_LOG_USER_NAME,"
        "CREATION_LOG_HOST_NAME,"
        "CREATION_LOG_TIME,"

        "LAST_UPDATE_USER_NAME,"
        "LAST_UPDATE_HOST_NAME,"
        "LAST_UPDATE_TIME)"
94
      "VALUES("
Steven Murray's avatar
Steven Murray committed
95
96
97
98
99
100
101
102
        ":ADMIN_USER_NAME,"

        ":USER_COMMENT,"

        ":CREATION_LOG_USER_NAME,"
        ":CREATION_LOG_HOST_NAME,"
        ":CREATION_LOG_TIME,"

103
104
105
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
106
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::ON);
Steven Murray's avatar
Steven Murray committed
107

108
    stmt.bindString(":ADMIN_USER_NAME", username);
Steven Murray's avatar
Steven Murray committed
109

110
    stmt.bindString(":USER_COMMENT", comment);
Steven Murray's avatar
Steven Murray committed
111

112
113
114
    stmt.bindString(":CREATION_LOG_USER_NAME", admin.username);
    stmt.bindString(":CREATION_LOG_HOST_NAME", admin.host);
    stmt.bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
115

116
117
118
    stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
    stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
    stmt.bindUint64(":LAST_UPDATE_TIME", now);
119

120
    stmt.executeNonQuery();
121
122
123
124
  } catch(exception::UserError &) {
    throw;
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
125
126
127
128
129
130
131
    throw;
  }
}

//------------------------------------------------------------------------------
// adminUserExists
//------------------------------------------------------------------------------
132
bool RdbmsCatalogue::adminUserExists(rdbms::Conn &conn, const std::string adminUsername) const {
133
134
135
136
137
138
139
  try {
    const char *const sql =
      "SELECT "
        "ADMIN_USER_NAME AS ADMIN_USER_NAME "
      "FROM "
        "ADMIN_USER "
      "WHERE "
140
        "ADMIN_USER_NAME = :ADMIN_USER_NAME";
141
142
143
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindString(":ADMIN_USER_NAME", adminUsername);
    auto rset = stmt.executeQuery();
144
    return rset.next();
145
146
  } catch(exception::UserError &) {
    throw;
147
148
149
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
Steven Murray's avatar
Steven Murray committed
150
  }
151
152
153
154
155
}

//------------------------------------------------------------------------------
// deleteAdminUser
//------------------------------------------------------------------------------
156
void RdbmsCatalogue::deleteAdminUser(const std::string &username) {
157
  try {
158
    const char *const sql = "DELETE FROM ADMIN_USER WHERE ADMIN_USER_NAME = :ADMIN_USER_NAME";
159
    auto conn = m_connPool.getConn();
160
161
162
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::ON);
    stmt.bindString(":ADMIN_USER_NAME", username);
    stmt.executeNonQuery();
163

164
    if(0 == stmt.getNbAffectedRows()) {
165
      throw exception::UserError(std::string("Cannot delete admin-user ") + username + " because they do not exist");
166
    }
167
168
169
170
  } catch(exception::UserError &) {
    throw;
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
171
172
    throw;
  }
Steven Murray's avatar
Steven Murray committed
173
}
174
175
176
177

//------------------------------------------------------------------------------
// getAdminUsers
//------------------------------------------------------------------------------
178
std::list<common::dataStructures::AdminUser> RdbmsCatalogue::getAdminUsers() const {
Steven Murray's avatar
Steven Murray committed
179
180
181
182
183
  try {
    std::list<common::dataStructures::AdminUser> admins;
    const char *const sql =
      "SELECT "
        "ADMIN_USER_NAME AS ADMIN_USER_NAME,"
184

Steven Murray's avatar
Steven Murray committed
185
        "USER_COMMENT AS USER_COMMENT,"
186

187
188
189
        "CREATION_LOG_USER_NAME AS CREATION_LOG_USER_NAME,"
        "CREATION_LOG_HOST_NAME AS CREATION_LOG_HOST_NAME,"
        "CREATION_LOG_TIME AS CREATION_LOG_TIME,"
190

191
192
193
        "LAST_UPDATE_USER_NAME AS LAST_UPDATE_USER_NAME,"
        "LAST_UPDATE_HOST_NAME AS LAST_UPDATE_HOST_NAME,"
        "LAST_UPDATE_TIME AS LAST_UPDATE_TIME "
194
      "FROM "
195
196
197
        "ADMIN_USER "
      "ORDER BY "
        "ADMIN_USER_NAME";
198
    auto conn = m_connPool.getConn();
199
200
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    auto rset = stmt.executeQuery();
201
    while (rset.next()) {
Steven Murray's avatar
Steven Murray committed
202
      common::dataStructures::AdminUser admin;
203

204
205
206
207
208
209
210
211
      admin.name = rset.columnString("ADMIN_USER_NAME");
      admin.comment = rset.columnString("USER_COMMENT");
      admin.creationLog.username = rset.columnString("CREATION_LOG_USER_NAME");
      admin.creationLog.host = rset.columnString("CREATION_LOG_HOST_NAME");
      admin.creationLog.time = rset.columnUint64("CREATION_LOG_TIME");
      admin.lastModificationLog.username = rset.columnString("LAST_UPDATE_USER_NAME");
      admin.lastModificationLog.host = rset.columnString("LAST_UPDATE_HOST_NAME");
      admin.lastModificationLog.time = rset.columnUint64("LAST_UPDATE_TIME");
212

Steven Murray's avatar
Steven Murray committed
213
214
      admins.push_back(admin);
    }
215

Steven Murray's avatar
Steven Murray committed
216
    return admins;
217
218
  } catch(exception::UserError &) {
    throw;
219
220
221
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
Steven Murray's avatar
Steven Murray committed
222
  }
223
224
225
226
227
}

//------------------------------------------------------------------------------
// modifyAdminUserComment
//------------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
228
void RdbmsCatalogue::modifyAdminUserComment(const common::dataStructures::SecurityIdentity &admin,
229
230
231
232
233
234
235
236
237
  const std::string &username, const std::string &comment) {
  try {
    const time_t now = time(nullptr);
    const char *const sql =
      "UPDATE ADMIN_USER SET "
        "USER_COMMENT = :USER_COMMENT,"
        "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME,"
        "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME,"
        "LAST_UPDATE_TIME = :LAST_UPDATE_TIME "
238
      "WHERE "
239
240
        "ADMIN_USER_NAME = :ADMIN_USER_NAME";
    auto conn = m_connPool.getConn();
241
242
243
244
245
246
247
248
249
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::ON);
    stmt.bindString(":USER_COMMENT", comment);
    stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
    stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
    stmt.bindUint64(":LAST_UPDATE_TIME", now);
    stmt.bindString(":ADMIN_USER_NAME", username);
    stmt.executeNonQuery();

    if(0 == stmt.getNbAffectedRows()) {
250
251
252
253
      throw exception::UserError(std::string("Cannot modify admin user ") + username + " because they do not exist");
    }
  } catch(exception::UserError &) {
    throw;
254
255
256
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
257
  }
Steven Murray's avatar
Steven Murray committed
258
}
259
260
261
262

//------------------------------------------------------------------------------
// createStorageClass
//------------------------------------------------------------------------------
263
void RdbmsCatalogue::createStorageClass(
Steven Murray's avatar
Steven Murray committed
264
  const common::dataStructures::SecurityIdentity &admin,
265
  const common::dataStructures::StorageClass &storageClass) {
Steven Murray's avatar
Steven Murray committed
266
  try {
267
    auto conn = m_connPool.getConn();
268
    if(storageClassExists(conn, storageClass.diskInstance, storageClass.name)) {
269
270
      throw exception::UserError(std::string("Cannot create storage class ") + storageClass.diskInstance + ":" +
        storageClass.name + " because it already exists");
271
    }
272
    const uint64_t storageClassId = getNextStorageClassId(conn);
273
    const time_t now = time(nullptr);
Steven Murray's avatar
Steven Murray committed
274
275
    const char *const sql =
      "INSERT INTO STORAGE_CLASS("
276
        "STORAGE_CLASS_ID,"
277
        "DISK_INSTANCE_NAME,"
Steven Murray's avatar
Steven Murray committed
278
279
280
281
282
283
284
285
286
287
288
289
        "STORAGE_CLASS_NAME,"
        "NB_COPIES,"

        "USER_COMMENT,"

        "CREATION_LOG_USER_NAME,"
        "CREATION_LOG_HOST_NAME,"
        "CREATION_LOG_TIME,"

        "LAST_UPDATE_USER_NAME,"
        "LAST_UPDATE_HOST_NAME,"
        "LAST_UPDATE_TIME)"
290
      "VALUES("
291
        ":STORAGE_CLASS_ID,"
292
        ":DISK_INSTANCE_NAME,"
Steven Murray's avatar
Steven Murray committed
293
294
295
296
297
298
299
300
301
        ":STORAGE_CLASS_NAME,"
        ":NB_COPIES,"

        ":USER_COMMENT,"

        ":CREATION_LOG_USER_NAME,"
        ":CREATION_LOG_HOST_NAME,"
        ":CREATION_LOG_TIME,"

302
303
304
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
305
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::ON);
Steven Murray's avatar
Steven Murray committed
306

307
    stmt.bindUint64(":STORAGE_CLASS_ID", storageClassId);
308
309
310
    stmt.bindString(":DISK_INSTANCE_NAME", storageClass.diskInstance);
    stmt.bindString(":STORAGE_CLASS_NAME", storageClass.name);
    stmt.bindUint64(":NB_COPIES", storageClass.nbCopies);
Steven Murray's avatar
Steven Murray committed
311

312
    stmt.bindString(":USER_COMMENT", storageClass.comment);
Steven Murray's avatar
Steven Murray committed
313

314
315
316
    stmt.bindString(":CREATION_LOG_USER_NAME", admin.username);
    stmt.bindString(":CREATION_LOG_HOST_NAME", admin.host);
    stmt.bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
317

318
319
320
    stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
    stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
    stmt.bindUint64(":LAST_UPDATE_TIME", now);
321

322
    stmt.executeNonQuery();
323
  } catch(exception::UserError &) {
324
    throw;
325
326
327
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
328
329
330
331
332
333
  }
}

//------------------------------------------------------------------------------
// storageClassExists
//------------------------------------------------------------------------------
334
bool RdbmsCatalogue::storageClassExists(rdbms::Conn &conn, const std::string &diskInstanceName,
335
  const std::string &storageClassName) const {
336
337
338
  try {
    const char *const sql =
      "SELECT "
339
        "DISK_INSTANCE_NAME AS DISK_INSTANCE_NAME, "
340
341
342
343
        "STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME "
      "FROM "
        "STORAGE_CLASS "
      "WHERE "
344
        "DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
345
        "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME";
346
347
348
349
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindString(":DISK_INSTANCE_NAME", diskInstanceName);
    stmt.bindString(":STORAGE_CLASS_NAME", storageClassName);
    auto rset = stmt.executeQuery();
350
    return rset.next();
351
352
  } catch(exception::UserError &) {
    throw;
353
354
355
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
Steven Murray's avatar
Steven Murray committed
356
  }
357
358
359
360
361
}

//------------------------------------------------------------------------------
// deleteStorageClass
//------------------------------------------------------------------------------
362
void RdbmsCatalogue::deleteStorageClass(const std::string &diskInstanceName, const std::string &storageClassName) {
363
364
365
366
367
  try {
    const char *const sql =
      "DELETE FROM "
        "STORAGE_CLASS "
      "WHERE "
368
        "DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
369
        "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME";
370
    auto conn = m_connPool.getConn();
371
    auto stmt = conn.createStmt(sql,rdbms::AutocommitMode::ON);
372

373
374
    stmt.bindString(":DISK_INSTANCE_NAME", diskInstanceName);
    stmt.bindString(":STORAGE_CLASS_NAME", storageClassName);
375

376
377
    stmt.executeNonQuery();
    if(0 == stmt.getNbAffectedRows()) {
378
379
      throw exception::UserError(std::string("Cannot delete storage-class ") + diskInstanceName + ":" +
        storageClassName + " because it does not exist");
380
    }
381
  } catch(exception::UserError &) {
382
    throw;
383
384
385
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
386
  }
Steven Murray's avatar
Steven Murray committed
387
}
388
389
390
391

//------------------------------------------------------------------------------
// getStorageClasses
//------------------------------------------------------------------------------
392
std::list<common::dataStructures::StorageClass> RdbmsCatalogue::getStorageClasses() const {
Steven Murray's avatar
Steven Murray committed
393
394
395
396
  try {
    std::list<common::dataStructures::StorageClass> storageClasses;
    const char *const sql =
      "SELECT "
397
        "DISK_INSTANCE_NAME AS DISK_INSTANCE_NAME,"
Steven Murray's avatar
Steven Murray committed
398
        "STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME,"
399
        "NB_COPIES AS NB_COPIES,"
Steven Murray's avatar
Steven Murray committed
400
401
402

        "USER_COMMENT AS USER_COMMENT,"

403
404
405
        "CREATION_LOG_USER_NAME AS CREATION_LOG_USER_NAME,"
        "CREATION_LOG_HOST_NAME AS CREATION_LOG_HOST_NAME,"
        "CREATION_LOG_TIME AS CREATION_LOG_TIME,"
Steven Murray's avatar
Steven Murray committed
406

407
408
409
        "LAST_UPDATE_USER_NAME AS LAST_UPDATE_USER_NAME,"
        "LAST_UPDATE_HOST_NAME AS LAST_UPDATE_HOST_NAME,"
        "LAST_UPDATE_TIME AS LAST_UPDATE_TIME "
410
      "FROM "
411
412
413
        "STORAGE_CLASS "
      "ORDER BY "
        "DISK_INSTANCE_NAME, STORAGE_CLASS_NAME";
414
    auto conn = m_connPool.getConn();
415
416
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    auto rset = stmt.executeQuery();
417
    while (rset.next()) {
Steven Murray's avatar
Steven Murray committed
418
419
      common::dataStructures::StorageClass storageClass;

420
421
422
423
424
425
426
427
428
429
      storageClass.diskInstance = rset.columnString("DISK_INSTANCE_NAME");
      storageClass.name = rset.columnString("STORAGE_CLASS_NAME");
      storageClass.nbCopies = rset.columnUint64("NB_COPIES");
      storageClass.comment = rset.columnString("USER_COMMENT");
      storageClass.creationLog.username = rset.columnString("CREATION_LOG_USER_NAME");
      storageClass.creationLog.host = rset.columnString("CREATION_LOG_HOST_NAME");
      storageClass.creationLog.time = rset.columnUint64("CREATION_LOG_TIME");
      storageClass.lastModificationLog.username = rset.columnString("LAST_UPDATE_USER_NAME");
      storageClass.lastModificationLog.host = rset.columnString("LAST_UPDATE_HOST_NAME");
      storageClass.lastModificationLog.time = rset.columnUint64("LAST_UPDATE_TIME");
Steven Murray's avatar
Steven Murray committed
430
431

      storageClasses.push_back(storageClass);
432
433
    }

Steven Murray's avatar
Steven Murray committed
434
    return storageClasses;
435
436
  } catch(exception::UserError &) {
    throw;
437
438
439
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
440
441
442
443
444
445
  }
}

//------------------------------------------------------------------------------
// modifyStorageClassNbCopies
//------------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
446
void RdbmsCatalogue::modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &admin,
447
448
449
450
451
452
453
454
455
  const std::string &instanceName, const std::string &name, const uint64_t nbCopies) {
  try {
    const time_t now = time(nullptr);
    const char *const sql =
      "UPDATE STORAGE_CLASS SET "
        "NB_COPIES = :NB_COPIES,"
        "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME,"
        "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME,"
        "LAST_UPDATE_TIME = :LAST_UPDATE_TIME "
456
      "WHERE "
457
458
459
        "DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
        "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME";
    auto conn = m_connPool.getConn();
460
461
462
463
464
465
466
467
468
469
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::ON);
    stmt.bindUint64(":NB_COPIES", nbCopies);
    stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
    stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
    stmt.bindUint64(":LAST_UPDATE_TIME", now);
    stmt.bindString(":DISK_INSTANCE_NAME", instanceName);
    stmt.bindString(":STORAGE_CLASS_NAME", name);
    stmt.executeNonQuery();

    if(0 == stmt.getNbAffectedRows()) {
470
471
472
473
474
      throw exception::UserError(std::string("Cannot modify storage class ") + instanceName + ":" + name +
        " because it does not exist");
    }
  } catch(exception::UserError &) {
    throw;
475
476
477
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
478
  }
Steven Murray's avatar
Steven Murray committed
479
}
480
481
482
483

//------------------------------------------------------------------------------
// modifyStorageClassComment
//------------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
484
void RdbmsCatalogue::modifyStorageClassComment(const common::dataStructures::SecurityIdentity &admin,
485
486
487
488
489
490
491
492
493
  const std::string &instanceName, const std::string &name, const std::string &comment) {
  try {
    const time_t now = time(nullptr);
    const char *const sql =
      "UPDATE STORAGE_CLASS SET "
        "USER_COMMENT = :USER_COMMENT,"
        "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME,"
        "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME,"
        "LAST_UPDATE_TIME = :LAST_UPDATE_TIME "
494
      "WHERE "
495
496
497
        "DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
        "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME";
    auto conn = m_connPool.getConn();
498
499
500
501
502
503
504
505
506
507
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::ON);
    stmt.bindString(":USER_COMMENT", comment);
    stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
    stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
    stmt.bindUint64(":LAST_UPDATE_TIME", now);
    stmt.bindString(":DISK_INSTANCE_NAME", instanceName);
    stmt.bindString(":STORAGE_CLASS_NAME", name);
    stmt.executeNonQuery();

    if(0 == stmt.getNbAffectedRows()) {
508
509
510
511
512
      throw exception::UserError(std::string("Cannot modify storage class ") + instanceName + ":" + name +
        " because it does not exist");
    }
  } catch(exception::UserError &) {
    throw;
513
514
515
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
516
  }
Steven Murray's avatar
Steven Murray committed
517
}
518
519
520
521

//------------------------------------------------------------------------------
// createTapePool
//------------------------------------------------------------------------------
522
void RdbmsCatalogue::createTapePool(
Steven Murray's avatar
Steven Murray committed
523
  const common::dataStructures::SecurityIdentity &admin,
524
525
526
527
  const std::string &name,
  const uint64_t nbPartialTapes,
  const bool encryptionValue,
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
528
  try {
529
    auto conn = m_connPool.getConn();
530

531
    if(tapePoolExists(conn, name)) {
532
      throw exception::UserError(std::string("Cannot create tape pool ") + name +
533
534
        " because a tape pool with the same name already exists");
    }
535
    const time_t now = time(nullptr);
Steven Murray's avatar
Steven Murray committed
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
    const char *const sql =
      "INSERT INTO TAPE_POOL("
        "TAPE_POOL_NAME,"
        "NB_PARTIAL_TAPES,"
        "IS_ENCRYPTED,"

        "USER_COMMENT,"

        "CREATION_LOG_USER_NAME,"
        "CREATION_LOG_HOST_NAME,"
        "CREATION_LOG_TIME,"

        "LAST_UPDATE_USER_NAME,"
        "LAST_UPDATE_HOST_NAME,"
        "LAST_UPDATE_TIME)"
551
      "VALUES("
Steven Murray's avatar
Steven Murray committed
552
553
554
555
556
557
558
559
560
561
        ":TAPE_POOL_NAME,"
        ":NB_PARTIAL_TAPES,"
        ":IS_ENCRYPTED,"

        ":USER_COMMENT,"

        ":CREATION_LOG_USER_NAME,"
        ":CREATION_LOG_HOST_NAME,"
        ":CREATION_LOG_TIME,"

562
563
564
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
565
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::ON);
Steven Murray's avatar
Steven Murray committed
566

567
568
569
    stmt.bindString(":TAPE_POOL_NAME", name);
    stmt.bindUint64(":NB_PARTIAL_TAPES", nbPartialTapes);
    stmt.bindBool(":IS_ENCRYPTED", encryptionValue);
Steven Murray's avatar
Steven Murray committed
570

571
    stmt.bindString(":USER_COMMENT", comment);
Steven Murray's avatar
Steven Murray committed
572

573
574
575
    stmt.bindString(":CREATION_LOG_USER_NAME", admin.username);
    stmt.bindString(":CREATION_LOG_HOST_NAME", admin.host);
    stmt.bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
576

577
578
579
    stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
    stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
    stmt.bindUint64(":LAST_UPDATE_TIME", now);
580

581
    stmt.executeNonQuery();
582
  } catch(exception::UserError &) {
583
    throw;
584
585
586
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
587
588
589
590
591
592
593
594
595
596
  }
}

//------------------------------------------------------------------------------
// tapePoolExists
//------------------------------------------------------------------------------
bool RdbmsCatalogue::tapePoolExists(const std::string &tapePoolName) const {
  try {
    auto conn = m_connPool.getConn();
    return tapePoolExists(conn, tapePoolName);
597
598
  } catch(exception::UserError &) {
    throw;
599
600
601
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
Steven Murray's avatar
Steven Murray committed
602
  }
603
604
}

605
606
607
//------------------------------------------------------------------------------
// tapePoolExists
//------------------------------------------------------------------------------
608
bool RdbmsCatalogue::tapePoolExists(rdbms::Conn &conn, const std::string &tapePoolName) const {
609
610
611
612
613
614
615
  try {
    const char *const sql =
      "SELECT "
        "TAPE_POOL_NAME AS TAPE_POOL_NAME "
      "FROM "
        "TAPE_POOL "
      "WHERE "
616
        "TAPE_POOL_NAME = :TAPE_POOL_NAME";
617
618
619
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindString(":TAPE_POOL_NAME", tapePoolName);
    auto rset = stmt.executeQuery();
620
    return rset.next();
621
622
  } catch(exception::UserError &) {
    throw;
623
624
625
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
626
627
628
  }
}

629
630
631
//------------------------------------------------------------------------------
// archiveFileExists
//------------------------------------------------------------------------------
632
bool RdbmsCatalogue::archiveFileIdExists(rdbms::Conn &conn, const uint64_t archiveFileId) const {
633
634
635
636
637
638
639
640
  try {
    const char *const sql =
      "SELECT "
        "ARCHIVE_FILE_ID AS ARCHIVE_FILE_ID "
      "FROM "
        "ARCHIVE_FILE "
      "WHERE "
        "ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID";
641
642
643
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindUint64(":ARCHIVE_FILE_ID", archiveFileId);
    auto rset = stmt.executeQuery();
644
    return rset.next();
645
646
  } catch(exception::UserError &) {
    throw;
647
648
649
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
650
651
652
  }
}

653
654
655
//------------------------------------------------------------------------------
// diskFileIdExists
//------------------------------------------------------------------------------
656
bool RdbmsCatalogue::diskFileIdExists(rdbms::Conn &conn, const std::string &diskInstanceName,
657
658
659
660
661
662
663
664
665
666
667
  const std::string &diskFileId) const {
  try {
    const char *const sql =
      "SELECT "
        "DISK_INSTANCE_NAME AS DISK_INSTANCE_NAME, "
        "DISK_FILE_ID AS DISK_FILE_ID "
      "FROM "
        "ARCHIVE_FILE "
      "WHERE "
        "DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
        "DISK_FILE_ID = :DISK_FILE_ID";
668
669
670
671
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindString(":DISK_INSTANCE_NAME", diskInstanceName);
    stmt.bindString(":DISK_FILE_ID", diskFileId);
    auto rset = stmt.executeQuery();
672
    return rset.next();
673
674
  } catch(exception::UserError &) {
    throw;
675
676
677
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
678
679
680
  }
}

681
682
683
//------------------------------------------------------------------------------
// diskFilePathExists
//------------------------------------------------------------------------------
684
bool RdbmsCatalogue::diskFilePathExists(rdbms::Conn &conn, const std::string &diskInstanceName,
685
686
687
688
689
690
691
692
693
694
695
  const std::string &diskFilePath) const {
  try {
    const char *const sql =
      "SELECT "
        "DISK_INSTANCE_NAME AS DISK_INSTANCE_NAME, "
        "DISK_FILE_PATH AS DISK_FILE_PATH "
      "FROM "
        "ARCHIVE_FILE "
      "WHERE "
        "DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
        "DISK_FILE_PATH = :DISK_FILE_PATH";
696
697
698
699
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindString(":DISK_INSTANCE_NAME", diskInstanceName);
    stmt.bindString(":DISK_FILE_PATH", diskFilePath);
    auto rset = stmt.executeQuery();
700
    return rset.next();
701
702
  } catch(exception::UserError &) {
    throw;
703
704
705
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
706
707
708
  }
}

709
710
711
//------------------------------------------------------------------------------
// diskFileUserExists
//------------------------------------------------------------------------------
712
bool RdbmsCatalogue::diskFileUserExists(rdbms::Conn &conn, const std::string &diskInstanceName,
713
714
715
716
717
718
719
720
721
722
723
  const std::string &diskFileUser) const {
  try {
    const char *const sql =
      "SELECT "
        "DISK_INSTANCE_NAME AS DISK_INSTANCE_NAME, "
        "DISK_FILE_USER AS DISK_FILE_USER "
      "FROM "
        "ARCHIVE_FILE "
      "WHERE "
        "DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
        "DISK_FILE_USER = :DISK_FILE_USER";
724
725
726
727
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindString(":DISK_INSTANCE_NAME", diskInstanceName);
    stmt.bindString(":DISK_FILE_USER", diskFileUser);
    auto rset = stmt.executeQuery();
728
    return rset.next();
729
730
  } catch(exception::UserError &) {
    throw;
731
732
733
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
734
735
736
  }
}

737
738
739
//------------------------------------------------------------------------------
// diskFileGroupExists
//------------------------------------------------------------------------------
740
bool RdbmsCatalogue::diskFileGroupExists(rdbms::Conn &conn, const std::string &diskInstanceName,
741
742
743
744
745
746
747
748
749
750
751
  const std::string &diskFileGroup) const {
  try {
    const char *const sql =
      "SELECT "
        "DISK_INSTANCE_NAME AS DISK_INSTANCE_NAME, "
        "DISK_FILE_GROUP AS DISK_FILE_GROUP "
      "FROM "
        "ARCHIVE_FILE "
      "WHERE "
        "DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
        "DISK_FILE_GROUP = :DISK_FILE_GROUP";
752
753
754
755
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindString(":DISK_INSTANCE_NAME", diskInstanceName);
    stmt.bindString(":DISK_FILE_GROUP", diskFileGroup);
    auto rset = stmt.executeQuery();
756
    return rset.next();
757
758
  } catch(exception::UserError &) {
    throw;
759
760
761
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
762
763
764
  }
}

765
766
767
//------------------------------------------------------------------------------
// archiveRouteExists
//------------------------------------------------------------------------------
768
bool RdbmsCatalogue::archiveRouteExists(rdbms::Conn &conn, const std::string &diskInstanceName,
769
770
771
772
  const std::string &storageClassName, const uint64_t copyNb) const {
  try {
    const char *const sql =
      "SELECT "
773
774
        "ARCHIVE_ROUTE.STORAGE_CLASS_ID AS STORAGE_CLASS_ID,"
        "ARCHIVE_ROUTE.COPY_NB AS COPY_NB "
775
776
      "FROM "
        "ARCHIVE_ROUTE "
777
778
      "INNER JOIN STORAGE_CLASS ON "
        "ARCHIVE_ROUTE.STORAGE_CLASS_ID = STORAGE_CLASS.STORAGE_CLASS_ID "
779
      "WHERE "
780
781
782
        "STORAGE_CLASS.DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
        "STORAGE_CLASS.STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME AND "
        "ARCHIVE_ROUTE.COPY_NB = :COPY_NB";
783
784
785
786
787
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindString(":DISK_INSTANCE_NAME", diskInstanceName);
    stmt.bindString(":STORAGE_CLASS_NAME", storageClassName);
    stmt.bindUint64(":COPY_NB", copyNb);
    auto rset = stmt.executeQuery();
788
    return rset.next();
789
790
  } catch(exception::UserError &) {
    throw;
791
792
793
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
794
795
796
  }
}

797
798
799
//------------------------------------------------------------------------------
// deleteTapePool
//------------------------------------------------------------------------------
800
void RdbmsCatalogue::deleteTapePool(const std::string &name) {
801
  try {
802
    const char *const sql = "DELETE FROM TAPE_POOL WHERE TAPE_POOL_NAME = :TAPE_POOL_NAME";
803
    auto conn = m_connPool.getConn();
804
805
806
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::ON);
    stmt.bindString(":TAPE_POOL_NAME", name);
    stmt.executeNonQuery();
807

808
    if(0 == stmt.getNbAffectedRows()) {
809
      throw exception::UserError(std::string("Cannot delete tape-pool ") + name + " because it does not exist");
810
    }
811
  } catch(exception::UserError &) {
812
    throw;
813
814
815
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
816
  }
Steven Murray's avatar
Steven Murray committed
817
}
818
819
820
821

//------------------------------------------------------------------------------
// getTapePools
//------------------------------------------------------------------------------
822
std::list<TapePool> RdbmsCatalogue::getTapePools() const {
Steven Murray's avatar
Steven Murray committed
823
  try {
824
    std::list<TapePool> pools;
Steven Murray's avatar
Steven Murray committed
825
826
    const char *const sql =
      "SELECT "
827
828
829
        "TAPE_POOL.TAPE_POOL_NAME AS TAPE_POOL_NAME,"
        "TAPE_POOL.NB_PARTIAL_TAPES AS NB_PARTIAL_TAPES,"
        "TAPE_POOL.IS_ENCRYPTED AS IS_ENCRYPTED,"
Steven Murray's avatar
Steven Murray committed
830

831
832
833
        "COALESCE(COUNT(TAPE.VID), 0) AS NB_TAPES,"
        "COALESCE(ROUND(SUM(CAPACITY_IN_BYTES)/1000000000), 0) AS CAPACITY_IN_GB,"
        "COALESCE(ROUND(SUM(DATA_IN_BYTES)/1000000000), 0) AS DATA_IN_GB,"
Steven Murray's avatar
Steven Murray committed
834

835
        "TAPE_POOL.USER_COMMENT AS USER_COMMENT,"
Steven Murray's avatar
Steven Murray committed
836

837
838
839
840
841
842
843
        "TAPE_POOL.CREATION_LOG_USER_NAME AS CREATION_LOG_USER_NAME,"
        "TAPE_POOL.CREATION_LOG_HOST_NAME AS CREATION_LOG_HOST_NAME,"
        "TAPE_POOL.CREATION_LOG_TIME AS CREATION_LOG_TIME,"

        "TAPE_POOL.LAST_UPDATE_USER_NAME AS LAST_UPDATE_USER_NAME,"
        "TAPE_POOL.LAST_UPDATE_HOST_NAME AS LAST_UPDATE_HOST_NAME,"
        "TAPE_POOL.LAST_UPDATE_TIME AS LAST_UPDATE_TIME "
844
      "FROM "
845
        "TAPE_POOL "
846
847
848
849
850
851
852
853
854
855
856
857
858
      "LEFT OUTER JOIN TAPE ON "
        "TAPE_POOL.TAPE_POOL_NAME = TAPE.TAPE_POOL_NAME "
      "GROUP BY "
        "TAPE_POOL.TAPE_POOL_NAME,"
        "TAPE_POOL.NB_PARTIAL_TAPES,"
        "TAPE_POOL.IS_ENCRYPTED,"
        "TAPE_POOL.USER_COMMENT,"
        "TAPE_POOL.CREATION_LOG_USER_NAME,"
        "TAPE_POOL.CREATION_LOG_HOST_NAME,"
        "TAPE_POOL.CREATION_LOG_TIME,"
        "TAPE_POOL.LAST_UPDATE_USER_NAME,"
        "TAPE_POOL.LAST_UPDATE_HOST_NAME,"
        "TAPE_POOL.LAST_UPDATE_TIME "
859
860
      "ORDER BY "
        "TAPE_POOL_NAME";
861

862
    auto conn = m_connPool.getConn();
863
864
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    auto rset = stmt.executeQuery();
865
    while (rset.next()) {
866
      TapePool pool;
Steven Murray's avatar
Steven Murray committed
867

868
869
870
      pool.name = rset.columnString("TAPE_POOL_NAME");
      pool.nbPartialTapes = rset.columnUint64("NB_PARTIAL_TAPES");
      pool.encryption = rset.columnBool("IS_ENCRYPTED");
871
872
873
      pool.nbTapes = rset.columnUint64("NB_TAPES");
      pool.capacityGigabytes = rset.columnUint64("CAPACITY_IN_GB");
      pool.dataGigabytes = rset.columnUint64("DATA_IN_GB");
874
875
876
877
878
879
880
      pool.comment = rset.columnString("USER_COMMENT");
      pool.creationLog.username = rset.columnString("CREATION_LOG_USER_NAME");
      pool.creationLog.host = rset.columnString("CREATION_LOG_HOST_NAME");
      pool.creationLog.time = rset.columnUint64("CREATION_LOG_TIME");
      pool.lastModificationLog.username = rset.columnString("LAST_UPDATE_USER_NAME");
      pool.lastModificationLog.host = rset.columnString("LAST_UPDATE_HOST_NAME");
      pool.lastModificationLog.time = rset.columnUint64("LAST_UPDATE_TIME");
Steven Murray's avatar
Steven Murray committed
881
882

      pools.push_back(pool);
883
884
    }

Steven Murray's avatar
Steven Murray committed
885
    return pools;
886
887
  } catch(exception::UserError &) {
    throw;
888
889
890
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
891
892
893
894
895
896
  }
}

//------------------------------------------------------------------------------
// modifyTapePoolNbPartialTapes
//------------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
897
void RdbmsCatalogue::modifyTapePoolNbPartialTapes(const common::dataStructures::SecurityIdentity &admin,
898
899
900
901
902
903
904
905
906
907
908
909
  const std::string &name, const uint64_t nbPartialTapes) {
  try {
    const time_t now = time(nullptr);
    const char *const sql =
      "UPDATE TAPE_POOL SET "
        "NB_PARTIAL_TAPES = :NB_PARTIAL_TAPES,"
        "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME,"
        "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME,"
        "LAST_UPDATE_TIME = :LAST_UPDATE_TIME "
      "WHERE "
        "TAPE_POOL_NAME = :TAPE_POOL_NAME";
    auto conn = m_connPool.getConn();
910
911
912
913
914
915
916
917
918
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::ON);
    stmt.bindUint64(":NB_PARTIAL_TAPES", nbPartialTapes);
    stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
    stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
    stmt.bindUint64(":LAST_UPDATE_TIME", now);
    stmt.bindString(":TAPE_POOL_NAME", name);
    stmt.executeNonQuery();

    if(0 == stmt.getNbAffectedRows()) {
919
920
921
922
      throw exception::UserError(std::string("Cannot modify tape pool ") + name + " because it does not exist");
    }
  } catch(exception::UserError &) {
    throw;
923
924
925
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
926
  }
Steven Murray's avatar
Steven Murray committed
927
}
928
929
930
931

//------------------------------------------------------------------------------
// modifyTapePoolComment
//------------------------------------------------------------------------------
932
933
void RdbmsCatalogue::modifyTapePoolComment(const common::dataStructures::SecurityIdentity &admin,
  const std::string &name, const std::string &comment) {
934
935
936
937
938
939
940
941
942
943
944
  try {
    const time_t now = time(nullptr);
    const char *const sql =
      "UPDATE TAPE_POOL SET "
        "USER_COMMENT = :USER_COMMENT,"
        "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME,"
        "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME,"
        "LAST_UPDATE_TIME = :LAST_UPDATE_TIME "
      "WHERE "
        "TAPE_POOL_NAME = :TAPE_POOL_NAME";
    auto conn = m_connPool.getConn();
945
946
947
948
949
950
951
952
953
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::ON);
    stmt.bindString(":USER_COMMENT", comment);
    stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
    stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
    stmt.bindUint64(":LAST_UPDATE_TIME", now);
    stmt.bindString(":TAPE_POOL_NAME", name);
    stmt.executeNonQuery();

    if(0 == stmt.getNbAffectedRows()) {
954
955
956
957
      throw exception::UserError(std::string("Cannot modify tape pool ") + name + " because it does not exist");
    }
  } catch(exception::UserError &) {
    throw;
958
959
960
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
961
  }
Steven Murray's avatar
Steven Murray committed
962
}
963
964
965
966

//------------------------------------------------------------------------------
// setTapePoolEncryption
//------------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
967
void RdbmsCatalogue::setTapePoolEncryption(const common::dataStructures::SecurityIdentity &admin,
968
969
970
971
972
973
974
975
976
977
978
979
  const std::string &name, const bool encryptionValue) {
  try {
    const time_t now = time(nullptr);
    const char *const sql =
      "UPDATE TAPE_POOL SET "
        "IS_ENCRYPTED = :IS_ENCRYPTED,"
        "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME,"
        "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME,"
        "LAST_UPDATE_TIME = :LAST_UPDATE_TIME "
      "WHERE "
        "TAPE_POOL_NAME = :TAPE_POOL_NAME";
    auto conn = m_connPool.getConn();
980
981
982
983
984
985
986
987
988
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::ON);
    stmt.bindBool(":IS_ENCRYPTED", encryptionValue);
    stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
    stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
    stmt.bindUint64(":LAST_UPDATE_TIME", now);
    stmt.bindString(":TAPE_POOL_NAME", name);
    stmt.executeNonQuery();

    if(0 == stmt.getNbAffectedRows()) {
989
990
991
992
      throw exception::UserError(std::string("Cannot modify tape pool ") + name + " because it does not exist");
    }
  } catch(exception::UserError &) {
    throw;
993
994
995
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
996
  }
Steven Murray's avatar
Steven Murray committed
997
}
998
999
1000

//------------------------------------------------------------------------------
// createArchiveRoute
For faster browsing, not all history is shown. View entire blame