use of org.h2.engine.Database in project h2database by h2database.
the class LobStorageMap method createClob.
@Override
public Value createClob(Reader reader, long maxLength) {
init();
int type = Value.CLOB;
try {
// we multiple by 3 here to get the worst-case size in bytes
if (maxLength != -1 && maxLength * 3 <= database.getMaxLengthInplaceLob()) {
char[] small = new char[(int) maxLength];
int len = IOUtils.readFully(reader, small, (int) maxLength);
if (len > maxLength) {
throw new IllegalStateException("len > blobLength, " + len + " > " + maxLength);
}
byte[] utf8 = new String(small, 0, len).getBytes(StandardCharsets.UTF_8);
if (utf8.length > database.getMaxLengthInplaceLob()) {
throw new IllegalStateException("len > maxinplace, " + utf8.length + " > " + database.getMaxLengthInplaceLob());
}
return ValueLobDb.createSmallLob(type, utf8);
}
if (maxLength < 0) {
maxLength = Long.MAX_VALUE;
}
CountingReaderInputStream in = new CountingReaderInputStream(reader, maxLength);
ValueLobDb lob = createLob(in, type);
// the length is not correct
lob = ValueLobDb.create(type, database, lob.getTableId(), lob.getLobId(), null, in.getLength());
return lob;
} catch (IllegalStateException e) {
throw DbException.get(ErrorCode.OBJECT_CLOSED, e);
} catch (IOException e) {
throw DbException.convertIOException(e, null);
}
}
use of org.h2.engine.Database in project h2database by h2database.
the class LobStorageMap method init.
@Override
public void init() {
if (init) {
return;
}
init = true;
Store s = database.getMvStore();
MVStore mvStore;
if (s == null) {
// in-memory database
mvStore = MVStore.open(null);
} else {
mvStore = s.getStore();
}
lobMap = mvStore.openMap("lobMap");
refMap = mvStore.openMap("lobRef");
dataMap = mvStore.openMap("lobData");
streamStore = new StreamStore(dataMap);
// garbage collection of the last blocks
if (database.isReadOnly()) {
return;
}
if (dataMap.isEmpty()) {
return;
}
// search for the last block
// (in theory, only the latest lob can have unreferenced blocks,
// but the latest lob could be a copy of another one, and
// we don't know that, so we iterate over all lobs)
long lastUsedKey = -1;
for (Entry<Long, Object[]> e : lobMap.entrySet()) {
long lobId = e.getKey();
Object[] v = e.getValue();
byte[] id = (byte[]) v[0];
long max = streamStore.getMaxBlockKey(id);
// a lob may not have a referenced blocks if data is kept inline
if (max != -1 && max > lastUsedKey) {
lastUsedKey = max;
if (TRACE) {
trace("lob " + lobId + " lastUsedKey=" + lastUsedKey);
}
}
}
if (TRACE) {
trace("lastUsedKey=" + lastUsedKey);
}
// delete all blocks that are newer
while (true) {
Long last = dataMap.lastKey();
if (last == null || last <= lastUsedKey) {
break;
}
if (TRACE) {
trace("gc " + last);
}
dataMap.remove(last);
}
// don't re-use block ids, except at the very end
Long last = dataMap.lastKey();
if (last != null) {
streamStore.setNextKey(last + 1);
}
}
use of org.h2.engine.Database in project h2database by h2database.
the class LobStorageMap method copyLob.
@Override
public ValueLobDb copyLob(ValueLobDb old, int tableId, long length) {
init();
int type = old.getType();
long oldLobId = old.getLobId();
long oldLength = old.getPrecision();
if (oldLength != length) {
throw DbException.throwInternalError("Length is different");
}
Object[] value = lobMap.get(oldLobId);
value = value.clone();
byte[] streamStoreId = (byte[]) value[0];
long lobId = generateLobId();
value[1] = tableId;
lobMap.put(lobId, value);
Object[] key = { streamStoreId, lobId };
refMap.put(key, Boolean.TRUE);
ValueLobDb lob = ValueLobDb.create(type, database, tableId, lobId, null, length);
if (TRACE) {
trace("copy " + old.getTableId() + "/" + old.getLobId() + " > " + tableId + "/" + lobId);
}
return lob;
}
use of org.h2.engine.Database in project h2database by h2database.
the class PageStore method openMetaIndex.
private void openMetaIndex() {
CreateTableData data = new CreateTableData();
ArrayList<Column> cols = data.columns;
cols.add(new Column("ID", Value.INT));
cols.add(new Column("TYPE", Value.INT));
cols.add(new Column("PARENT", Value.INT));
cols.add(new Column("HEAD", Value.INT));
cols.add(new Column("OPTIONS", Value.STRING));
cols.add(new Column("COLUMNS", Value.STRING));
metaSchema = new Schema(database, 0, "", null, true);
data.schema = metaSchema;
data.tableName = "PAGE_INDEX";
data.id = META_TABLE_ID;
data.temporary = false;
data.persistData = true;
data.persistIndexes = true;
data.create = false;
data.session = pageStoreSession;
metaTable = new RegularTable(data);
metaIndex = (PageDataIndex) metaTable.getScanIndex(pageStoreSession);
metaObjects.clear();
metaObjects.put(-1, metaIndex);
}
use of org.h2.engine.Database in project h2database by h2database.
the class PageStore method addMeta.
/**
* Add the meta data of an index.
*
* @param index the index to add
* @param session the session
*/
public void addMeta(PageIndex index, Session session) {
Table table = index.getTable();
if (SysProperties.CHECK) {
if (!table.isTemporary()) {
// the Database lock before we take the PageStore lock
synchronized (database) {
synchronized (this) {
database.verifyMetaLocked(session);
}
}
}
}
synchronized (this) {
int type = index instanceof PageDataIndex ? META_TYPE_DATA_INDEX : META_TYPE_BTREE_INDEX;
IndexColumn[] columns = index.getIndexColumns();
StatementBuilder buff = new StatementBuilder();
for (IndexColumn col : columns) {
buff.appendExceptFirst(",");
int id = col.column.getColumnId();
buff.append(id);
int sortType = col.sortType;
if (sortType != 0) {
buff.append('/');
buff.append(sortType);
}
}
String columnList = buff.toString();
CompareMode mode = table.getCompareMode();
String options = mode.getName() + "," + mode.getStrength() + ",";
if (table.isTemporary()) {
options += "temp";
}
options += ",";
if (index instanceof PageDelegateIndex) {
options += "d";
}
options += "," + mode.isBinaryUnsigned();
Row row = metaTable.getTemplateRow();
row.setValue(0, ValueInt.get(index.getId()));
row.setValue(1, ValueInt.get(type));
row.setValue(2, ValueInt.get(table.getId()));
row.setValue(3, ValueInt.get(index.getRootPageId()));
row.setValue(4, ValueString.get(options));
row.setValue(5, ValueString.get(columnList));
row.setKey(index.getId() + 1);
metaIndex.add(session, row);
}
}
Aggregations