13.null_pk.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * PROGRAM: Object oriented API samples.
  3. * MODULE: 13.null_pk.cpp
  4. * DESCRIPTION: Changing metadata, passed from DB engine, and using modified
  5. * copy later. Useful for changing nullability or coercing datatype.
  6. * In this sample we insert NULLs in all columns.
  7. *
  8. * Example for the following interfaces:
  9. * IMessageMetadata - describe input and output data format
  10. * IMetadataBuilder - tool to modify/create metadata
  11. *
  12. * The contents of this file are subject to the Interbase Public
  13. * License Version 1.0 (the "License"); you may not use this file
  14. * except in compliance with the License. You may obtain a copy
  15. * of the License at http://www.Inprise.com/IPL.html
  16. *
  17. * Software distributed under the License is distributed on an
  18. * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
  19. * or implied. See the License for the specific language governing
  20. * rights and limitations under the License.
  21. *
  22. * The Original Code was created by Inprise Corporation
  23. * and its predecessors. Portions created by Inprise Corporation are
  24. * Copyright (C) Inprise Corporation.
  25. *
  26. * All Rights Reserved.
  27. * Contributor(s): ______________________________________.
  28. * Alex Peshkov, 2013, 2020
  29. */
  30. #include "ifaceExamples.h"
  31. static IMaster* master = fb_get_master_interface();
  32. int main()
  33. {
  34. int rc = 0;
  35. // set default password if none specified in environment
  36. setenv("ISC_USER", "sysdba", 0);
  37. setenv("ISC_PASSWORD", "masterkey", 0);
  38. // status vector and main dispatcher
  39. ThrowStatusWrapper status(master->getStatus());
  40. IProvider* prov = master->getDispatcher();
  41. // declare pointers to required interfaces
  42. IAttachment* att = NULL;
  43. ITransaction* tra = NULL;
  44. // Interface executes prepared SQL statement
  45. IStatement* stmt = NULL;
  46. // Interfaces provides access to format of data in messages
  47. IMessageMetadata* meta = NULL;
  48. // Interface makes it possible to change format of data or define it yourself
  49. IMetadataBuilder* builder = NULL;
  50. const char* sqlStr =
  51. "Insert into COUNTRY values(?, ?)";
  52. try
  53. {
  54. // attach employee db
  55. att = prov->attachDatabase(&status, "employee", 0, NULL);
  56. // start transaction
  57. tra = att->startTransaction(&status, 0, NULL);
  58. // prepare statement
  59. stmt = att->prepare(&status, tra, 0, sqlStr, SAMPLES_DIALECT, 0);
  60. // build metadata
  61. meta = stmt->getInputMetadata(&status);
  62. builder = meta->getBuilder(&status);
  63. // set nullability on fields
  64. for (unsigned n = 0; n < meta->getCount(&status); ++n)
  65. {
  66. unsigned t = meta->getType(&status, n);
  67. builder->setType(&status, n, t | 1);
  68. }
  69. // IMetadata should be ready
  70. meta->release();
  71. meta = NULL;
  72. meta = builder->getMetadata(&status);
  73. // no need in builder any more
  74. builder->release();
  75. builder = NULL;
  76. // allocate buffer on stack
  77. char buffer[256];
  78. unsigned len = meta->getMessageLength(&status);
  79. if (len > sizeof(buffer))
  80. {
  81. throw "Input message length too big - can't continue";
  82. }
  83. // all null
  84. for (unsigned n = 0; n < meta->getCount(&status); ++n)
  85. {
  86. short* flag = (short*)&buffer[meta->getNullOffset(&status, n)];
  87. *flag = -1;
  88. // setting value for NULL field makes no sense - skip it
  89. }
  90. // this should throw - passing NULLs to not-NULL columns
  91. // can work only with something like before insert trigger
  92. stmt->execute(&status, tra, meta, buffer, NULL, NULL);
  93. // close interfaces
  94. stmt->free(&status);
  95. stmt = NULL;
  96. meta->release();
  97. meta = NULL;
  98. tra->rollback(&status);
  99. tra = NULL;
  100. att->detach(&status);
  101. att = NULL;
  102. }
  103. catch (const FbException& error)
  104. {
  105. // handle error
  106. rc = 1;
  107. char buf[256];
  108. master->getUtilInterface()->formatStatus(buf, sizeof(buf), error.getStatus());
  109. fprintf(stderr, "%s\n", buf);
  110. }
  111. // release interfaces after error caught
  112. if (builder)
  113. builder->release();
  114. if (meta)
  115. meta->release();
  116. if (stmt)
  117. stmt->release();
  118. if (tra)
  119. tra->release();
  120. if (att)
  121. att->release();
  122. prov->release();
  123. status.dispose();
  124. return rc;
  125. }