RdbmsCatalogue.cpp 119 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/AutoRollback.hpp"
21
22
#include "catalogue/RdbmsCatalogue.hpp"
#include "catalogue/RdbmsCatalogueSchema.hpp"
23
#include "catalogue/UserError.hpp"
24
#include "common/dataStructures/TapeFile.hpp"
25
#include "common/exception/Exception.hpp"
26
#include "common/utils/utils.hpp"
27

28
#include <iostream>
29
30
31
#include <memory>
#include <time.h>

32
33
34
namespace cta {
namespace catalogue {

35
36
37
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
38
RdbmsCatalogue::RdbmsCatalogue() {
39
40
41
42
43
}

//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
44
RdbmsCatalogue::~RdbmsCatalogue() {
45
46
47
48
49
}

//------------------------------------------------------------------------------
// createBootstrapAdminAndHostNoAuth
//------------------------------------------------------------------------------
50
void RdbmsCatalogue::createBootstrapAdminAndHostNoAuth(
51
  const common::dataStructures::SecurityIdentity &cliIdentity,
52
  const std::string &username,
53
54
  const std::string &hostName,
  const std::string &comment) {
55
  try {
56
    createAdminUser(cliIdentity, username, comment);
57
    createAdminHost(cliIdentity, hostName, comment);
58
59
60
  } catch(UserError &) {
    throw;
  } catch (exception::Exception &ex) {
61
62
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
63
64
65
66
67
}

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

        ":USER_COMMENT,"

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

100
101
102
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
Steven Murray's avatar
Steven Murray committed
103
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
Steven Murray's avatar
Steven Murray committed
104

105
    stmt->bindString(":ADMIN_USER_NAME", username);
Steven Murray's avatar
Steven Murray committed
106

107
    stmt->bindString(":USER_COMMENT", comment);
Steven Murray's avatar
Steven Murray committed
108

109
    stmt->bindString(":CREATION_LOG_USER_NAME", cliIdentity.username);
110
    stmt->bindString(":CREATION_LOG_HOST_NAME", cliIdentity.host);
111
    stmt->bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
112

113
    stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
114
115
116
    stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
    stmt->bindUint64(":LAST_UPDATE_TIME", now);

Steven Murray's avatar
Steven Murray committed
117
    stmt->executeNonQuery();
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  } catch(UserError &) {
    throw;
  } catch (exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
}

//------------------------------------------------------------------------------
// adminUserExists
//------------------------------------------------------------------------------
bool RdbmsCatalogue::adminUserExists(const std::string adminUsername) const {
  try {
    const char *const sql =
      "SELECT "
        "ADMIN_USER_NAME AS ADMIN_USER_NAME "
      "FROM "
        "ADMIN_USER "
      "WHERE "
        "ADMIN_USER_NAME = :ADMIN_USER_NAME;";
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
    stmt->bindString(":ADMIN_USER_NAME", adminUsername);
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
    return rset->next();
  } catch (exception::Exception &ex) {
142
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
Steven Murray's avatar
Steven Murray committed
143
  }
144
145
146
147
148
}

//------------------------------------------------------------------------------
// deleteAdminUser
//------------------------------------------------------------------------------
149
void RdbmsCatalogue::deleteAdminUser(const std::string &username) {
150
151
152
153
154
155
156
157
158
159
160
161
162
163
  try {
    const char *const sql = "DELETE FROM ADMIN_USER WHERE ADMIN_USER_NAME = :ADMIN_USER_NAME;";
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
    stmt->bindString(":ADMIN_USER_NAME", username);
    stmt->executeNonQuery();

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

//------------------------------------------------------------------------------
// getAdminUsers
//------------------------------------------------------------------------------
169
std::list<common::dataStructures::AdminUser>
170
RdbmsCatalogue::getAdminUsers() const {
Steven Murray's avatar
Steven Murray committed
171
172
173
174
175
  try {
    std::list<common::dataStructures::AdminUser> admins;
    const char *const sql =
      "SELECT "
        "ADMIN_USER_NAME AS ADMIN_USER_NAME,"
176

Steven Murray's avatar
Steven Murray committed
177
        "USER_COMMENT AS USER_COMMENT,"
178

179
180
181
        "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,"
182

183
184
185
        "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 "
186
187
      "FROM "
        "ADMIN_USER";
Steven Murray's avatar
Steven Murray committed
188
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
189
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
Steven Murray's avatar
Steven Murray committed
190
191
    while (rset->next()) {
      common::dataStructures::AdminUser admin;
192

Steven Murray's avatar
Steven Murray committed
193
194
      admin.name = rset->columnText("ADMIN_USER_NAME");
      admin.comment = rset->columnText("USER_COMMENT");
195
196
197
198
199
200
      admin.creationLog.username = rset->columnText("CREATION_LOG_USER_NAME");
      admin.creationLog.host = rset->columnText("CREATION_LOG_HOST_NAME");
      admin.creationLog.time = rset->columnUint64("CREATION_LOG_TIME");
      admin.lastModificationLog.username = rset->columnText("LAST_UPDATE_USER_NAME");
      admin.lastModificationLog.host = rset->columnText("LAST_UPDATE_HOST_NAME");
      admin.lastModificationLog.time = rset->columnUint64("LAST_UPDATE_TIME");
201

Steven Murray's avatar
Steven Murray committed
202
203
      admins.push_back(admin);
    }
204

Steven Murray's avatar
Steven Murray committed
205
    return admins;
206
  } catch (exception::Exception &ex) {
207
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
Steven Murray's avatar
Steven Murray committed
208
  }
209
210
211
212
213
}

//------------------------------------------------------------------------------
// modifyAdminUserComment
//------------------------------------------------------------------------------
214
215
void RdbmsCatalogue::modifyAdminUserComment(const common::dataStructures::SecurityIdentity &cliIdentity,
                                            const std::string &username, const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
216
217
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
218
219
220
221

//------------------------------------------------------------------------------
// createAdminHost
//------------------------------------------------------------------------------
222
void RdbmsCatalogue::createAdminHost(
223
224
225
  const common::dataStructures::SecurityIdentity &cliIdentity,
  const std::string &hostName,
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
226
  try {
227
    if(adminHostExists(hostName)) {
228
229
230
      throw UserError(std::string("Cannot create admin host " + hostName +
        " because an admin host with the same name already exists"));
    }
Steven Murray's avatar
Steven Murray committed
231
232
233
234
235
236
237
238
239
240
241
242
243
244
    const uint64_t now = time(NULL);
    const char *const sql =
      "INSERT INTO ADMIN_HOST("
        "ADMIN_HOST_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)"
245
      "VALUES("
Steven Murray's avatar
Steven Murray committed
246
247
248
249
250
251
252
253
        ":ADMIN_HOST_NAME,"

        ":USER_COMMENT,"

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

254
255
256
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
Steven Murray's avatar
Steven Murray committed
257
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
Steven Murray's avatar
Steven Murray committed
258

259
    stmt->bindString(":ADMIN_HOST_NAME", hostName);
Steven Murray's avatar
Steven Murray committed
260

261
    stmt->bindString(":USER_COMMENT", comment);
Steven Murray's avatar
Steven Murray committed
262

263
    stmt->bindString(":CREATION_LOG_USER_NAME", cliIdentity.username);
264
    stmt->bindString(":CREATION_LOG_HOST_NAME", cliIdentity.host);
265
    stmt->bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
266

267
    stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
268
269
270
    stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
    stmt->bindUint64(":LAST_UPDATE_TIME", now);

Steven Murray's avatar
Steven Murray committed
271
    stmt->executeNonQuery();
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
  } catch(UserError &) {
    throw;
  } catch (exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
}

//------------------------------------------------------------------------------
// adminHostExists
//------------------------------------------------------------------------------
bool RdbmsCatalogue::adminHostExists(const std::string adminHost) const {
  try {
    const char *const sql =
      "SELECT "
       "ADMIN_HOST_NAME AS ADMIN_HOST_NAME "
      "FROM "
        "ADMIN_HOST "
      "WHERE "
        "ADMIN_HOST_NAME = :ADMIN_HOST_NAME;";
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
    stmt->bindString(":ADMIN_HOST_NAME", adminHost);
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
    return rset->next();
  } catch (exception::Exception &ex) {
296
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
Steven Murray's avatar
Steven Murray committed
297
  }
298
299
300
301
302
}

//------------------------------------------------------------------------------
// deleteAdminHost
//------------------------------------------------------------------------------
303
void RdbmsCatalogue::deleteAdminHost(const std::string &hostName) {
304
305
306
307
308
309
310
311
312
313
314
315
316
317
  try {
    const char *const sql = "DELETE FROM ADMIN_HOST WHERE ADMIN_HOST_NAME = :ADMIN_HOST_NAME;";
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
    stmt->bindString(":ADMIN_HOST_NAME", hostName);
    stmt->executeNonQuery();

    if(0 == stmt->getNbAffectedRows()) {
      throw UserError(std::string("Cannot delete admin-host ") + hostName + " because it does not exist");
    }
  } catch(UserError &) {
    throw;
  } catch (exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
Steven Murray's avatar
Steven Murray committed
318
}
319
320
321
322

//------------------------------------------------------------------------------
// getAdminHosts
//------------------------------------------------------------------------------
323
std::list<common::dataStructures::AdminHost> RdbmsCatalogue::getAdminHosts() const {
Steven Murray's avatar
Steven Murray committed
324
325
326
327
328
329
330
331
  try {
    std::list<common::dataStructures::AdminHost> hosts;
    const char *const sql =
      "SELECT "
        "ADMIN_HOST_NAME AS ADMIN_HOST_NAME,"

        "USER_COMMENT AS USER_COMMENT,"

332
333
334
        "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
335

336
337
338
        "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 "
339
      "FROM "
340
        "ADMIN_HOST";
Steven Murray's avatar
Steven Murray committed
341
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
342
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
Steven Murray's avatar
Steven Murray committed
343
344
345
346
347
    while (rset->next()) {
      common::dataStructures::AdminHost host;

      host.name = rset->columnText("ADMIN_HOST_NAME");
      host.comment = rset->columnText("USER_COMMENT");
348
349
350
351
352
353
      host.creationLog.username = rset->columnText("CREATION_LOG_USER_NAME");
      host.creationLog.host = rset->columnText("CREATION_LOG_HOST_NAME");
      host.creationLog.time = rset->columnUint64("CREATION_LOG_TIME");
      host.lastModificationLog.username = rset->columnText("LAST_UPDATE_USER_NAME");
      host.lastModificationLog.host = rset->columnText("LAST_UPDATE_HOST_NAME");
      host.lastModificationLog.time = rset->columnUint64("LAST_UPDATE_TIME");
Steven Murray's avatar
Steven Murray committed
354
355

      hosts.push_back(host);
356
357
    }

Steven Murray's avatar
Steven Murray committed
358
    return hosts;
359
  } catch (exception::Exception &ex) {
360
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
361
362
363
364
365
366
  }
}

//------------------------------------------------------------------------------
// modifyAdminHostComment
//------------------------------------------------------------------------------
367
368
void RdbmsCatalogue::modifyAdminHostComment(const common::dataStructures::SecurityIdentity &cliIdentity,
                                            const std::string &hostName, const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
369
370
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
371
372
373
374

//------------------------------------------------------------------------------
// createStorageClass
//------------------------------------------------------------------------------
375
void RdbmsCatalogue::createStorageClass(
376
377
378
379
  const common::dataStructures::SecurityIdentity &cliIdentity,
  const std::string &name,
  const uint64_t nbCopies,
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
380
  try {
381
    if(storageClassExists(name)) {
382
383
384
      throw UserError(std::string("Cannot create storage class ") + name +
        " because a storage class with the same name already exists");
    }
Steven Murray's avatar
Steven Murray committed
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
    const time_t now = time(NULL);
    const char *const sql =
      "INSERT INTO STORAGE_CLASS("
        "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)"
400
        "VALUES("
Steven Murray's avatar
Steven Murray committed
401
402
403
404
405
406
407
408
409
        ":STORAGE_CLASS_NAME,"
        ":NB_COPIES,"

        ":USER_COMMENT,"

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

410
411
412
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
Steven Murray's avatar
Steven Murray committed
413
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
Steven Murray's avatar
Steven Murray committed
414

415
    stmt->bindString(":STORAGE_CLASS_NAME", name);
416
    stmt->bindUint64(":NB_COPIES", nbCopies);
Steven Murray's avatar
Steven Murray committed
417

418
    stmt->bindString(":USER_COMMENT", comment);
Steven Murray's avatar
Steven Murray committed
419

420
    stmt->bindString(":CREATION_LOG_USER_NAME", cliIdentity.username);
421
    stmt->bindString(":CREATION_LOG_HOST_NAME", cliIdentity.host);
422
    stmt->bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
423

424
    stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
425
426
427
    stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
    stmt->bindUint64(":LAST_UPDATE_TIME", now);

Steven Murray's avatar
Steven Murray committed
428
    stmt->executeNonQuery();
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
  } catch(UserError &) {
    throw;
  } catch (exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
}

//------------------------------------------------------------------------------
// storageClassExists
//------------------------------------------------------------------------------
bool RdbmsCatalogue::storageClassExists(const std::string &storageClassName) const {
  try {
    const char *const sql =
      "SELECT "
        "STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME "
      "FROM "
        "STORAGE_CLASS "
      "WHERE "
        "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME;";
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
    stmt->bindString(":STORAGE_CLASS_NAME", storageClassName);
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
    return rset->next();
  } catch (exception::Exception &ex) {
453
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
Steven Murray's avatar
Steven Murray committed
454
  }
455
456
457
458
459
}

//------------------------------------------------------------------------------
// deleteStorageClass
//------------------------------------------------------------------------------
460
461
462
463
464
465
void RdbmsCatalogue::deleteStorageClass(const std::string &name) {
  try {
    const char *const sql =
      "DELETE FROM "
        "STORAGE_CLASS "
      "WHERE "
466
        "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME;";
Steven Murray's avatar
Steven Murray committed
467
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
468
469
470
471

    stmt->bindString(":STORAGE_CLASS_NAME", name);

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

//------------------------------------------------------------------------------
// getStorageClasses
//------------------------------------------------------------------------------
485
std::list<common::dataStructures::StorageClass>
486
  RdbmsCatalogue::getStorageClasses() const {
Steven Murray's avatar
Steven Murray committed
487
488
489
490
491
  try {
    std::list<common::dataStructures::StorageClass> storageClasses;
    const char *const sql =
      "SELECT "
        "STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME,"
492
        "NB_COPIES AS NB_COPIES,"
Steven Murray's avatar
Steven Murray committed
493
494
495

        "USER_COMMENT AS USER_COMMENT,"

496
497
498
        "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
499

500
501
502
        "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 "
503
504
      "FROM "
        "STORAGE_CLASS";
Steven Murray's avatar
Steven Murray committed
505
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
506
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
Steven Murray's avatar
Steven Murray committed
507
508
509
510
511
512
    while (rset->next()) {
      common::dataStructures::StorageClass storageClass;

      storageClass.name = rset->columnText("STORAGE_CLASS_NAME");
      storageClass.nbCopies = rset->columnUint64("NB_COPIES");
      storageClass.comment = rset->columnText("USER_COMMENT");
513
514
515
516
517
518
      storageClass.creationLog.username = rset->columnText("CREATION_LOG_USER_NAME");
      storageClass.creationLog.host = rset->columnText("CREATION_LOG_HOST_NAME");
      storageClass.creationLog.time = rset->columnUint64("CREATION_LOG_TIME");
      storageClass.lastModificationLog.username = rset->columnText("LAST_UPDATE_USER_NAME");
      storageClass.lastModificationLog.host = rset->columnText("LAST_UPDATE_HOST_NAME");
      storageClass.lastModificationLog.time = rset->columnUint64("LAST_UPDATE_TIME");
Steven Murray's avatar
Steven Murray committed
519
520

      storageClasses.push_back(storageClass);
521
522
    }

Steven Murray's avatar
Steven Murray committed
523
    return storageClasses;
524
525
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
526
527
528
529
530
531
  }
}

//------------------------------------------------------------------------------
// modifyStorageClassNbCopies
//------------------------------------------------------------------------------
532
void RdbmsCatalogue::modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t nbCopies) {
Steven Murray's avatar
Steven Murray committed
533
534
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
535
536
537
538

//------------------------------------------------------------------------------
// modifyStorageClassComment
//------------------------------------------------------------------------------
539
void RdbmsCatalogue::modifyStorageClassComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
540
541
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
542
543
544
545

//------------------------------------------------------------------------------
// createTapePool
//------------------------------------------------------------------------------
546
void RdbmsCatalogue::createTapePool(
547
  const common::dataStructures::SecurityIdentity &cliIdentity,
548
549
550
551
  const std::string &name,
  const uint64_t nbPartialTapes,
  const bool encryptionValue,
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
552
  try {
553
554
555
556
    if(tapePoolExists(name)) {
      throw UserError(std::string("Cannot create tape pool ") + name +
        " because a tape pool with the same name already exists");
    }
Steven Murray's avatar
Steven Murray committed
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
    const time_t now = time(NULL);
    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)"
573
        "VALUES("
Steven Murray's avatar
Steven Murray committed
574
575
576
577
578
579
580
581
582
583
        ":TAPE_POOL_NAME,"
        ":NB_PARTIAL_TAPES,"
        ":IS_ENCRYPTED,"

        ":USER_COMMENT,"

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

584
585
586
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
Steven Murray's avatar
Steven Murray committed
587
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
Steven Murray's avatar
Steven Murray committed
588

589
    stmt->bindString(":TAPE_POOL_NAME", name);
590
591
    stmt->bindUint64(":NB_PARTIAL_TAPES", nbPartialTapes);
    stmt->bindUint64(":IS_ENCRYPTED", encryptionValue);
Steven Murray's avatar
Steven Murray committed
592

593
    stmt->bindString(":USER_COMMENT", comment);
Steven Murray's avatar
Steven Murray committed
594

595
    stmt->bindString(":CREATION_LOG_USER_NAME", cliIdentity.username);
596
    stmt->bindString(":CREATION_LOG_HOST_NAME", cliIdentity.host);
597
    stmt->bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
598

599
    stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
600
601
602
    stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
    stmt->bindUint64(":LAST_UPDATE_TIME", now);

Steven Murray's avatar
Steven Murray committed
603
    stmt->executeNonQuery();
604
605
  } catch(UserError &) {
    throw;
606
607
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
Steven Murray's avatar
Steven Murray committed
608
  }
609
610
}

611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
//------------------------------------------------------------------------------
// tapePoolExists
//------------------------------------------------------------------------------
bool RdbmsCatalogue::tapePoolExists(const std::string &tapePoolName) const {
  try {
    const char *const sql =
      "SELECT "
        "TAPE_POOL_NAME AS TAPE_POOL_NAME "
      "FROM "
        "TAPE_POOL "
      "WHERE "
        "TAPE_POOL_NAME = :TAPE_POOL_NAME;";
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
    stmt->bindString(":TAPE_POOL_NAME", tapePoolName);
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
    return rset->next();
  } catch (exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
}

632
633
634
//------------------------------------------------------------------------------
// deleteTapePool
//------------------------------------------------------------------------------
635
void RdbmsCatalogue::deleteTapePool(const std::string &name) {
636
637
638
639
640
641
642
643
644
645
646
647
648
649
  try {
    const char *const sql = "DELETE FROM TAPE_POOL WHERE TAPE_POOL_NAME = :TAPE_POOL_NAME;";
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
    stmt->bindString(":TAPE_POOL_NAME", name);
    stmt->executeNonQuery();

    if(0 == stmt->getNbAffectedRows()) {
      throw UserError(std::string("Cannot delete tape-pool ") + name + " because it does not exist");
    }
  } catch(UserError &) {
    throw;
  } catch (exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
Steven Murray's avatar
Steven Murray committed
650
}
651
652
653
654

//------------------------------------------------------------------------------
// getTapePools
//------------------------------------------------------------------------------
655
std::list<common::dataStructures::TapePool>
656
  RdbmsCatalogue::getTapePools() const {
Steven Murray's avatar
Steven Murray committed
657
  try {
658
    std::list<common::dataStructures::TapePool> pools;
Steven Murray's avatar
Steven Murray committed
659
660
    const char *const sql =
      "SELECT "
661
        "TAPE_POOL_NAME AS TAPE_POOL_NAME,"
Steven Murray's avatar
Steven Murray committed
662
        "NB_PARTIAL_TAPES AS NB_PARTIAL_TAPES,"
663
        "IS_ENCRYPTED AS IS_ENCRYPTED,"
Steven Murray's avatar
Steven Murray committed
664
665
666

        "USER_COMMENT AS USER_COMMENT,"

667
668
669
        "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
670

671
672
673
        "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 "
674
675
      "FROM "
        "TAPE_POOL";
Steven Murray's avatar
Steven Murray committed
676
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
677
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
Steven Murray's avatar
Steven Murray committed
678
679
680
681
682
683
684
    while (rset->next()) {
      common::dataStructures::TapePool pool;

      pool.name = rset->columnText("TAPE_POOL_NAME");
      pool.nbPartialTapes = rset->columnUint64("NB_PARTIAL_TAPES");
      pool.encryption = rset->columnUint64("IS_ENCRYPTED");
      pool.comment = rset->columnText("USER_COMMENT");
685
686
687
688
689
690
      pool.creationLog.username = rset->columnText("CREATION_LOG_USER_NAME");
      pool.creationLog.host = rset->columnText("CREATION_LOG_HOST_NAME");
      pool.creationLog.time = rset->columnUint64("CREATION_LOG_TIME");
      pool.lastModificationLog.username = rset->columnText("LAST_UPDATE_USER_NAME");
      pool.lastModificationLog.host = rset->columnText("LAST_UPDATE_HOST_NAME");
      pool.lastModificationLog.time = rset->columnUint64("LAST_UPDATE_TIME");
Steven Murray's avatar
Steven Murray committed
691
692

      pools.push_back(pool);
693
694
    }

Steven Murray's avatar
Steven Murray committed
695
    return pools;
696
697
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
698
699
700
701
702
703
  }
}

//------------------------------------------------------------------------------
// modifyTapePoolNbPartialTapes
//------------------------------------------------------------------------------
704
void RdbmsCatalogue::modifyTapePoolNbPartialTapes(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t nbPartialTapes) {
Steven Murray's avatar
Steven Murray committed
705
706
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
707
708
709
710

//------------------------------------------------------------------------------
// modifyTapePoolComment
//------------------------------------------------------------------------------
711
void RdbmsCatalogue::modifyTapePoolComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
712
713
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
714
715
716
717

//------------------------------------------------------------------------------
// setTapePoolEncryption
//------------------------------------------------------------------------------
718
void RdbmsCatalogue::setTapePoolEncryption(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const bool encryptionValue) {
Steven Murray's avatar
Steven Murray committed
719
720
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
721
722
723
724

//------------------------------------------------------------------------------
// createArchiveRoute
//------------------------------------------------------------------------------
725
void RdbmsCatalogue::createArchiveRoute(
726
727
728
729
730
  const common::dataStructures::SecurityIdentity &cliIdentity,
  const std::string &storageClassName,
  const uint64_t copyNb,
  const std::string &tapePoolName,
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
  try {
    const time_t now = time(NULL);
    const char *const sql =
      "INSERT INTO ARCHIVE_ROUTE("
        "STORAGE_CLASS_NAME,"
        "COPY_NB,"
        "TAPE_POOL_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)"
748
      "VALUES("
Steven Murray's avatar
Steven Murray committed
749
750
751
752
753
754
755
756
757
758
        ":STORAGE_CLASS_NAME,"
        ":COPY_NB,"
        ":TAPE_POOL_NAME,"

        ":USER_COMMENT,"

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

759
760
761
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
Steven Murray's avatar
Steven Murray committed
762
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
Steven Murray's avatar
Steven Murray committed
763

764
    stmt->bindString(":STORAGE_CLASS_NAME", storageClassName);
765
    stmt->bindUint64(":COPY_NB", copyNb);
766
    stmt->bindString(":TAPE_POOL_NAME", tapePoolName);
Steven Murray's avatar
Steven Murray committed
767

768
    stmt->bindString(":USER_COMMENT", comment);
Steven Murray's avatar
Steven Murray committed
769

770
    stmt->bindString(":CREATION_LOG_USER_NAME", cliIdentity.username);
771
    stmt->bindString(":CREATION_LOG_HOST_NAME", cliIdentity.host);
772
    stmt->bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
773

774
    stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
775
776
777
    stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
    stmt->bindUint64(":LAST_UPDATE_TIME", now);

Steven Murray's avatar
Steven Murray committed
778
    stmt->executeNonQuery();
779
780
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
Steven Murray's avatar
Steven Murray committed
781
  }
782
783
784
785
786
}

//------------------------------------------------------------------------------
// deleteArchiveRoute
//------------------------------------------------------------------------------
787
void RdbmsCatalogue::deleteArchiveRoute(const std::string &storageClassName, const uint64_t copyNb) {
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
  try {
    const char *const sql =
      "DELETE FROM "
        "ARCHIVE_ROUTE "
      "WHERE "
        "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME AND "
        "COPY_NB = :COPY_NB;";
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
    stmt->bindString(":STORAGE_CLASS_NAME", storageClassName);
    stmt->bindUint64(":COPY_NB", copyNb);
    stmt->executeNonQuery();

    if(0 == stmt->getNbAffectedRows()) {
      UserError ue;
      ue.getMessage() << "Cannot delete archive route for storage-class " << storageClassName + " and copy number " <<
        copyNb << " because it does not exist";
      throw ue;
    }
  } catch(UserError &) {
    throw;
  } catch (exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
Steven Murray's avatar
Steven Murray committed
811
}
812
813
814
815

//------------------------------------------------------------------------------
// getArchiveRoutes
//------------------------------------------------------------------------------
816
std::list<common::dataStructures::ArchiveRoute>
817
  RdbmsCatalogue::getArchiveRoutes() const {
Steven Murray's avatar
Steven Murray committed
818
819
820
821
822
  try {
    std::list<common::dataStructures::ArchiveRoute> routes;
    const char *const sql =
      "SELECT "
        "STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME,"
823
824
        "COPY_NB AS COPY_NB,"
        "TAPE_POOL_NAME AS TAPE_POOL_NAME,"
Steven Murray's avatar
Steven Murray committed
825
826
827

        "USER_COMMENT AS USER_COMMENT,"

828
829
830
        "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
831

832
833
834
        "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 "
835
836
      "FROM "
        "ARCHIVE_ROUTE";
Steven Murray's avatar
Steven Murray committed
837
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
838
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
Steven Murray's avatar
Steven Murray committed
839
840
841
842
843
844
845
    while (rset->next()) {
      common::dataStructures::ArchiveRoute route;

      route.storageClassName = rset->columnText("STORAGE_CLASS_NAME");
      route.copyNb = rset->columnUint64("COPY_NB");
      route.tapePoolName = rset->columnText("TAPE_POOL_NAME");
      route.comment = rset->columnText("USER_COMMENT");
846
847
848
849
850
851
      route.creationLog.username = rset->columnText("CREATION_LOG_USER_NAME");
      route.creationLog.host = rset->columnText("CREATION_LOG_HOST_NAME");
      route.creationLog.time = rset->columnUint64("CREATION_LOG_TIME");
      route.lastModificationLog.username = rset->columnText("LAST_UPDATE_USER_NAME");
      route.lastModificationLog.host = rset->columnText("LAST_UPDATE_HOST_NAME");
      route.lastModificationLog.time = rset->columnUint64("LAST_UPDATE_TIME");
Steven Murray's avatar
Steven Murray committed
852
853

      routes.push_back(route);
854
855
    }

Steven Murray's avatar
Steven Murray committed
856
    return routes;
857
858
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
859
860
861
862
863
864
  }
}

//------------------------------------------------------------------------------
// modifyArchiveRouteTapePoolName
//------------------------------------------------------------------------------
865
void RdbmsCatalogue::modifyArchiveRouteTapePoolName(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &storageClassName, const uint64_t copyNb, const std::string &tapePoolName) {
Steven Murray's avatar
Steven Murray committed
866
867
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
868
869
870
871

//------------------------------------------------------------------------------
// modifyArchiveRouteComment
//------------------------------------------------------------------------------
872
void RdbmsCatalogue::modifyArchiveRouteComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &storageClassName, const uint64_t copyNb, const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
873
874
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
875
876
877
878

//------------------------------------------------------------------------------
// createLogicalLibrary
//------------------------------------------------------------------------------
879
void RdbmsCatalogue::createLogicalLibrary(
880
881
882
  const common::dataStructures::SecurityIdentity &cliIdentity,
  const std::string &name,
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
883
  try {
884
    if(logicalLibraryExists(name)) {
885
886
887
      throw UserError(std::string("Cannot create logical library ") + name +
        " because a logical library with the same name already exists");
    }
Steven Murray's avatar
Steven Murray committed
888
889
890
891
892
893
894
895
896
897
898
899
900
901
    const time_t now = time(NULL);
    const char *const sql =
      "INSERT INTO LOGICAL_LIBRARY("
        "LOGICAL_LIBRARY_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)"
902
        "VALUES("
Steven Murray's avatar
Steven Murray committed
903
904
905
906
907
908
909
910
        ":LOGICAL_LIBRARY_NAME,"

        ":USER_COMMENT,"

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

911
912
913
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
Steven Murray's avatar
Steven Murray committed
914
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
Steven Murray's avatar
Steven Murray committed
915

916
    stmt->bindString(":LOGICAL_LIBRARY_NAME", name);
Steven Murray's avatar
Steven Murray committed
917

918
    stmt->bindString(":USER_COMMENT", comment);
Steven Murray's avatar
Steven Murray committed
919

920
    stmt->bindString(":CREATION_LOG_USER_NAME", cliIdentity.username);
921
    stmt->bindString(":CREATION_LOG_HOST_NAME", cliIdentity.host);
922
    stmt->bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
923

924
    stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
925
926
927
    stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
    stmt->bindUint64(":LAST_UPDATE_TIME", now);

Steven Murray's avatar
Steven Murray committed
928
    stmt->executeNonQuery();
929
930
  } catch(UserError &) {
    throw;
Steven Murray's avatar
Steven Murray committed
931
932
933
  } catch(std::exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.what());
  }
934
935
}

936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
//------------------------------------------------------------------------------
// logicalLibraryExists
//------------------------------------------------------------------------------
bool RdbmsCatalogue::logicalLibraryExists(const std::string &logicalLibraryName) const {
  try {
    const char *const sql =
      "SELECT "
        "LOGICAL_LIBRARY_NAME AS LOGICAL_LIBRARY_NAME "
      "FROM "
        "LOGICAL_LIBRARY "
      "WHERE "
        "LOGICAL_LIBRARY_NAME = :LOGICAL_LIBRARY_NAME;";
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
    stmt->bindString(":LOGICAL_LIBRARY_NAME", logicalLibraryName);
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
    return rset->next();
  } catch (exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
}

957
958
959
//------------------------------------------------------------------------------
// deleteLogicalLibrary
//------------------------------------------------------------------------------
960
void RdbmsCatalogue::deleteLogicalLibrary(const std::string &name) {
961
962
963
964
965
966
967
968
969
970
971
972
973
974
  try {
    const char *const sql = "DELETE FROM LOGICAL_LIBRARY WHERE LOGICAL_LIBRARY_NAME = :LOGICAL_LIBRARY_NAME;";
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
    stmt->bindString(":LOGICAL_LIBRARY_NAME", name);
    stmt->executeNonQuery();

    if(0 == stmt->getNbAffectedRows()) {
      throw UserError(std::string("Cannot delete logical-library ") + name + " because it does not exist");
    }
  } catch(UserError &) {
    throw;
  } catch (exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
Steven Murray's avatar
Steven Murray committed
975
}
976
977
978
979

//------------------------------------------------------------------------------
// getLogicalLibraries
//------------------------------------------------------------------------------
980
std::list<common::dataStructures::LogicalLibrary>
981
  RdbmsCatalogue::getLogicalLibraries() const {
Steven Murray's avatar
Steven Murray committed
982
  try {
983
    std::list<common::dataStructures::LogicalLibrary> libs;
Steven Murray's avatar
Steven Murray committed
984
985
    const char *const sql =
      "SELECT "
986
        "LOGICAL_LIBRARY_NAME AS LOGICAL_LIBRARY_NAME,"
987

Steven Murray's avatar
Steven Murray committed
988
        "USER_COMMENT AS USER_COMMENT,"
989

990
991
992
        "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,"
993

994
995
996
        "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 "
997
998
      "FROM "
        "LOGICAL_LIBRARY";
Steven Murray's avatar
Steven Murray committed
999
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
1000
    std::unique_ptr<DbRset> rset(stmt->executeQuery());