RdbmsCatalogue.cpp 188 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
25
#include "catalogue/UserSpecifiedANonEmptyTape.hpp"
#include "catalogue/UserSpecifiedANonExistentTape.hpp"
26
#include "common/dataStructures/TapeFile.hpp"
27
#include "common/exception/Exception.hpp"
28
#include "common/exception/UserError.hpp"
29
#include "common/make_unique.hpp"
30
#include "common/threading/MutexLocker.hpp"
31
#include "common/Timer.hpp"
32
#include "common/utils/utils.hpp"
33
#include "rdbms/AutoRollback.hpp"
34

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

40
41
42
namespace cta {
namespace catalogue {

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

//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
66
RdbmsCatalogue::~RdbmsCatalogue() {
67
68
69
70
71
}

//------------------------------------------------------------------------------
// createAdminUser
//------------------------------------------------------------------------------
72
void RdbmsCatalogue::createAdminUser(
Steven Murray's avatar
Steven Murray committed
73
  const common::dataStructures::SecurityIdentity &admin,
74
  const std::string &username,
75
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
76
  try {
77
    auto conn = m_connPool.getConn();
78
    if (adminUserExists(conn, username)) {
79
      throw exception::UserError(std::string("Cannot create admin user " + username +
80
81
        " because an admin user with the same name already exists"));
    }
82
    const uint64_t now = time(nullptr);
Steven Murray's avatar
Steven Murray committed
83
84
85
86
87
88
89
90
91
92
93
94
95
    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)"
96
      "VALUES("
Steven Murray's avatar
Steven Murray committed
97
98
99
100
101
102
103
104
        ":ADMIN_USER_NAME,"

        ":USER_COMMENT,"

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

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

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

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

114
115
116
    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
117

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

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

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

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

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

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

Steven Murray's avatar
Steven Murray committed
187
        "USER_COMMENT AS USER_COMMENT,"
188

189
190
191
        "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,"
192

193
194
195
        "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 "
196
      "FROM "
197
198
199
        "ADMIN_USER "
      "ORDER BY "
        "ADMIN_USER_NAME";
200
    auto conn = m_connPool.getConn();
201
202
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    auto rset = stmt.executeQuery();
203
    while (rset.next()) {
Steven Murray's avatar
Steven Murray committed
204
      common::dataStructures::AdminUser admin;
205

206
207
208
209
210
211
212
213
      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");
214

Steven Murray's avatar
Steven Murray committed
215
216
      admins.push_back(admin);
    }
217

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

//------------------------------------------------------------------------------
// modifyAdminUserComment
//------------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
230
void RdbmsCatalogue::modifyAdminUserComment(const common::dataStructures::SecurityIdentity &admin,
231
232
233
234
235
236
237
238
239
  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 "
240
      "WHERE "
241
242
        "ADMIN_USER_NAME = :ADMIN_USER_NAME";
    auto conn = m_connPool.getConn();
243
244
245
246
247
248
249
250
251
    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()) {
252
253
254
255
      throw exception::UserError(std::string("Cannot modify admin user ") + username + " because they do not exist");
    }
  } catch(exception::UserError &) {
    throw;
256
257
258
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
259
  }
Steven Murray's avatar
Steven Murray committed
260
}
261
262
263
264

//------------------------------------------------------------------------------
// createStorageClass
//------------------------------------------------------------------------------
265
void RdbmsCatalogue::createStorageClass(
Steven Murray's avatar
Steven Murray committed
266
  const common::dataStructures::SecurityIdentity &admin,
267
  const common::dataStructures::StorageClass &storageClass) {
Steven Murray's avatar
Steven Murray committed
268
  try {
269
    auto conn = m_connPool.getConn();
270
    if(storageClassExists(conn, storageClass.diskInstance, storageClass.name)) {
271
272
      throw exception::UserError(std::string("Cannot create storage class ") + storageClass.diskInstance + ":" +
        storageClass.name + " because it already exists");
273
    }
274
    const uint64_t storageClassId = getNextStorageClassId(conn);
275
    const time_t now = time(nullptr);
Steven Murray's avatar
Steven Murray committed
276
277
    const char *const sql =
      "INSERT INTO STORAGE_CLASS("
278
        "STORAGE_CLASS_ID,"
279
        "DISK_INSTANCE_NAME,"
Steven Murray's avatar
Steven Murray committed
280
281
282
283
284
285
286
287
288
289
290
291
        "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)"
292
      "VALUES("
293
        ":STORAGE_CLASS_ID,"
294
        ":DISK_INSTANCE_NAME,"
Steven Murray's avatar
Steven Murray committed
295
296
297
298
299
300
301
302
303
        ":STORAGE_CLASS_NAME,"
        ":NB_COPIES,"

        ":USER_COMMENT,"

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

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

309
    stmt.bindUint64(":STORAGE_CLASS_ID", storageClassId);
310
311
312
    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
313

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

316
317
318
    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
319

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

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

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

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

375
376
    stmt.bindString(":DISK_INSTANCE_NAME", diskInstanceName);
    stmt.bindString(":STORAGE_CLASS_NAME", storageClassName);
377

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

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

        "USER_COMMENT AS USER_COMMENT,"

405
406
407
        "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
408

409
410
411
        "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 "
412
      "FROM "
413
414
415
        "STORAGE_CLASS "
      "ORDER BY "
        "DISK_INSTANCE_NAME, STORAGE_CLASS_NAME";
416
    auto conn = m_connPool.getConn();
417
418
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    auto rset = stmt.executeQuery();
419
    while (rset.next()) {
Steven Murray's avatar
Steven Murray committed
420
421
      common::dataStructures::StorageClass storageClass;

422
423
424
425
426
427
428
429
430
431
      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
432
433

      storageClasses.push_back(storageClass);
434
435
    }

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

//------------------------------------------------------------------------------
// modifyStorageClassNbCopies
//------------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
448
void RdbmsCatalogue::modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &admin,
449
450
451
452
453
454
455
456
457
  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 "
458
      "WHERE "
459
460
461
        "DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
        "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME";
    auto conn = m_connPool.getConn();
462
463
464
465
466
467
468
469
470
471
    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()) {
472
473
474
475
476
      throw exception::UserError(std::string("Cannot modify storage class ") + instanceName + ":" + name +
        " because it does not exist");
    }
  } catch(exception::UserError &) {
    throw;
477
478
479
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
480
  }
Steven Murray's avatar
Steven Murray committed
481
}
482
483
484
485

//------------------------------------------------------------------------------
// modifyStorageClassComment
//------------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
486
void RdbmsCatalogue::modifyStorageClassComment(const common::dataStructures::SecurityIdentity &admin,
487
488
489
490
491
492
493
494
495
  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 "
496
      "WHERE "
497
498
499
        "DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
        "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME";
    auto conn = m_connPool.getConn();
500
501
502
503
504
505
506
507
508
509
    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()) {
510
511
512
513
514
      throw exception::UserError(std::string("Cannot modify storage class ") + instanceName + ":" + name +
        " because it does not exist");
    }
  } catch(exception::UserError &) {
    throw;
515
516
517
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
518
  }
Steven Murray's avatar
Steven Murray committed
519
}
520
521
522
523

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

533
    if(tapePoolExists(conn, name)) {
534
      throw exception::UserError(std::string("Cannot create tape pool ") + name +
535
536
        " because a tape pool with the same name already exists");
    }
537
    const time_t now = time(nullptr);
Steven Murray's avatar
Steven Murray committed
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
    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)"
553
      "VALUES("
Steven Murray's avatar
Steven Murray committed
554
555
556
557
558
559
560
561
562
563
        ":TAPE_POOL_NAME,"
        ":NB_PARTIAL_TAPES,"
        ":IS_ENCRYPTED,"

        ":USER_COMMENT,"

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

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

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

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

575
576
577
    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
578

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

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

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

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

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

655
656
657
//------------------------------------------------------------------------------
// diskFileIdExists
//------------------------------------------------------------------------------
658
bool RdbmsCatalogue::diskFileIdExists(rdbms::Conn &conn, const std::string &diskInstanceName,
659
660
661
662
663
664
665
666
667
668
669
  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";
670
671
672
673
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindString(":DISK_INSTANCE_NAME", diskInstanceName);
    stmt.bindString(":DISK_FILE_ID", diskFileId);
    auto rset = stmt.executeQuery();
674
    return rset.next();
675
676
  } catch(exception::UserError &) {
    throw;
677
678
679
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
680
681
682
  }
}

683
684
685
//------------------------------------------------------------------------------
// diskFilePathExists
//------------------------------------------------------------------------------
686
bool RdbmsCatalogue::diskFilePathExists(rdbms::Conn &conn, const std::string &diskInstanceName,
687
688
689
690
691
692
693
694
695
696
697
  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";
698
699
700
701
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindString(":DISK_INSTANCE_NAME", diskInstanceName);
    stmt.bindString(":DISK_FILE_PATH", diskFilePath);
    auto rset = stmt.executeQuery();
702
    return rset.next();
703
704
  } catch(exception::UserError &) {
    throw;
705
706
707
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
708
709
710
  }
}

711
712
713
//------------------------------------------------------------------------------
// diskFileUserExists
//------------------------------------------------------------------------------
714
bool RdbmsCatalogue::diskFileUserExists(rdbms::Conn &conn, const std::string &diskInstanceName,
715
716
717
718
719
720
721
722
723
724
725
  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";
726
727
728
729
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindString(":DISK_INSTANCE_NAME", diskInstanceName);
    stmt.bindString(":DISK_FILE_USER", diskFileUser);
    auto rset = stmt.executeQuery();
730
    return rset.next();
731
732
  } catch(exception::UserError &) {
    throw;
733
734
735
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
736
737
738
  }
}

739
740
741
//------------------------------------------------------------------------------
// diskFileGroupExists
//------------------------------------------------------------------------------
742
bool RdbmsCatalogue::diskFileGroupExists(rdbms::Conn &conn, const std::string &diskInstanceName,
743
744
745
746
747
748
749
750
751
752
753
  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";
754
755
756
757
    auto stmt = conn.createStmt(sql, rdbms::AutocommitMode::OFF);
    stmt.bindString(":DISK_INSTANCE_NAME", diskInstanceName);
    stmt.bindString(":DISK_FILE_GROUP", diskFileGroup);
    auto rset = stmt.executeQuery();
758
    return rset.next();
759
760
  } catch(exception::UserError &) {
    throw;
761
762
763
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
764
765
766
  }
}

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

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

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

//------------------------------------------------------------------------------
// getTapePools
//------------------------------------------------------------------------------
824
std::list<TapePool> RdbmsCatalogue::getTapePools() const {
Steven Murray's avatar
Steven Murray committed
825
  try {
826
    std::list<TapePool> pools;
Steven Murray's avatar
Steven Murray committed
827
828
    const char *const sql =
      "SELECT "
829
830
831
        "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
832

833
        "COALESCE(COUNT(TAPE.VID), 0) AS NB_TAPES,"
834
835
        "COALESCE(SUM(CAPACITY_IN_BYTES), 0) AS CAPACITY_IN_BYTES,"
        "COALESCE(SUM(DATA_IN_BYTES), 0) AS DATA_IN_BYTES,"
Steven Murray's avatar
Steven Murray committed
836

837
        "TAPE_POOL.USER_COMMENT AS USER_COMMENT,"
Steven Murray's avatar
Steven Murray committed
838

839
840
841
842
843
844
845
        "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 "
846
      "FROM "
847
        "TAPE_POOL "
848
849
850
851
852
853
854
855
856
857
858
859
860
      "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 "
861
862
      "ORDER BY "
        "TAPE_POOL_NAME";
863

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

870
871
872
      pool.name = rset.columnString("TAPE_POOL_NAME");
      pool.nbPartialTapes = rset.columnUint64("NB_PARTIAL_TAPES");
      pool.encryption = rset.columnBool("IS_ENCRYPTED");
873
      pool.nbTapes = rset.columnUint64("NB_TAPES");
874
875
      pool.capacityBytes = rset.columnUint64("CAPACITY_IN_BYTES");
      pool.dataBytes = rset.columnUint64("DATA_IN_BYTES");
876
877
878
879
880
881
882
      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
883
884

      pools.push_back(pool);
885
886
    }

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

//------------------------------------------------------------------------------
// modifyTapePoolNbPartialTapes
//------------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
899
void RdbmsCatalogue::modifyTapePoolNbPartialTapes(const common::dataStructures::SecurityIdentity &admin,
900
901
902
903
904
905
906
907
908
909
910
911
  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();
912
913
914
915
916
917
918
919
920
    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()) {
921
922
923
924
      throw exception::UserError(std::string("Cannot modify tape pool ") + name + " because it does not exist");
    }
  } catch(exception::UserError &) {
    throw;
925
926
927
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
928
  }
Steven Murray's avatar
Steven Murray committed
929
}
930
931
932
933

//------------------------------------------------------------------------------
// modifyTapePoolComment
//------------------------------------------------------------------------------
934
935
void RdbmsCatalogue::modifyTapePoolComment(const common::dataStructures::SecurityIdentity &admin,
  const std::string &name, const std::string &comment) {
936
937
938
939
940
941
942
943
944
945
946
  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();
947
948
949
950
951
952
953
954
955
    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()) {
956
957
958
959
      throw exception::UserError(std::string("Cannot modify tape pool ") + name + " because it does not exist");
    }
  } catch(exception::UserError &) {
    throw;
960
961
962
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
963
  }
Steven Murray's avatar
Steven Murray committed
964
}
965
966
967
968

//------------------------------------------------------------------------------
// setTapePoolEncryption
//------------------------------------------------------------------------------
Steven Murray's avatar
Steven Murray committed
969
void RdbmsCatalogue::setTapePoolEncryption(const common::dataStructures::SecurityIdentity &admin,
970
971
972
973
974
975
976
977
978
979
980
981
  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();
982
983
984
985
986
987
988
989
990
    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()) {
991
992
993
994
      throw exception::UserError(std::string("Cannot modify tape pool ") + name + " because it does not exist");
    }
  } catch(exception::UserError &) {
    throw;
995
996
997
  } catch(exception::Exception &ex) {
    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
    throw;
998
  }
Steven Murray's avatar
Steven Murray committed
999
}
1000

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