/** * Store a list of records. A record that already exists will be updated. A transaction will be * used. If there is a problem with storing one of the records the whole operation will be rolled * back. * * @param records - the records to store or update * @throws DBException in case of a database problem * @throws IllegalArgumentException when the given record cannot be stored * @throws IllegalStateException when the columns that are part of the primary key have not all * been assigned a value */ public void store(List<Record> records) throws DBException, IllegalArgumentException, IllegalStateException { Boolean[] insert = new Boolean[records.size()]; startTransaction(); int r = 0; try { for (Record record : records) if (isStorable(record)) insert[r++] = doStore(record); else throw new IllegalArgumentException( String.format("Record (%s) cannot be stored!", record.toString(false))); } catch (Exception e) { rollbackTransactions(); throw new DBException(e); } commitTransaction(); // Inform client: r = 0; for (Record record : records) { Boolean inserted = insert[r++]; if (inserted == null) continue; // record was unchanged else if (inserted) client.storageEvent(RecordOperation.Inserted, record.getReference(), this); else client.storageEvent(RecordOperation.Updated, record.getReference(), this); } }
/* (non-Javadoc) * @see uk.ac.ucl.excites.sapelli.collector.db.ProjectStore#serialise(uk.ac.ucl.excites.sapelli.collector.model.Project, java.io.OutputStream) */ @Override public void serialise(Project project, OutputStream out) throws IOException { // Project XML bytes: InputStream projectXMLFileIn = new FileInputStream(ProjectLoader.GetProjectXMLFile(getProjectFolder(project))); ByteArrayOutputStream projectXMLBytesOut = new ByteArrayOutputStream(); IOUtils.copy(projectXMLFileIn, projectXMLBytesOut); projectXMLFileIn.close(); projectXMLBytesOut.close(); // FSI record bytes for each Form: List<byte[]> fsiRecordBytesList = new ArrayList<>(project.getNumberOfForms()); for (Form form : project.getForms()) { Record fsiRecord = retrieveFSIRecord(form); // we query the projectStore to save time... if (fsiRecord == null) // ... but we don't rely on it: fsiRecord = getFSIRecord(form); // may trigger optionality analysis fsiRecordBytesList.add(fsiRecord.toBytes(true)); } // Create serialisedProject valueSet: ValueSet<ColumnSet> serialisedProjectVS = new ValueSet<ColumnSet>( PROJECT_SERIALISIATION_CS, projectXMLBytesOut.toByteArray(), fsiRecordBytesList); // Return as byte array: BitOutputStream bitsOut = new BitWrapOutputStream(out); serialisedProjectVS.writeToBitStream(bitsOut, true); bitsOut.flush(); }
/** * Insert a single record, if it already exists a DuplicateException will be thrown. Note that * this method does not start a new transaction. If this is a desired the client code should take * care of that by first calling {@link #startTransaction()}. However, if an error occurs any open * transaction will be rolled back! * * @param record * @throws DBPrimaryKeyException when the record already exists * @throws DBConstraintException when a table/index constraint is violated * @throws DBException in case of another database problem * @throws IllegalArgumentException when the given record cannot be stored * @throws IllegalStateException when the columns that are part of the primary key have not all * been assigned a value */ public void insert(Record record) throws DBPrimaryKeyException, DBConstraintException, DBException, IllegalArgumentException, IllegalStateException { if (!isStorable(record)) throw new IllegalArgumentException( String.format("Record (%s) cannot be inserted!", record.toString(false))); boolean inserted = false; try { inserted = doInsert(record); } catch (DBException e) { rollbackTransactions(); // !!! throw e; } // Inform client if a real insert happened: if (inserted) client.storageEvent(RecordOperation.Inserted, record.getReference(), this); }
protected final boolean isStorable(Record record, boolean allowMeta) { // Perform check to determine whether the Record can be stored: // Obviously it makes no sense to store null records: if (record == null) return false; // Unless explicitly allowed, meta model or schema records cannot be stored directly: if (!allowMeta && record.getSchema().getModel() == Model.META_MODEL) return false; // Check if the record has non-null values in each non-optional (sub)column, except the // auto-incrementing PK column if there is one: IntegerColumn autoKeyCol = record.getSchema().getAutoIncrementingPrimaryKeyColumn(); if (!record.isFilled( autoKeyCol != null ? Collections.<Column<?>>singleton(autoKeyCol) : ColumnSet.SKIP_NONE, true)) return false; // (Add additional checks here) // All OK: return true; }
/** * Deletes a series of records. A transaction will be used. Upon an error the whole operation will * be rolled back. * * @param records - the records to delete * @throws DBException */ public void delete(Collection<Record> records) throws DBException { startTransaction(); List<Record> deleted = new ArrayList<Record>(records.size()); try { for (Record record : records) if (isStorable(record)) { if (doDelete(record)) deleted.add(record); } } catch (DBException e) { rollbackTransactions(); throw e; } commitTransaction(); // Inform client: for (Record record : deleted) client.storageEvent(RecordOperation.Deleted, record.getReference(), this); }
/** * Stores a single record, if it already exists it is updated. Note that this method does not * start a new transaction. If this is a desired the client code should take care of that by first * calling {@link #startTransaction()}. However, if an error occurs any open transaction will be * rolled back! * * @param record - the record to store or update; records of internal schemata will be rejected * @throws DBConstraintException when a table/index constraint is violated * @throws DBException in case of a database problem * @throws IllegalArgumentException when the given record cannot be stored * @throws IllegalStateException when the columns that are part of the primary key have not all * been assigned a value */ public void store(Record record) throws DBException, IllegalArgumentException, IllegalStateException { if (!isStorable(record)) throw new IllegalArgumentException( String.format("Record (%s) cannot be stored!", record.toString(false))); Boolean insert = null; try { insert = doStore(record); } catch (DBException e) { rollbackTransactions(); // !!! throw e; } // Inform client: if (insert == null) return; // record was unchanged else if (insert) client.storageEvent(RecordOperation.Inserted, record.getReference(), this); else client.storageEvent(RecordOperation.Updated, record.getReference(), this); }
/** * Deletes a single record. Note that this method does not start a new transaction. If this is a * desired the client code should take care of that by first calling {@link #startTransaction()}. * However, if an error occurs any open transaction will be rolled back! * * @param record - the record to delete * @throws DBException */ public void delete(Record record) throws DBException { if (!isStorable(record)) return; try { doDelete(record); } catch (DBException e) { rollbackTransactions(); // !!! throw e; } // Inform client: client.storageEvent(RecordOperation.Deleted, record.getReference(), this); }