/** Example of blind write. */ // [TARGET write(Iterable)] // [VARIABLE my_singer_id] public void write(long singerId) { // [START write] Mutation mutation = Mutation.newInsertBuilder("Singer") .set("SingerId") .to(singerId) .set("FirstName") .to("Billy") .set("LastName") .to("Joel") .build(); dbClient.write(Collections.singletonList(mutation)); // [END write] }
/** Example of unprotected blind write. */ // [TARGET writeAtLeastOnce(Iterable)] // [VARIABLE my_singer_id] public void writeAtLeastOnce(long singerId) { // [START writeAtLeastOnce] Mutation mutation = Mutation.newInsertBuilder("Singers") .set("SingerId") .to(singerId) .set("FirstName") .to("Billy") .set("LastName") .to("Joel") .build(); dbClient.writeAtLeastOnce(Collections.singletonList(mutation)); // [END writeAtLeastOnce] }
@Test public void toProtoCoalescingChangeOfColumn() { List<Mutation> mutations = Arrays.asList( Mutation.newInsertBuilder("T").set("C1").to("V1").build(), Mutation.newInsertBuilder("T").set("C1").to("V2").build(), Mutation.newInsertBuilder("T").set("C1").to("V3").build(), Mutation.newInsertBuilder("T").set("C2").to("V4").build(), Mutation.newInsertBuilder("T").set("C2").to("V5").build()); List<com.google.spanner.v1.Mutation> proto = new ArrayList<>(); Mutation.toProto(mutations, proto); assertThat(proto.size()).isEqualTo(2); MatcherAssert.assertThat( proto.get(0), matchesProto( "insert { table: 'T' columns: 'C1' values { values { string_value: 'V1' } }" + " values { values { string_value: 'V2' } }" + " values { values { string_value: 'V3' } } }")); MatcherAssert.assertThat( proto.get(1), matchesProto( "insert { table: 'T' columns: 'C2' values { values { string_value: 'V4' } }" + " values { values { string_value: 'V5' } } }")); }
@Test public void toProtoCoalescingChangeOfTable() { List<Mutation> mutations = Arrays.asList( Mutation.newInsertBuilder("T1").set("C").to("V1").build(), Mutation.newInsertBuilder("T1").set("C").to("V2").build(), Mutation.newInsertBuilder("T1").set("C").to("V3").build(), Mutation.newInsertBuilder("T2").set("C").to("V4").build(), Mutation.newInsertBuilder("T2").set("C").to("V5").build()); List<com.google.spanner.v1.Mutation> proto = new ArrayList<>(); Mutation.toProto(mutations, proto); assertThat(proto.size()).isEqualTo(2); MatcherAssert.assertThat( proto.get(0), matchesProto( "insert { table: 'T1' columns: 'C' values { values { string_value: 'V1' } }" + " values { values { string_value: 'V2' } }" + " values { values { string_value: 'V3' } } }")); MatcherAssert.assertThat( proto.get(1), matchesProto( "insert { table: 'T2' columns: 'C' values { values { string_value: 'V4' } }" + " values { values { string_value: 'V5' } } }")); }
@Test public void asMap() { Mutation m = Mutation.newInsertBuilder("T").build(); assertThat(m.asMap()).isEqualTo(ImmutableMap.of()); m = Mutation.newInsertBuilder("T").set("C1").to(true).set("C2").to(1234).build(); assertThat(m.asMap()) .isEqualTo(ImmutableMap.of("C1", Value.bool(true), "C2", Value.int64(1234))); }
@Test public void insertEmpty() { Mutation m = Mutation.newInsertBuilder("T1").build(); assertThat(m.getTable()).isEqualTo("T1"); assertThat(m.getOperation()).isEqualTo(Mutation.Op.INSERT); assertThat(m.getColumns()).isEmpty(); assertThat(m.getValues()).isEmpty(); assertThat(m.toString()).isEqualTo("insert(T1{})"); }
@Test public void toProtoCoalescingChangeOfOperation() { List<Mutation> mutations = Arrays.asList( Mutation.newInsertBuilder("T").set("C").to("V1").build(), Mutation.newInsertBuilder("T").set("C").to("V2").build(), Mutation.newInsertBuilder("T").set("C").to("V3").build(), Mutation.newUpdateBuilder("T").set("C").to("V4").build(), Mutation.newUpdateBuilder("T").set("C").to("V5").build()); List<com.google.spanner.v1.Mutation> proto = new ArrayList<>(); Mutation.toProto(mutations, proto); assertThat(proto.size()).isEqualTo(2); MatcherAssert.assertThat( proto.get(0), matchesProto( "insert { table: 'T' columns: 'C' values { values { string_value: 'V1' } }" + " values { values { string_value: 'V2' } }" + " values { values { string_value: 'V3' } } }")); MatcherAssert.assertThat( proto.get(1), matchesProto( "update { table: 'T' columns: 'C' values { values { string_value: 'V4' } }" + " values { values { string_value: 'V5' } } }")); }
@Test public void unfinishedBindingV1() { Mutation.WriteBuilder b = Mutation.newInsertBuilder("T1"); b.set("C1"); expectedException.expect(IllegalStateException.class); expectedException.expectMessage("Incomplete binding for column C1"); b.build(); }
@Test public void unfinishedBindingV2() { Mutation.WriteBuilder b = Mutation.newInsertBuilder("T1"); b.set("C1"); expectedException.expect(IllegalStateException.class); expectedException.expectMessage("Incomplete binding for column C1"); b.set("C2"); }
@Test public void notInBinding() { ValueBinder<Mutation.WriteBuilder> binder = Mutation.newInsertBuilder("T1").set("C1"); binder.to(1234); expectedException.expect(IllegalStateException.class); expectedException.expectMessage("No binding currently active"); binder.to(5678); }
@Test public void insert() { Mutation m = Mutation.newInsertBuilder("T1").set("C1").to(true).set("C2").to(1234).build(); assertThat(m.getTable()).isEqualTo("T1"); assertThat(m.getOperation()).isEqualTo(Mutation.Op.INSERT); assertThat(m.getColumns()).containsExactly("C1", "C2").inOrder(); assertThat(m.getValues()).containsExactly(Value.bool(true), Value.int64(1234)).inOrder(); assertThat(m.toString()).isEqualTo("insert(T1{C1=true,C2=1234})"); }
@Test public void rollback() { TransactionManager manager = client.transactionManager(); TransactionContext txn = manager.begin(); txn.buffer( Mutation.newInsertBuilder("T").set("K").to("Key2").set("BoolValue").to(true).build()); manager.rollback(); assertThat(manager.getState()).isEqualTo(TransactionState.ROLLED_BACK); // Row should not have been inserted. assertThat(client.singleUse().readRow("T", Key.of("Key2"), Arrays.asList("K", "BoolValue"))) .isNull(); }
@Test public void simpleInsert() { TransactionManager manager = client.transactionManager(); TransactionContext txn = manager.begin(); assertThat(manager.getState()).isEqualTo(TransactionState.STARTED); txn.buffer( Mutation.newInsertBuilder("T").set("K").to("Key1").set("BoolValue").to(true).build()); manager.commit(); assertThat(manager.getState()).isEqualTo(TransactionState.COMMITTED); Struct row = client.singleUse().readRow("T", Key.of("Key1"), Arrays.asList("K", "BoolValue")); assertThat(row.getString(0)).isEqualTo("Key1"); assertThat(row.getBoolean(1)).isTrue(); }
@Test public void duplicateColumn() { expectedException.expect(IllegalStateException.class); expectedException.expectMessage("Duplicate column"); Mutation.newInsertBuilder("T1").set("C1").to(true).set("C1").to(false).build(); }
@Test public void duplicateColumnCaseInsensitive() { expectedException.expect(IllegalStateException.class); expectedException.expectMessage("Duplicate column"); Mutation.newInsertBuilder("T1").set("C1").to(true).set("c1").to(false).build(); }
@Test public void equalsAndHashCode() { EqualsTester tester = new EqualsTester(); // Equality, not identity. tester.addEqualityGroup( Mutation.newInsertBuilder("T1").build(), Mutation.newInsertBuilder("T1").build()); // Operation types are distinguished. tester.addEqualityGroup(Mutation.newInsertOrUpdateBuilder("T1").build()); tester.addEqualityGroup(Mutation.newUpdateBuilder("T1").build()); tester.addEqualityGroup(Mutation.newReplaceBuilder("T1").build()); // Table is distinguished. tester.addEqualityGroup(Mutation.newInsertBuilder("T2").build()); // Columns/values are distinguished (but by equality, not identity). tester.addEqualityGroup( Mutation.newInsertBuilder("T1").set("C").to("V").build(), Mutation.newInsertBuilder("T1").set("C").to("V").build()); // Deletes consider the key set. tester.addEqualityGroup(Mutation.delete("T1", KeySet.all())); tester.addEqualityGroup( Mutation.delete("T1", KeySet.singleKey(Key.of("k"))), Mutation.delete("T1", Key.of("k"))); tester.testEquals(); }
client.writeAtLeastOnce( asList( Mutation.newInsertBuilder("T").set("K").to("k1").set("V").to("v1").build(), Mutation.newInsertBuilder("T").set("K").to("k2").set("V").to("v2").build(), Mutation.newInsertBuilder("T").set("K").to("k3").set("V").to("v3").build(), Mutation.newInsertBuilder("T").set("K").to("k4").set("V").to("v4").build()));
@Test public void tableNotFound() { // TODO(user): More precise matchers! Customer code needs to discern table not found, column // not found, etc. expectedException.expect(isSpannerException(ErrorCode.NOT_FOUND)); write( Mutation.newInsertBuilder("TableThatDoesNotExist") .set("K") .to(uniqueString()) .set("StringuniqueString(Value") .to("V1") .build()); }
@Test public void invalidInsert() { TransactionManager manager = client.transactionManager(); TransactionContext txn = manager.begin(); txn.buffer( Mutation.newInsertBuilder("InvalidTable") .set("K") .to("Key1") .set("BoolValue") .to(true) .build()); try { manager.commit(); fail("Expected exception"); } catch (SpannerException e) { // expected } assertThat(manager.getState()).isEqualTo(TransactionState.COMMIT_FAILED); // We cannot retry for non aborted errors. expectedException.expect(IllegalStateException.class); manager.resetForRetry(); }
client.write( Arrays.asList( Mutation.newInsertBuilder("T").set("K").to("Key3").set("BoolValue").to(true).build())); TransactionManager manager1 = client.transactionManager(); TransactionContext txn1 = manager1.begin();