| 101 | } |
| 102 | |
| 103 | bool BTreeDatabase::open() { |
| 104 | WriteLocker writeLocker(m_lock); |
| 105 | if (m_open) |
| 106 | return false; |
| 107 | |
| 108 | if (!m_device) |
| 109 | throw DBException("BlockStorage::open called with no IODevice set"); |
| 110 | |
| 111 | if (!m_device->isOpen()) |
| 112 | m_device->open(IOMode::ReadWrite); |
| 113 | |
| 114 | m_open = true; |
| 115 | |
| 116 | if (m_device->size() > 0) { |
| 117 | DataStreamIODevice ds(m_device); |
| 118 | ds.seek(0); |
| 119 | |
| 120 | auto magic = ds.readBytes(VersionMagicSize); |
| 121 | if (magic != ByteArray::fromCString(VersionMagic)) |
| 122 | throw DBException("Device is not a valid BTreeDatabase file"); |
| 123 | |
| 124 | m_blockSize = ds.read<uint32_t>(); |
| 125 | |
| 126 | auto contentIdentifier = ds.readBytes(ContentIdentifierStringSize); |
| 127 | contentIdentifier.appendByte('\0'); |
| 128 | m_contentIdentifier = String(contentIdentifier.ptr()); |
| 129 | m_keySize = ds.read<uint32_t>(); |
| 130 | |
| 131 | readRoot(); |
| 132 | |
| 133 | if (m_device->isWritable()) |
| 134 | m_device->resize(m_deviceSize); |
| 135 | |
| 136 | return false; |
| 137 | |
| 138 | } else { |
| 139 | m_deviceSize = HeaderSize; |
| 140 | m_device->resize(m_deviceSize); |
| 141 | m_headFreeIndexBlock = InvalidBlockIndex; |
| 142 | |
| 143 | DataStreamIODevice ds(m_device); |
| 144 | ds.seek(0); |
| 145 | |
| 146 | ds.writeData(VersionMagic, VersionMagicSize); |
| 147 | ds.write<uint32_t>(m_blockSize); |
| 148 | |
| 149 | if (m_contentIdentifier.empty()) |
| 150 | throw DBException("Opening new database and no content identifier set!"); |
| 151 | |
| 152 | if (m_contentIdentifier.utf8Size() > ContentIdentifierStringSize) |
| 153 | throw DBException("contentIdentifier in BTreeDatabase implementation is greater than maximum identifier length"); |
| 154 | if (m_keySize == 0) |
| 155 | throw DBException("key size is not set opening a new BTreeDatabase"); |
| 156 | |
| 157 | ByteArray contentIdentifier = m_contentIdentifier.utf8Bytes(); |
| 158 | contentIdentifier.resize(ContentIdentifierStringSize, 0); |
| 159 | ds.writeBytes(contentIdentifier); |
| 160 | ds.write(m_keySize); |
nothing calls this directly
no test coverage detected