Java Code Examples for com.google.cloud.spanner.Mutation

The following examples show how to use com.google.cloud.spanner.Mutation. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source Project: spanner-event-exporter   Source File: Queue.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Sends a QueueMessage to the spanner queue table
 *
 * <p>Example of sending data to a queue.
 *
 * <pre>{@code
 * MyProto myProto = MyProto.newBuilder().setMessage("My-Message").build();
 *
 * try {
 *   Queue.send(dbClient, queueName, "myKey", ByteArray.copyFrom(myProto.toByteArray()));
 * } catch (SpannerException e) {
 *   log.error("Could not write message to Queue", e);
 * }
 * }</pre>
 *
 * @param dbClient the Spanner database client
 * @param queueName the name of the queue to be polled
 * @param key the name used to partition the passed value for storage and lookup
 * @param value the message payload
 * @return Timestamp the timestamp that the message was written
 */
public static Timestamp send(DatabaseClient dbClient, String queueName, String key, byte[] value)
    throws SpannerException {
  Preconditions.checkNotNull(dbClient);
  Preconditions.checkNotNull(queueName);
  Preconditions.checkNotNull(key);
  Preconditions.checkNotNull(value);

  final List<Mutation> mutations = new ArrayList<>();
  mutations.add(
      Mutation.newInsertBuilder(queueName)
          .set("MessageId")
          .to(UUID.randomUUID().toString())
          .set("Key")
          .to(key)
          .set("Payload")
          .to(ByteArray.copyFrom(value))
          .set("Ack")
          .to(false)
          .set("Timestamp")
          .to(Value.COMMIT_TIMESTAMP)
          .build());

  return dbClient.write(mutations);
}
 
Example 2
@Test
public void testCommitTimestampsType() {
	CommitTimestamps entity = new CommitTimestamps();

	doWithFields(CommitTimestamps.class,
			f -> setField(f, entity, CommitTimestamp.of(f.getType())),
			ff -> !ff.isSynthetic() && Objects.isNull(ff.getAnnotation(PrimaryKey.class)));

	WriteBuilder writeBuilder = Mutation.newInsertBuilder("commit_timestamps_table");
	this.spannerEntityWriter.write(entity, writeBuilder::set);
	Mutation mutation = writeBuilder.build();
	assertThat(mutation.asMap().entrySet().stream()
			.filter(e -> !"id".equals(e.getKey()))
			.map(Map.Entry::getValue)
			.collect(Collectors.toList())).allMatch(Value::isCommitTimestamp);
}
 
Example 3
Source Project: beam   Source File: MutationSizeEstimatorTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void primitiveArrays() throws Exception {
  Mutation int64 =
      Mutation.newInsertOrUpdateBuilder("test")
          .set("one")
          .toInt64Array(new long[] {1L, 2L, 3L})
          .build();
  Mutation float64 =
      Mutation.newInsertOrUpdateBuilder("test")
          .set("one")
          .toFloat64Array(new double[] {1., 2.})
          .build();
  Mutation bool =
      Mutation.newInsertOrUpdateBuilder("test")
          .set("one")
          .toBoolArray(new boolean[] {true, true, false, true})
          .build();

  assertThat(MutationSizeEstimator.sizeOf(int64), is(24L));
  assertThat(MutationSizeEstimator.sizeOf(float64), is(16L));
  assertThat(MutationSizeEstimator.sizeOf(bool), is(4L));
}
 
Example 4
Source Project: google-cloud-java   Source File: DatabaseClientSnippets.java    License: Apache License 2.0 6 votes vote down vote up
/** 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]
}
 
Example 5
Source Project: spanner-jdbc   Source File: CloudSpannerPreparedStatement.java    License: MIT License 6 votes vote down vote up
private Mutation createUpdateMutation(Update update, boolean generateParameterMetaData)
    throws SQLException {
  if (update.getTables().isEmpty())
    throw new CloudSpannerSQLException("No table found in update statement",
        Code.INVALID_ARGUMENT);
  if (update.getTables().size() > 1)
    throw new CloudSpannerSQLException(
        "Update statements for multiple tables at once are not supported", Code.INVALID_ARGUMENT);
  String table = unquoteIdentifier(update.getTables().get(0).getFullyQualifiedName());
  getParameterStore().setTable(table);
  List<Expression> expressions = update.getExpressions();
  WriteBuilder builder = Mutation.newUpdateBuilder(table);
  int index = 0;
  for (Column col : update.getColumns()) {
    String columnName = unquoteIdentifier(col.getFullyQualifiedName());
    expressions.get(index).accept(new ValueBinderExpressionVisitorAdapter<>(getParameterStore(),
        builder.set(columnName), columnName));
    index++;
  }
  visitUpdateWhereClause(update.getWhere(), builder, generateParameterMetaData);

  return builder.build();
}
 
Example 6
Source Project: google-cloud-java   Source File: DatabaseClientSnippets.java    License: Apache License 2.0 6 votes vote down vote up
/** Example of using {@link TransactionManager}. */
// [TARGET transactionManager()]
// [VARIABLE my_singer_id]
public void transactionManager(final long singerId) throws InterruptedException {
  // [START transactionManager]
  try (TransactionManager manager = dbClient.transactionManager()) {
    TransactionContext txn = manager.begin();
    while (true) {
      try {
        String column = "FirstName";
        Struct row = txn.readRow("Singers", Key.of(singerId), Collections.singleton(column));
        String name = row.getString(column);
        txn.buffer(
            Mutation.newUpdateBuilder("Singers").set(column).to(name.toUpperCase()).build());
        manager.commit();
        break;
      } catch (AbortedException e) {
        Thread.sleep(e.getRetryDelayInMillis() / 1000);
        txn = manager.resetForRetry();
      }
    }
  }
  // [END transactionManager]
}
 
Example 7
Source Project: java-docs-samples   Source File: SpannerTasks.java    License: Apache License 2.0 6 votes vote down vote up
private static void writeExampleData(PrintWriter pw) {
  List<Mutation> mutations = new ArrayList<>();
  for (Singer singer : SINGERS) {
    mutations.add(
        Mutation.newInsertBuilder("Singers")
            .set("SingerId")
            .to(singer.singerId)
            .set("FirstName")
            .to(singer.firstName)
            .set("LastName")
            .to(singer.lastName)
            .build());
  }
  for (Album album : ALBUMS) {
    mutations.add(
        Mutation.newInsertBuilder("Albums")
            .set("SingerId")
            .to(album.singerId)
            .set("AlbumId")
            .to(album.albumId)
            .set("AlbumTitle")
            .to(album.albumTitle)
            .build());
  }
  SpannerClient.getDatabaseClient().write(mutations);
}
 
Example 8
Source Project: spanner-jdbc   Source File: CloudSpannerPreparedStatementTest.java    License: MIT License 6 votes vote down vote up
@Test()
public void testDeleteStatementWithNullValueInKey()
    throws SQLException, NoSuchMethodException, SecurityException, IllegalAccessException,
    IllegalArgumentException, InvocationTargetException {
  CloudSpannerPreparedStatement ps =
      CloudSpannerTestObjects.createPreparedStatement("DELETE FROM FOO WHERE ID=?");
  ps.setNull(1, Types.BIGINT);
  Mutations mutations;
  Method createMutations = ps.getClass().getDeclaredMethod("createMutations");
  createMutations.setAccessible(true);
  mutations = (Mutations) createMutations.invoke(ps);

  Mutation deleteMutation = mutations.getMutations().get(0);
  Assert.assertNotNull(deleteMutation);
  Assert.assertEquals(Op.DELETE, deleteMutation.getOperation());
  List<Key> keys = Lists.newArrayList(deleteMutation.getKeySet().getKeys());
  Assert.assertEquals(1, keys.size());
  Assert.assertNull(keys.get(0).getParts().iterator().next());
}
 
Example 9
Source Project: spring-cloud-gcp   Source File: SpannerTemplateTests.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void updateColumnsArrayTest() {
	Mutation mutation = Mutation.newInsertOrUpdateBuilder("custom_test_table")
			.build();
	List<Mutation> mutations = Collections.singletonList(mutation);
	TestEntity entity = new TestEntity();
	Set<String> cols = new HashSet<>(Arrays.asList("a", "b"));
	when(this.mutationFactory.update(same(entity),
			eq(cols)))
					.thenReturn(mutations);

	verifyBeforeAndAfterEvents(new BeforeSaveEvent(Collections.singletonList(entity), cols),
			new AfterSaveEvent(mutations, Collections.singletonList(entity), cols),
			() -> this.spannerTemplate.update(entity, "a", "b"), x -> x.verify(this.databaseClient, times(1))
					.write(eq(mutations)));
}
 
Example 10
Source Project: beam   Source File: SpannerReadIT.java    License: Apache License 2.0 6 votes vote down vote up
private void makeTestData() {
  DatabaseClient databaseClient = getDatabaseClient();

  List<Mutation> mutations = new ArrayList<>();
  for (int i = 0; i < 5L; i++) {
    mutations.add(
        Mutation.newInsertOrUpdateBuilder(options.getTable())
            .set("key")
            .to((long) i)
            .set("value")
            .to(RandomUtils.randomAlphaNumeric(100))
            .build());
  }

  databaseClient.writeAtLeastOnce(mutations);
}
 
Example 11
Source Project: beam   Source File: MutationSizeEstimator.java    License: Apache License 2.0 6 votes vote down vote up
/** Estimates a size of mutation in bytes. */
static long sizeOf(Mutation m) {
  if (m.getOperation() == Mutation.Op.DELETE) {
    return sizeOf(m.getKeySet());
  }
  long result = 0;
  for (Value v : m.getValues()) {
    switch (v.getType().getCode()) {
      case ARRAY:
        result += estimateArrayValue(v);
        break;
      case STRUCT:
        throw new IllegalArgumentException("Structs are not supported in mutation.");
      default:
        result += estimatePrimitiveValue(v);
    }
  }
  return result;
}
 
Example 12
Source Project: beam   Source File: SpannerIOWriteTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void streamingWrites() throws Exception {
  TestStream<Mutation> testStream =
      TestStream.create(SerializableCoder.of(Mutation.class))
          .addElements(m(1L), m(2L))
          .advanceProcessingTime(Duration.standardMinutes(1))
          .addElements(m(3L), m(4L))
          .advanceProcessingTime(Duration.standardMinutes(1))
          .addElements(m(5L), m(6L))
          .advanceWatermarkToInfinity();
  pipeline
      .apply(testStream)
      .apply(
          SpannerIO.write()
              .withProjectId("test-project")
              .withInstanceId("test-instance")
              .withDatabaseId("test-database")
              .withServiceFactory(serviceFactory));
  pipeline.run();

  verifyBatches(batch(m(1L), m(2L)), batch(m(3L), m(4L)), batch(m(5L), m(6L)));
}
 
Example 13
Source Project: beam   Source File: SpannerIOWriteTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void streamingWritesWithGrouping() throws Exception {

  // verify that grouping/sorting occurs when set.
  TestStream<Mutation> testStream =
      TestStream.create(SerializableCoder.of(Mutation.class))
          .addElements(m(1L), m(5L), m(2L), m(4L), m(3L), m(6L))
          .advanceWatermarkToInfinity();
  pipeline
      .apply(testStream)
      .apply(
          SpannerIO.write()
              .withProjectId("test-project")
              .withInstanceId("test-instance")
              .withDatabaseId("test-database")
              .withServiceFactory(serviceFactory)
              .withGroupingFactor(40)
              .withMaxNumRows(2));
  pipeline.run();

  // Output should be batches of sorted mutations.
  verifyBatches(batch(m(1L), m(2L)), batch(m(3L), m(4L)), batch(m(5L), m(6L)));
}
 
Example 14
Source Project: beam   Source File: MutationSizeEstimatorTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void nullPrimitiveArrays() throws Exception {
  Mutation int64 =
      Mutation.newInsertOrUpdateBuilder("test").set("one").toInt64Array((long[]) null).build();
  Mutation float64 =
      Mutation.newInsertOrUpdateBuilder("test")
          .set("one")
          .toFloat64Array((double[]) null)
          .build();
  Mutation bool =
      Mutation.newInsertOrUpdateBuilder("test").set("one").toBoolArray((boolean[]) null).build();

  assertThat(MutationSizeEstimator.sizeOf(int64), is(0L));
  assertThat(MutationSizeEstimator.sizeOf(float64), is(0L));
  assertThat(MutationSizeEstimator.sizeOf(bool), is(0L));
}
 
Example 15
Source Project: google-cloud-java   Source File: DatabaseClientSnippets.java    License: Apache License 2.0 6 votes vote down vote up
/** Example of a read write transaction. */
// [TARGET readWriteTransaction()]
// [VARIABLE my_singer_id]
public void readWriteTransaction(final long singerId) {
  // [START readWriteTransaction]
  TransactionRunner runner = dbClient.readWriteTransaction();
  runner.run(
      new TransactionCallable<Void>() {

        @Override
        public Void run(TransactionContext transaction) throws Exception {
          String column = "FirstName";
          Struct row =
              transaction.readRow("Singers", Key.of(singerId), Collections.singleton(column));
          String name = row.getString(column);
          transaction.buffer(
              Mutation.newUpdateBuilder("Singers").set(column).to(name.toUpperCase()).build());
          return null;
        }
      });
  // [END readWriteTransaction]
}
 
Example 16
Source Project: beam   Source File: SpannerIOWriteTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void streamingWritesNoGrouping() throws Exception {

  // verify that grouping/sorting does not occur - batches should be created in received order.
  TestStream<Mutation> testStream =
      TestStream.create(SerializableCoder.of(Mutation.class))
          .addElements(m(1L), m(5L), m(2L), m(4L), m(3L), m(6L))
          .advanceWatermarkToInfinity();

  // verify that grouping/sorting does not occur when notset.
  pipeline
      .apply(testStream)
      .apply(
          SpannerIO.write()
              .withProjectId("test-project")
              .withInstanceId("test-instance")
              .withDatabaseId("test-database")
              .withServiceFactory(serviceFactory)
              .withMaxNumRows(2));
  pipeline.run();

  verifyBatches(batch(m(1L), m(5L)), batch(m(2L), m(4L)), batch(m(3L), m(6L)));
}
 
Example 17
Source Project: beam   Source File: SpannerIO.java    License: Apache License 2.0 6 votes vote down vote up
private void spannerWriteWithRetryIfSchemaChange(Iterable<Mutation> batch)
    throws SpannerException {
  for (int retry = 1; ; retry++) {
    try {
      spannerAccessor.getDatabaseClient().writeAtLeastOnce(batch);
      return;
    } catch (AbortedException e) {
      if (retry >= ABORTED_RETRY_ATTEMPTS) {
        throw e;
      }
      if (e.isRetryable() || e.getMessage().contains(errString)) {
        continue;
      }
      throw e;
    }
  }
}
 
Example 18
/**
 * Executes a batch of inserts to a table.
 */
public void batchInsert(int batchSize) {
  ArrayList<Mutation> mutations = new ArrayList<>();
  for (int i = 0; i < batchSize; i++) {
    mutations.add(buildSingleMutationInsert());
  }
  this.databaseClient.write(mutations);
}
 
Example 19
Source Project: java-docs-samples   Source File: BufferedWriteExample.java    License: Apache License 2.0 5 votes vote down vote up
static void bufferedWrite(String projectId, String instanceId, String databaseId)
    throws SQLException {
  String connectionUrl =
      String.format(
          "jdbc:cloudspanner:/projects/%s/instances/%s/databases/%s",
          projectId, instanceId, databaseId);
  long singerId = 30;
  long albumId = 10;
  try (Connection connection = DriverManager.getConnection(connectionUrl)) {
    // Unwrap the Cloud Spanner specific interface to be able to access custom methods.
    CloudSpannerJdbcConnection spannerConnection =
        connection.unwrap(CloudSpannerJdbcConnection.class);
    spannerConnection.setAutoCommit(false);
    Mutation mutationSingers =
        Mutation.newInsertBuilder("Singers")
            .set("SingerId")
            .to(singerId)
            .set("FirstName")
            .to("Marvin")
            .set("LastName")
            .to("Mooney")
            .build();
    Mutation mutationAlbums =
        Mutation.newInsertBuilder("Albums")
            .set("SingerId")
            .to(singerId)
            .set("AlbumId")
            .to(albumId)
            .set("AlbumTitle")
            .to("Hand in hand")
            .set("MarketingBudget")
            .to(1000)
            .build();
    spannerConnection.bufferedWrite(Arrays.asList(mutationSingers, mutationAlbums));
    spannerConnection.commit();
    System.out.printf(
        "Transaction committed at [%s]%n", spannerConnection.getCommitTimestamp().toString());
  }
}
 
Example 20
private static Mutation buildSingleMutationInsert() {
  Mutation mutation = Mutation.newInsertBuilder(AIRPORT_TABLE)
      .set("id").to(UUID.randomUUID().toString())
      .set("address").to("100 Main Street")
      .set("country").to("United States")
      .set("date_built").to(Date.parseDate("2000-04-14"))
      .set("name").to("Foobar Airport")
      .set("plane_capacity").to((int) (1000 * Math.random()))
      .build();
  return mutation;
}
 
Example 21
Source Project: DataflowTemplates   Source File: LocalSpannerIO.java    License: Apache License 2.0 5 votes vote down vote up
@Override
public SpannerWriteResult expand(PCollection<Mutation> input) {
  getSpannerConfig().validate();

  return input
      .apply("To mutation group", ParDo.of(new ToMutationGroupFn()))
      .apply("Write mutations to Cloud Spanner", new WriteGrouped(this));
}
 
Example 22
Source Project: spring-cloud-gcp   Source File: SpannerTemplateTests.java    License: Apache License 2.0 5 votes vote down vote up
@Test
public void updateTest() {
	Mutation mutation = Mutation.newUpdateBuilder("custom_test_table").build();
	TestEntity entity = new TestEntity();
	List<Mutation> mutations = Collections.singletonList(mutation);
	when(this.mutationFactory.update(entity, null))
			.thenReturn(mutations);

	verifyBeforeAndAfterEvents(new BeforeSaveEvent(Collections.singletonList(entity), null),
			new AfterSaveEvent(mutations, Collections.singletonList(entity), null),
			() -> this.spannerTemplate.update(entity), x -> x.verify(this.databaseClient, times(1))
					.write(eq(mutations)));
}
 
Example 23
Source Project: spring-cloud-gcp   Source File: SpannerTemplateTests.java    License: Apache License 2.0 5 votes vote down vote up
@Test
public void deleteKeysTest() {
	KeySet keys = KeySet.newBuilder().addKey(Key.of("key1")).addKey(Key.of("key2"))
			.build();
	Mutation mutation = Mutation.delete("custom_test_table", keys);
	List<Mutation> mutations = Collections.singletonList(mutation);
	when(this.mutationFactory.delete(eq(TestEntity.class), same(keys)))
			.thenReturn(mutation);

	verifyBeforeAndAfterEvents(new BeforeDeleteEvent(mutations, null, keys, TestEntity.class),
			new AfterDeleteEvent(mutations, null, keys, TestEntity.class),
			() -> this.spannerTemplate.delete(TestEntity.class, keys), x -> x.verify(this.databaseClient, times(1))
					.write(eq(Collections.singletonList(mutation))));
}
 
Example 24
Source Project: beam   Source File: MutationKeyEncoder.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Builds a lexicographically sortable binary key based on a primary key descriptor.
 *
 * @param m a spanner mutation.
 * @return a binary string that preserves the ordering of the primary key.
 */
public byte[] encodeTableNameAndKey(Mutation m) {
  OrderedCode orderedCode = new OrderedCode();
  String tableName = m.getTable().toLowerCase();

  if (schema.getColumns(tableName).isEmpty()) {
    // Log an warning for an unknown table.
    if (!unknownTablesWarnings.containsKey(tableName)) {
      unknownTablesWarnings.putIfAbsent(tableName, new AtomicInteger(0));
    }
    // Only log every 10000 rows per table, or there will be way too much logging...
    int numWarnings = unknownTablesWarnings.get(tableName).incrementAndGet();
    if (1 == (numWarnings % ROWS_PER_UNKNOWN_TABLE_LOG_MESSAGE)) {
      System.err.printf(
          "Performance issue: Mutation references an unknown table: %s. "
              + "See SpannerIO documentation section 'Database Schema Preparation' "
              + "(At least %,d occurrences)\n",
          tableName, numWarnings);
    }
  }

  orderedCode.writeBytes(tableName.getBytes(StandardCharsets.UTF_8));

  if (m.getOperation() == Op.DELETE) {
    if (isPointDelete(m)) {
      Key key = m.getKeySet().getKeys().iterator().next();
      encodeKey(orderedCode, tableName, key);
    } else {
      // The key is left empty for non-point deletes, since there is no general way to batch them.
    }
  } else {
    encodeKey(orderedCode, m);
  }
  return orderedCode.getEncodedBytes();
}
 
Example 25
@Test
public void writeIncompatibleTypeTest() {
	this.expectedEx.expect(SpannerDataException.class);
	this.expectedEx.expectMessage("Unsupported mapping for type: " +
			"class org.springframework.cloud.gcp.data.spanner.core.convert.TestEntities$TestEntity");
	FaultyTestEntity ft = new FaultyTestEntity();
	ft.fieldWithUnsupportedType = new TestEntity();
	WriteBuilder writeBuilder = Mutation.newInsertBuilder("faulty_test_table");
	this.spannerEntityWriter.write(ft, writeBuilder::set);
}
 
Example 26
public Stream<Mutation> stream(String tableName) {
  Table table = ddl.table(tableName);
  if (table == null) {
    throw new IllegalArgumentException("Unknown table " + tableName);
  }
  return Stream.generate(new TableSupplier(table));
}
 
Example 27
Source Project: spanner-jdbc   Source File: XATransaction.java    License: MIT License 5 votes vote down vote up
static void prepareMutations(TransactionContext transaction, String xid, List<Mutation> mutations)
    throws SQLException {
  int index = 0;
  for (Mutation mutation : mutations) {
    WriteBuilder prepared =
        Mutation.newInsertBuilder(CloudSpannerXAConnection.XA_PREPARED_MUTATIONS_TABLE);
    prepared.set(CloudSpannerXAConnection.XA_XID_COLUMN).to(xid);
    prepared.set(CloudSpannerXAConnection.XA_NUMBER_COLUMN).to(index);
    prepared.set(CloudSpannerXAConnection.XA_MUTATION_COLUMN).to(serializeMutation(mutation));
    transaction.buffer(prepared.build());
    index++;
  }
}
 
Example 28
Source Project: spanner-jdbc   Source File: XATransaction.java    License: MIT License 5 votes vote down vote up
static void commitPrepared(TransactionContext transaction, String xid) throws SQLException {
  try (ResultSet rs = transaction.executeQuery(getPreparedMutationsStatement(xid))) {
    while (rs.next()) {
      String serialized = rs.getString(1);
      Mutation mutation = deserializeMutation(serialized);
      transaction.buffer(mutation);
    }
  }
  cleanupPrepared(transaction, xid);
}
 
Example 29
Source Project: spanner-jdbc   Source File: XATransaction.java    License: MIT License 5 votes vote down vote up
@VisibleForTesting
static String serializeMutation(Mutation mutation) throws SQLException {
  try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
      ObjectOutputStream stream = new ObjectOutputStream(bos)) {
    stream.writeObject(mutation);
    return Base64.getEncoder().encodeToString(bos.toByteArray());
  } catch (IOException e) {
    throw new CloudSpannerSQLException("Could not serialize mutation", Code.INTERNAL, e);
  }
}
 
Example 30
Source Project: spanner-jdbc   Source File: XATransaction.java    License: MIT License 5 votes vote down vote up
@VisibleForTesting
static Mutation deserializeMutation(String mutation) throws SQLException {
  try (ByteArrayInputStream bis = new ByteArrayInputStream(Base64.getDecoder().decode(mutation));
      ObjectInputStream input = new ObjectInputStream(bis)) {
    return (Mutation) input.readObject();
  } catch (IOException | ClassNotFoundException e) {
    throw new CloudSpannerSQLException("Could not deserialize mutation", Code.INTERNAL, e);
  }
}