RdbmsCatalogue.cpp 130 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 <ctype.h>
29
#include <iostream>
30
31
32
#include <memory>
#include <time.h>

33
34
35
namespace cta {
namespace catalogue {

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
namespace {

/**
 * Returns an all upper-case version of the specified string.
 *
 * @param str The string to be copied into an all upper case version of itself.
 * @return An all upper-case version of the specified string.
 */
std::string toUpper(const std::string &str) {
  std::string upperStr;

  for(auto c: str) {
    upperStr += toupper(c);
  }

  return upperStr;
}

/**
 * Returns true of the specified string in considered to be a valid
 * representation of a boolean value.
 *
 * @param str The string to be tested.
 * @return True if the specified string is a valid representation of a boolean value.
 */
bool isValidBool(const std::string &str) {
  const std::string upperStr = toUpper(str);

  return upperStr == "TRUE" || upperStr == "FALSE";
}

} // anonymous namespace

69
70
71
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
72
RdbmsCatalogue::RdbmsCatalogue() {
73
74
75
76
77
}

//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
78
RdbmsCatalogue::~RdbmsCatalogue() {
79
80
81
82
83
}

//------------------------------------------------------------------------------
// createBootstrapAdminAndHostNoAuth
//------------------------------------------------------------------------------
84
void RdbmsCatalogue::createBootstrapAdminAndHostNoAuth(
85
  const common::dataStructures::SecurityIdentity &cliIdentity,
86
  const std::string &username,
87
88
  const std::string &hostName,
  const std::string &comment) {
89
  try {
90
    createAdminUser(cliIdentity, username, comment);
91
    createAdminHost(cliIdentity, hostName, comment);
92
93
94
  } catch(UserError &) {
    throw;
  } catch (exception::Exception &ex) {
95
96
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
  }
97
98
99
100
101
}

//------------------------------------------------------------------------------
// createAdminUser
//------------------------------------------------------------------------------
102
void RdbmsCatalogue::createAdminUser(
103
  const common::dataStructures::SecurityIdentity &cliIdentity,
104
  const std::string &username,
105
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
106
  try {
107
108
109
110
    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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
    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)"
125
      "VALUES("
Steven Murray's avatar
Steven Murray committed
126
127
128
129
130
131
132
133
        ":ADMIN_USER_NAME,"

        ":USER_COMMENT,"

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

134
135
136
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
Steven Murray's avatar
Steven Murray committed
137
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
Steven Murray's avatar
Steven Murray committed
138

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

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

143
    stmt->bindString(":CREATION_LOG_USER_NAME", cliIdentity.username);
144
    stmt->bindString(":CREATION_LOG_HOST_NAME", cliIdentity.host);
145
    stmt->bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
146

147
    stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
148
149
150
    stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
    stmt->bindUint64(":LAST_UPDATE_TIME", now);

Steven Murray's avatar
Steven Murray committed
151
    stmt->executeNonQuery();
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
  } 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 "
170
        "ADMIN_USER_NAME = :ADMIN_USER_NAME";
171
172
173
174
175
    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) {
176
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
Steven Murray's avatar
Steven Murray committed
177
  }
178
179
180
181
182
}

//------------------------------------------------------------------------------
// deleteAdminUser
//------------------------------------------------------------------------------
183
void RdbmsCatalogue::deleteAdminUser(const std::string &username) {
184
  try {
185
    const char *const sql = "DELETE FROM ADMIN_USER WHERE ADMIN_USER_NAME = :ADMIN_USER_NAME";
186
187
188
189
190
191
192
193
194
195
196
197
    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
198
}
199
200
201
202

//------------------------------------------------------------------------------
// getAdminUsers
//------------------------------------------------------------------------------
203
std::list<common::dataStructures::AdminUser>
204
RdbmsCatalogue::getAdminUsers() const {
Steven Murray's avatar
Steven Murray committed
205
206
207
208
209
  try {
    std::list<common::dataStructures::AdminUser> admins;
    const char *const sql =
      "SELECT "
        "ADMIN_USER_NAME AS ADMIN_USER_NAME,"
210

Steven Murray's avatar
Steven Murray committed
211
        "USER_COMMENT AS USER_COMMENT,"
212

213
214
215
        "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,"
216

217
218
219
        "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 "
220
221
      "FROM "
        "ADMIN_USER";
Steven Murray's avatar
Steven Murray committed
222
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
223
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
Steven Murray's avatar
Steven Murray committed
224
225
    while (rset->next()) {
      common::dataStructures::AdminUser admin;
226

Steven Murray's avatar
Steven Murray committed
227
228
      admin.name = rset->columnText("ADMIN_USER_NAME");
      admin.comment = rset->columnText("USER_COMMENT");
229
230
231
232
233
234
      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");
235

Steven Murray's avatar
Steven Murray committed
236
237
      admins.push_back(admin);
    }
238

Steven Murray's avatar
Steven Murray committed
239
    return admins;
240
  } catch (exception::Exception &ex) {
241
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
Steven Murray's avatar
Steven Murray committed
242
  }
243
244
245
246
247
}

//------------------------------------------------------------------------------
// modifyAdminUserComment
//------------------------------------------------------------------------------
248
249
void RdbmsCatalogue::modifyAdminUserComment(const common::dataStructures::SecurityIdentity &cliIdentity,
                                            const std::string &username, const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
250
251
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
252
253
254
255

//------------------------------------------------------------------------------
// createAdminHost
//------------------------------------------------------------------------------
256
void RdbmsCatalogue::createAdminHost(
257
258
259
  const common::dataStructures::SecurityIdentity &cliIdentity,
  const std::string &hostName,
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
260
  try {
261
    if(adminHostExists(hostName)) {
262
263
264
      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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
    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)"
279
      "VALUES("
Steven Murray's avatar
Steven Murray committed
280
281
282
283
284
285
286
287
        ":ADMIN_HOST_NAME,"

        ":USER_COMMENT,"

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

288
289
290
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
Steven Murray's avatar
Steven Murray committed
291
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
Steven Murray's avatar
Steven Murray committed
292

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

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

297
    stmt->bindString(":CREATION_LOG_USER_NAME", cliIdentity.username);
298
    stmt->bindString(":CREATION_LOG_HOST_NAME", cliIdentity.host);
299
    stmt->bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
300

301
    stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
302
303
304
    stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
    stmt->bindUint64(":LAST_UPDATE_TIME", now);

Steven Murray's avatar
Steven Murray committed
305
    stmt->executeNonQuery();
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
  } 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 "
324
        "ADMIN_HOST_NAME = :ADMIN_HOST_NAME";
325
326
327
328
329
    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) {
330
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
Steven Murray's avatar
Steven Murray committed
331
  }
332
333
334
335
336
}

//------------------------------------------------------------------------------
// deleteAdminHost
//------------------------------------------------------------------------------
337
void RdbmsCatalogue::deleteAdminHost(const std::string &hostName) {
338
  try {
339
    const char *const sql = "DELETE FROM ADMIN_HOST WHERE ADMIN_HOST_NAME = :ADMIN_HOST_NAME";
340
341
342
343
344
345
346
347
348
349
350
351
    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
352
}
353
354
355
356

//------------------------------------------------------------------------------
// getAdminHosts
//------------------------------------------------------------------------------
357
std::list<common::dataStructures::AdminHost> RdbmsCatalogue::getAdminHosts() const {
Steven Murray's avatar
Steven Murray committed
358
359
360
361
362
363
364
365
  try {
    std::list<common::dataStructures::AdminHost> hosts;
    const char *const sql =
      "SELECT "
        "ADMIN_HOST_NAME AS ADMIN_HOST_NAME,"

        "USER_COMMENT AS USER_COMMENT,"

366
367
368
        "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
369

370
371
372
        "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 "
373
      "FROM "
374
        "ADMIN_HOST";
Steven Murray's avatar
Steven Murray committed
375
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
376
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
Steven Murray's avatar
Steven Murray committed
377
378
379
380
381
    while (rset->next()) {
      common::dataStructures::AdminHost host;

      host.name = rset->columnText("ADMIN_HOST_NAME");
      host.comment = rset->columnText("USER_COMMENT");
382
383
384
385
386
387
      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
388
389

      hosts.push_back(host);
390
391
    }

Steven Murray's avatar
Steven Murray committed
392
    return hosts;
393
  } catch (exception::Exception &ex) {
394
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
395
396
397
398
399
400
  }
}

//------------------------------------------------------------------------------
// modifyAdminHostComment
//------------------------------------------------------------------------------
401
402
void RdbmsCatalogue::modifyAdminHostComment(const common::dataStructures::SecurityIdentity &cliIdentity,
                                            const std::string &hostName, const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
403
404
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
405
406
407
408

//------------------------------------------------------------------------------
// createStorageClass
//------------------------------------------------------------------------------
409
void RdbmsCatalogue::createStorageClass(
410
411
412
413
  const common::dataStructures::SecurityIdentity &cliIdentity,
  const std::string &name,
  const uint64_t nbCopies,
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
414
  try {
415
    if(storageClassExists(name)) {
416
417
418
      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
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
    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)"
434
        "VALUES("
Steven Murray's avatar
Steven Murray committed
435
436
437
438
439
440
441
442
443
        ":STORAGE_CLASS_NAME,"
        ":NB_COPIES,"

        ":USER_COMMENT,"

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

444
445
446
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
Steven Murray's avatar
Steven Murray committed
447
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
Steven Murray's avatar
Steven Murray committed
448

449
    stmt->bindString(":STORAGE_CLASS_NAME", name);
450
    stmt->bindUint64(":NB_COPIES", nbCopies);
Steven Murray's avatar
Steven Murray committed
451

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

454
    stmt->bindString(":CREATION_LOG_USER_NAME", cliIdentity.username);
455
    stmt->bindString(":CREATION_LOG_HOST_NAME", cliIdentity.host);
456
    stmt->bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
457

458
    stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
459
460
461
    stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
    stmt->bindUint64(":LAST_UPDATE_TIME", now);

Steven Murray's avatar
Steven Murray committed
462
    stmt->executeNonQuery();
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
  } 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 "
481
        "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME";
482
483
484
485
486
    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) {
487
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
Steven Murray's avatar
Steven Murray committed
488
  }
489
490
491
492
493
}

//------------------------------------------------------------------------------
// deleteStorageClass
//------------------------------------------------------------------------------
494
495
496
497
498
499
void RdbmsCatalogue::deleteStorageClass(const std::string &name) {
  try {
    const char *const sql =
      "DELETE FROM "
        "STORAGE_CLASS "
      "WHERE "
500
        "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME";
Steven Murray's avatar
Steven Murray committed
501
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
502
503
504
505

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

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

//------------------------------------------------------------------------------
// getStorageClasses
//------------------------------------------------------------------------------
519
std::list<common::dataStructures::StorageClass>
520
  RdbmsCatalogue::getStorageClasses() const {
Steven Murray's avatar
Steven Murray committed
521
522
523
524
525
  try {
    std::list<common::dataStructures::StorageClass> storageClasses;
    const char *const sql =
      "SELECT "
        "STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME,"
526
        "NB_COPIES AS NB_COPIES,"
Steven Murray's avatar
Steven Murray committed
527
528
529

        "USER_COMMENT AS USER_COMMENT,"

530
531
532
        "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
533

534
535
536
        "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 "
537
538
      "FROM "
        "STORAGE_CLASS";
Steven Murray's avatar
Steven Murray committed
539
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
540
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
Steven Murray's avatar
Steven Murray committed
541
542
543
544
545
546
    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");
547
548
549
550
551
552
      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
553
554

      storageClasses.push_back(storageClass);
555
556
    }

Steven Murray's avatar
Steven Murray committed
557
    return storageClasses;
558
559
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
560
561
562
563
564
565
  }
}

//------------------------------------------------------------------------------
// modifyStorageClassNbCopies
//------------------------------------------------------------------------------
566
void RdbmsCatalogue::modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t nbCopies) {
Steven Murray's avatar
Steven Murray committed
567
568
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
569
570
571
572

//------------------------------------------------------------------------------
// modifyStorageClassComment
//------------------------------------------------------------------------------
573
void RdbmsCatalogue::modifyStorageClassComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
574
575
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
576
577
578
579

//------------------------------------------------------------------------------
// createTapePool
//------------------------------------------------------------------------------
580
void RdbmsCatalogue::createTapePool(
581
  const common::dataStructures::SecurityIdentity &cliIdentity,
582
583
584
585
  const std::string &name,
  const uint64_t nbPartialTapes,
  const bool encryptionValue,
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
586
  try {
587
588
589
590
    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
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
    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)"
607
        "VALUES("
Steven Murray's avatar
Steven Murray committed
608
609
610
611
612
613
614
615
616
617
        ":TAPE_POOL_NAME,"
        ":NB_PARTIAL_TAPES,"
        ":IS_ENCRYPTED,"

        ":USER_COMMENT,"

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

618
619
620
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
Steven Murray's avatar
Steven Murray committed
621
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
Steven Murray's avatar
Steven Murray committed
622

623
    stmt->bindString(":TAPE_POOL_NAME", name);
624
625
    stmt->bindUint64(":NB_PARTIAL_TAPES", nbPartialTapes);
    stmt->bindUint64(":IS_ENCRYPTED", encryptionValue);
Steven Murray's avatar
Steven Murray committed
626

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

629
    stmt->bindString(":CREATION_LOG_USER_NAME", cliIdentity.username);
630
    stmt->bindString(":CREATION_LOG_HOST_NAME", cliIdentity.host);
631
    stmt->bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
632

633
    stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
634
635
636
    stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
    stmt->bindUint64(":LAST_UPDATE_TIME", now);

Steven Murray's avatar
Steven Murray committed
637
    stmt->executeNonQuery();
638
639
  } catch(UserError &) {
    throw;
640
641
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
Steven Murray's avatar
Steven Murray committed
642
  }
643
644
}

645
646
647
648
649
650
651
652
653
654
655
//------------------------------------------------------------------------------
// 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 "
656
        "TAPE_POOL_NAME = :TAPE_POOL_NAME";
657
658
659
660
661
662
663
664
665
    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());
  }
}

666
667
668
//------------------------------------------------------------------------------
// deleteTapePool
//------------------------------------------------------------------------------
669
void RdbmsCatalogue::deleteTapePool(const std::string &name) {
670
  try {
671
    const char *const sql = "DELETE FROM TAPE_POOL WHERE TAPE_POOL_NAME = :TAPE_POOL_NAME";
672
673
674
675
676
677
678
679
680
681
682
683
    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
684
}
685
686
687
688

//------------------------------------------------------------------------------
// getTapePools
//------------------------------------------------------------------------------
689
std::list<common::dataStructures::TapePool>
690
  RdbmsCatalogue::getTapePools() const {
Steven Murray's avatar
Steven Murray committed
691
  try {
692
    std::list<common::dataStructures::TapePool> pools;
Steven Murray's avatar
Steven Murray committed
693
694
    const char *const sql =
      "SELECT "
695
        "TAPE_POOL_NAME AS TAPE_POOL_NAME,"
Steven Murray's avatar
Steven Murray committed
696
        "NB_PARTIAL_TAPES AS NB_PARTIAL_TAPES,"
697
        "IS_ENCRYPTED AS IS_ENCRYPTED,"
Steven Murray's avatar
Steven Murray committed
698
699
700

        "USER_COMMENT AS USER_COMMENT,"

701
702
703
        "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
704

705
706
707
        "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 "
708
709
      "FROM "
        "TAPE_POOL";
Steven Murray's avatar
Steven Murray committed
710
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
711
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
Steven Murray's avatar
Steven Murray committed
712
713
714
715
716
717
718
    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");
719
720
721
722
723
724
      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
725
726

      pools.push_back(pool);
727
728
    }

Steven Murray's avatar
Steven Murray committed
729
    return pools;
730
731
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
732
733
734
735
736
737
  }
}

//------------------------------------------------------------------------------
// modifyTapePoolNbPartialTapes
//------------------------------------------------------------------------------
738
void RdbmsCatalogue::modifyTapePoolNbPartialTapes(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const uint64_t nbPartialTapes) {
Steven Murray's avatar
Steven Murray committed
739
740
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
741
742
743
744

//------------------------------------------------------------------------------
// modifyTapePoolComment
//------------------------------------------------------------------------------
745
void RdbmsCatalogue::modifyTapePoolComment(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
746
747
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
748
749
750
751

//------------------------------------------------------------------------------
// setTapePoolEncryption
//------------------------------------------------------------------------------
752
void RdbmsCatalogue::setTapePoolEncryption(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &name, const bool encryptionValue) {
Steven Murray's avatar
Steven Murray committed
753
754
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
755
756
757
758

//------------------------------------------------------------------------------
// createArchiveRoute
//------------------------------------------------------------------------------
759
void RdbmsCatalogue::createArchiveRoute(
760
761
762
763
764
  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
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
  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)"
782
      "VALUES("
Steven Murray's avatar
Steven Murray committed
783
784
785
786
787
788
789
790
791
792
        ":STORAGE_CLASS_NAME,"
        ":COPY_NB,"
        ":TAPE_POOL_NAME,"

        ":USER_COMMENT,"

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

793
794
795
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
Steven Murray's avatar
Steven Murray committed
796
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
Steven Murray's avatar
Steven Murray committed
797

798
    stmt->bindString(":STORAGE_CLASS_NAME", storageClassName);
799
    stmt->bindUint64(":COPY_NB", copyNb);
800
    stmt->bindString(":TAPE_POOL_NAME", tapePoolName);
Steven Murray's avatar
Steven Murray committed
801

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

804
    stmt->bindString(":CREATION_LOG_USER_NAME", cliIdentity.username);
805
    stmt->bindString(":CREATION_LOG_HOST_NAME", cliIdentity.host);
806
    stmt->bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
807

808
    stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
809
810
811
    stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
    stmt->bindUint64(":LAST_UPDATE_TIME", now);

Steven Murray's avatar
Steven Murray committed
812
    stmt->executeNonQuery();
813
814
  } catch(exception::Exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
Steven Murray's avatar
Steven Murray committed
815
  }
816
817
818
819
820
}

//------------------------------------------------------------------------------
// deleteArchiveRoute
//------------------------------------------------------------------------------
821
void RdbmsCatalogue::deleteArchiveRoute(const std::string &storageClassName, const uint64_t copyNb) {
822
823
824
825
826
827
  try {
    const char *const sql =
      "DELETE FROM "
        "ARCHIVE_ROUTE "
      "WHERE "
        "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME AND "
828
        "COPY_NB = :COPY_NB";
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
    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
845
}
846
847
848
849

//------------------------------------------------------------------------------
// getArchiveRoutes
//------------------------------------------------------------------------------
850
std::list<common::dataStructures::ArchiveRoute>
851
  RdbmsCatalogue::getArchiveRoutes() const {
Steven Murray's avatar
Steven Murray committed
852
853
854
855
856
  try {
    std::list<common::dataStructures::ArchiveRoute> routes;
    const char *const sql =
      "SELECT "
        "STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME,"
857
858
        "COPY_NB AS COPY_NB,"
        "TAPE_POOL_NAME AS TAPE_POOL_NAME,"
Steven Murray's avatar
Steven Murray committed
859
860
861

        "USER_COMMENT AS USER_COMMENT,"

862
863
864
        "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
865

866
867
868
        "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 "
869
870
      "FROM "
        "ARCHIVE_ROUTE";
Steven Murray's avatar
Steven Murray committed
871
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
872
    std::unique_ptr<DbRset> rset(stmt->executeQuery());
Steven Murray's avatar
Steven Murray committed
873
874
875
876
877
878
879
    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");
880
881
882
883
884
885
      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
886
887

      routes.push_back(route);
888
889
    }

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

//------------------------------------------------------------------------------
// modifyArchiveRouteTapePoolName
//------------------------------------------------------------------------------
899
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
900
901
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
902
903
904
905

//------------------------------------------------------------------------------
// modifyArchiveRouteComment
//------------------------------------------------------------------------------
906
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
907
908
  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
}
909
910
911
912

//------------------------------------------------------------------------------
// createLogicalLibrary
//------------------------------------------------------------------------------
913
void RdbmsCatalogue::createLogicalLibrary(
914
915
916
  const common::dataStructures::SecurityIdentity &cliIdentity,
  const std::string &name,
  const std::string &comment) {
Steven Murray's avatar
Steven Murray committed
917
  try {
918
    if(logicalLibraryExists(name)) {
919
920
921
      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
922
923
924
925
926
927
928
929
930
931
932
933
934
935
    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)"
936
        "VALUES("
Steven Murray's avatar
Steven Murray committed
937
938
939
940
941
942
943
944
        ":LOGICAL_LIBRARY_NAME,"

        ":USER_COMMENT,"

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

945
946
947
        ":LAST_UPDATE_USER_NAME,"
        ":LAST_UPDATE_HOST_NAME,"
        ":LAST_UPDATE_TIME)";
Steven Murray's avatar
Steven Murray committed
948
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
Steven Murray's avatar
Steven Murray committed
949

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

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

954
    stmt->bindString(":CREATION_LOG_USER_NAME", cliIdentity.username);
955
    stmt->bindString(":CREATION_LOG_HOST_NAME", cliIdentity.host);
956
    stmt->bindUint64(":CREATION_LOG_TIME", now);
Steven Murray's avatar
Steven Murray committed
957

958
    stmt->bindString(":LAST_UPDATE_USER_NAME", cliIdentity.username);
959
960
961
    stmt->bindString(":LAST_UPDATE_HOST_NAME", cliIdentity.host);
    stmt->bindUint64(":LAST_UPDATE_TIME", now);

Steven Murray's avatar
Steven Murray committed
962
    stmt->executeNonQuery();
963
964
  } catch(UserError &) {
    throw;
Steven Murray's avatar
Steven Murray committed
965
966
967
  } catch(std::exception &ex) {
    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.what());
  }
968
969
}

970
971
972
973
974
975
976
977
978
979
980
//------------------------------------------------------------------------------
// 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 "
981
        "LOGICAL_LIBRARY_NAME = :LOGICAL_LIBRARY_NAME";
982
983
984
985
986
987
988
989
990
    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());
  }
}

991
992
993
//------------------------------------------------------------------------------
// deleteLogicalLibrary
//------------------------------------------------------------------------------
994
void RdbmsCatalogue::deleteLogicalLibrary(const std::string &name) {
995
  try {
996
    const char *const sql = "DELETE FROM LOGICAL_LIBRARY WHERE LOGICAL_LIBRARY_NAME = :LOGICAL_LIBRARY_NAME";
997
998
999
1000
    std::unique_ptr<DbStmt> stmt(m_conn->createStmt(sql));
    stmt->bindString(":LOGICAL_LIBRARY_NAME", name);
    stmt->executeNonQuery();