private void checkValue(Storeable value) throws ColumnFormatException { if (value == null) { throw new IllegalArgumentException("Value is null"); } try { for (int i = 0; i < columnTypes.size(); ++i) { if (value.getColumnAt(i) != null && !columnTypes.get(i).equals(value.getColumnAt(i).getClass())) { throw new ColumnFormatException( "Wrong column type. was: " + value.getColumnAt(i).getClass().toString() + "; expected: " + columnTypes.get(i)); } } boolean unusedValue = true; try { value.getColumnAt(columnTypes.size()); } catch (IndexOutOfBoundsException e) { unusedValue = false; } if (unusedValue) { throw new ColumnFormatException("Alien value"); } } catch (IndexOutOfBoundsException e) { throw new ColumnFormatException("Alien value", e); } }
public int uncommittedChanges() { Set<Map.Entry<String, Storeable>> indexedSet = tableIndexedData.entrySet(); Set<Map.Entry<String, Storeable>> diskSet = tableOnDisk.entrySet(); int count = 0; Iterator<Map.Entry<String, Storeable>> iter1 = indexedSet.iterator(); Iterator<Map.Entry<String, Storeable>> iter2 = diskSet.iterator(); while (iter1.hasNext()) { Map.Entry<String, Storeable> next = iter1.next(); Storeable entryOnDisk = tableOnDisk.get(next.getKey()); if (entryOnDisk == null) { // записи на диске нет, то она изменение ++count; } else if (!entryOnDisk.equals(next.getValue())) { // запись на диске есть, но она другая, тоже изменение ++count; } } while (iter2.hasNext()) { Map.Entry<String, Storeable> next = iter2.next(); Storeable entryIndexed = tableIndexedData.get(next.getKey()); if (entryIndexed == null) { // на диске есть, индексированной нет, изменение ++count; } } return count; }
@Test(expected = IllegalStateException.class) public void closeTablePutValueShouldFail() throws Exception { dataTable.close(); Storeable value = new StoreableDataValue(types); value.setColumnAt(0, 5); value.setColumnAt(1, "book"); dataTable.put("key", value); }
@Test public void removeValidKeyTest() { Assert.assertNull(dataTable.remove("chair")); Storeable firstValue = new StoreableDataValue(types); firstValue.setColumnAt(0, 2); firstValue.setColumnAt(1, "black"); dataTable.put("cats", firstValue); Assert.assertEquals(dataTable.remove("cats"), firstValue); }
@Test public void getValidKey() throws Exception { Assert.assertNull(dataTable.get("one")); Storeable value = new StoreableDataValue(types); value.setColumnAt(0, 5); value.setColumnAt(1, "book"); dataTable.put("favourite", value); Assert.assertEquals(dataTable.get("favourite"), value); }
/** * Устанавливает значение по указанному ключу. * * @param key Ключ для нового значения. Не может быть null. * @param value Новое значение. Не может быть null. * @return Значение, которое было записано по этому ключу ранее. Если ранее значения не было * записано, возвращает null. * @throws IllegalArgumentException Если значение параметров key или value является null. * @throws ru.fizteh.fivt.storage.structured.ColumnFormatException - при попытке передать * Storeable с колонками другого типа. */ @Override public Storeable put(String key, Storeable value) throws ColumnFormatException { checkKey(key); checkValue(value); Storeable oldValue = tableIndexedData.get(key); if (oldValue == null || !oldValue.equals(value)) { HashcodeDestination dest = new HashcodeDestination(key); tableFileModified[dest.getDir()][dest.getFile()] = true; tableIndexedData.put(key, value); } return oldValue; }
public static String serialize(Storeable s, List<Class<?>> types) { Document document; try { document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); Element root = document.createElement("row"); for (int i = 0; i < types.size(); ++i) { Object obj = s.getColumnAt(i); Element child; if (obj == null) { child = document.createElement("null"); } else { child = document.createElement("col"); child.setTextContent(obj.toString()); } root.appendChild(child); } document.appendChild(root); } catch (IndexOutOfBoundsException | ParserConfigurationException e) { throw new ColumnFormatException(); } StringWriter writer; try { Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); writer = new StringWriter(); transformer.transform(new DOMSource(document), new StreamResult(writer)); } catch (TransformerException e) { throw new RuntimeException("FATAL: Unable to initialize converter"); } return writer.getBuffer().toString().replaceAll("\n|\r", ""); }
public static boolean validate(Storeable s, List<Class<?>> types) { for (int classID = 0; classID < types.size(); ++classID) { try { Object object = s.getColumnAt(classID); if (object == null) { continue; } if (!object.getClass().equals(types.get(classID))) { return false; } } catch (IndexOutOfBoundsException e) { return false; } } try { s.getColumnAt(types.size()); return false; } catch (IndexOutOfBoundsException e) { return true; } }
@Test public void putValidValueTest() { Storeable firstValue = new StoreableDataValue(types); firstValue.setColumnAt(0, 56); firstValue.setColumnAt(1, "pages"); Storeable secondValue = new StoreableDataValue(types); secondValue.setColumnAt(0, 40); secondValue.setColumnAt(1, "pages"); dataTable.put("qwerty", secondValue); Assert.assertEquals(dataTable.put("qwerty", firstValue), secondValue); Assert.assertNull(dataTable.put("key", firstValue)); }