Flesh out duplicate txInstant support.

This commit is contained in:
Richard Newman 2018-01-29 16:38:02 -08:00
parent a8dcad65da
commit 7c5143d4e9
4 changed files with 34 additions and 19 deletions

View file

@ -1344,18 +1344,17 @@ mod tests {
assert_transact!(conn, "[[:db/add :db/tx :db/txInstant #inst \"2017-06-16T00:59:11.257Z\"]
[:db/add :db/tx :db/txInstant #inst \"2017-06-16T00:59:11.752Z\"]
[:db/add 102 :db/ident :name/Vlad]]",
Err("Could not insert non-fts one statements into temporary search table!"));
Err("conflicting datoms in tx"));
// Test multiple txInstants with the same value.
// Test disabled: depends on #535.
// assert_transact!(conn, "[[:db/add :db/tx :db/txInstant #inst \"2017-06-16T00:59:11.257Z\"]
// [:db/add :db/tx :db/txInstant #inst \"2017-06-16T00:59:11.257Z\"]
// [:db/add 103 :db/ident :name/Dimitri]
// [:db/add 104 :db/ident :name/Anton]]");
// assert_matches!(conn.last_transaction(),
// "[[103 :db/ident :name/Dimitri ?tx true]
// [104 :db/ident :name/Anton ?tx true]
// [?tx :db/txInstant #inst \"2017-06-16T00:59:11.257Z\" ?tx true]]");
assert_transact!(conn, "[[:db/add :db/tx :db/txInstant #inst \"2017-06-16T00:59:11.257Z\"]
[:db/add :db/tx :db/txInstant #inst \"2017-06-16T00:59:11.257Z\"]
[:db/add 103 :db/ident :name/Dimitri]
[:db/add 104 :db/ident :name/Anton]]");
assert_matches!(conn.last_transaction(),
"[[103 :db/ident :name/Dimitri ?tx true]
[104 :db/ident :name/Anton ?tx true]
[?tx :db/txInstant #inst \"2017-06-16T00:59:11.257Z\" ?tx true]]");
// Test txInstant retraction
// Test disabled: retracting a datom that doesn't exist should fail.

View file

@ -82,5 +82,10 @@ error_chain! {
description("unrecognized or no ident found for entid")
display("unrecognized or no ident found for entid: {}", entid)
}
ConflictingDatoms {
description("conflicting datoms in tx")
display("conflicting datoms in tx")
}
}
}

View file

@ -8,6 +8,9 @@
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
// Oh, error_chain.
#![recursion_limit="128"]
#[macro_use]
extern crate error_chain;
extern crate itertools;

View file

@ -633,11 +633,21 @@ impl<'conn, 'a> Tx<'conn, 'a> {
let added = op == OpType::Add;
// We take the last encountered :db/txInstant value.
// If more than one is provided, the transactor will fail.
if added &&
e == self.tx_id &&
a == entids::DB_TX_INSTANT {
if let TypedValue::Instant(instant) = v {
self.tx_instant = Some(instant);
if let Some(ts) = self.tx_instant {
if ts == instant {
// Dupes are fine.
} else {
bail!(ErrorKind::ConflictingDatoms);
}
} else {
self.tx_instant = Some(instant);
}
continue;
} else {
// The type error has been caught earlier.
unreachable!()
@ -657,14 +667,12 @@ impl<'conn, 'a> Tx<'conn, 'a> {
tx_instant = self.tx_instant.unwrap_or_else(now);
// Transact [:db/add :db/txInstant NOW :db/tx] if it doesn't exist.
if self.tx_instant == None {
non_fts_one.push((self.tx_id,
entids::DB_TX_INSTANT,
self.schema.require_attribute_for_entid(entids::DB_TX_INSTANT).unwrap(),
TypedValue::Instant(tx_instant),
true));
}
// Transact [:db/add :db/txInstant tx_instant :db/tx].
non_fts_one.push((self.tx_id,
entids::DB_TX_INSTANT,
self.schema.require_attribute_for_entid(entids::DB_TX_INSTANT).unwrap(),
tx_instant.into(),
true));
if !non_fts_one.is_empty() {
self.store.insert_non_fts_searches(&non_fts_one[..], db::SearchType::Inexact)?;