| 172 | } |
| 173 | |
| 174 | bool Mapping::DbHandle::attach(const char* aliasDb, ICryptKeyCallback* cryptCb) |
| 175 | { |
| 176 | FbLocalStatus st; |
| 177 | bool down = false; // true if on attach db is shutdown |
| 178 | |
| 179 | if (hasData()) |
| 180 | { |
| 181 | MAP_DEBUG(fprintf(stderr, "Already attached %s\n", aliasDb)); |
| 182 | return down; |
| 183 | } |
| 184 | |
| 185 | DispatcherPtr prov; |
| 186 | if (cryptCb) |
| 187 | { |
| 188 | prov->setDbCryptCallback(&st, cryptCb); |
| 189 | check("IProvider::setDbCryptCallback", &st); |
| 190 | } |
| 191 | |
| 192 | ClumpletWriter embeddedSysdba(ClumpletWriter::dpbList, MAX_DPB_SIZE); |
| 193 | embeddedSysdba.insertString(isc_dpb_user_name, DBA_USER_NAME, fb_strlen(DBA_USER_NAME)); |
| 194 | embeddedSysdba.insertByte(isc_dpb_sec_attach, TRUE); |
| 195 | embeddedSysdba.insertString(isc_dpb_config, ParsedList::getNonLoopbackProviders(aliasDb)); |
| 196 | embeddedSysdba.insertByte(isc_dpb_map_attach, TRUE); |
| 197 | embeddedSysdba.insertByte(isc_dpb_no_db_triggers, TRUE); |
| 198 | |
| 199 | MAP_DEBUG(fprintf(stderr, "Attach %s\n", aliasDb)); |
| 200 | IAttachment* att = prov->attachDatabase(&st, aliasDb, |
| 201 | embeddedSysdba.getBufferLength(), embeddedSysdba.getBuffer()); |
| 202 | |
| 203 | if (st->getState() & IStatus::STATE_ERRORS) |
| 204 | { |
| 205 | const ISC_STATUS* s = st->getErrors(); |
| 206 | MAP_DEBUG(isc_print_status(s)); |
| 207 | bool missing = fb_utils::containsErrorCode(s, isc_io_error); |
| 208 | down = fb_utils::containsErrorCode(s, isc_shutdown); |
| 209 | if (!(missing || down)) |
| 210 | check("IProvider::attachDatabase", &st); |
| 211 | |
| 212 | // down/missing DB is not a reason to fail mapping |
| 213 | } |
| 214 | else |
| 215 | assignRefNoIncr(att); |
| 216 | |
| 217 | MAP_DEBUG(fprintf(stderr, "Att=%p\n", att)); |
| 218 | |
| 219 | return down; |
| 220 | } |
| 221 | |
| 222 | |
| 223 | FB_SIZE_T Mapping::Map::hash(const Map& value, FB_SIZE_T hashSize) |
no test coverage detected