2626import com .google .cloud .bigtable .data .v2 .models .BulkMutation ;
2727import com .google .cloud .bigtable .data .v2 .models .BulkMutationBatcher ;
2828import com .google .cloud .bigtable .data .v2 .models .ConditionalRowMutation ;
29+ import com .google .cloud .bigtable .data .v2 .models .Filters .Filter ;
2930import com .google .cloud .bigtable .data .v2 .models .InstanceName ;
3031import com .google .cloud .bigtable .data .v2 .models .KeyOffset ;
3132import com .google .cloud .bigtable .data .v2 .models .Query ;
3738import com .google .protobuf .ByteString ;
3839import java .io .IOException ;
3940import java .util .List ;
41+ import javax .annotation .Nullable ;
4042
4143/**
4244 * Client for reading from and writing to existing Bigtable tables.
@@ -143,7 +145,7 @@ public static BigtableDataClient create(BigtableDataSettings settings) throws IO
143145 *
144146 * <p>Sample code:
145147 *
146- * <pre>{code
148+ * <pre>{@ code
147149 * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]");
148150 * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) {
149151 * String tableId = "[TABLE]";
@@ -153,7 +155,8 @@ public static BigtableDataClient create(BigtableDataSettings settings) throws IO
153155 * if(row != null) {
154156 * System.out.println(row.getKey().toStringUtf8());
155157 * for(RowCell cell : row.getCells()) {
156- * System.out.println("Family: " + cell.getFamily() + " Qualifier: " + cell.getQualifier().toStringUtf8() + " Value: " + cell.getValue().toStringUtf8());
158+ * System.out.printf("Family: %s Qualifier: %s Value: %s", cell.getFamily(),
159+ * cell.getQualifier().toStringUtf8(), cell.getValue().toStringUtf8());
157160 * }
158161 * }
159162 * } catch(ApiException e) {
@@ -164,7 +167,7 @@ public static BigtableDataClient create(BigtableDataSettings settings) throws IO
164167 * @throws com.google.api.gax.rpc.ApiException when a serverside error occurs
165168 */
166169 public Row readRow (String tableId , ByteString rowKey ) {
167- return ApiExceptions .callAndTranslateApiException (readRowAsync (tableId , rowKey ));
170+ return ApiExceptions .callAndTranslateApiException (readRowAsync (tableId , rowKey , null ));
168171 }
169172
170173 /**
@@ -173,7 +176,7 @@ public Row readRow(String tableId, ByteString rowKey) {
173176 *
174177 * <p>Sample code:
175178 *
176- * <pre>{code
179+ * <pre>{@ code
177180 * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]");
178181 * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) {
179182 * String tableId = "[TABLE]";
@@ -183,7 +186,8 @@ public Row readRow(String tableId, ByteString rowKey) {
183186 * if(row != null) {
184187 * System.out.println(row.getKey().toStringUtf8());
185188 * for(RowCell cell : row.getCells()) {
186- * System.out.println("Family: " + cell.getFamily() + " Qualifier: " + cell.getQualifier().toStringUtf8() + " Value: " + cell.getValue().toStringUtf8());
189+ * System.out.printf("Family: %s Qualifier: %s Value: %s", cell.getFamily(),
190+ * cell.getQualifier().toStringUtf8(), cell.getValue().toStringUtf8());
187191 * }
188192 * }
189193 * } catch(ApiException e) {
@@ -194,7 +198,81 @@ public Row readRow(String tableId, ByteString rowKey) {
194198 * @throws com.google.api.gax.rpc.ApiException when a serverside error occurs
195199 */
196200 public Row readRow (String tableId , String rowKey ) {
197- return ApiExceptions .callAndTranslateApiException (readRowAsync (tableId , rowKey ));
201+ return ApiExceptions .callAndTranslateApiException (
202+ readRowAsync (tableId , ByteString .copyFromUtf8 (rowKey ), null ));
203+ }
204+
205+ /**
206+ * Convenience method for synchronously reading a single row. If the row does not exist, the value
207+ * will be null.
208+ *
209+ * <p>Sample code:
210+ *
211+ * <pre>{@code
212+ * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]");
213+ * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) {
214+ * String tableId = "[TABLE]";
215+ *
216+ * // Build the filter expression
217+ * Filter filter = FILTERS.chain()
218+ * .filter(FILTERS.qualifier().regex("prefix.*"))
219+ * .filter(FILTERS.limit().cellsPerRow(10));
220+ *
221+ * Row row = bigtableDataClient.readRow(tableId, "key", filter);
222+ * // Do something with row, for example, display all cells
223+ * if(row != null) {
224+ * System.out.println(row.getKey().toStringUtf8());
225+ * for(RowCell cell : row.getCells()) {
226+ * System.out.printf("Family: %s Qualifier: %s Value: %s", cell.getFamily(),
227+ * cell.getQualifier().toStringUtf8(), cell.getValue().toStringUtf8());
228+ * }
229+ * }
230+ * } catch(ApiException e) {
231+ * e.printStackTrace();
232+ * }
233+ * }</pre>
234+ *
235+ * @throws com.google.api.gax.rpc.ApiException when a serverside error occurs
236+ */
237+ public Row readRow (String tableId , String rowKey , @ Nullable Filter filter ) {
238+ return ApiExceptions .callAndTranslateApiException (
239+ readRowAsync (tableId , ByteString .copyFromUtf8 (rowKey ), filter ));
240+ }
241+
242+ /**
243+ * Convenience method for synchronously reading a single row. If the row does not exist, the value
244+ * will be null.
245+ *
246+ * <p>Sample code:
247+ *
248+ * <pre>{@code
249+ * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]");
250+ * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) {
251+ * String tableId = "[TABLE]";
252+ *
253+ * // Build the filter expression
254+ * Filter filter = FILTERS.chain()
255+ * .filter(FILTERS.qualifier().regex("prefix.*"))
256+ * .filter(FILTERS.limit().cellsPerRow(10));
257+ *
258+ * Row row = bigtableDataClient.readRow(tableId, ByteString.copyFromUtf8("key"), filter);
259+ * // Do something with row, for example, display all cells
260+ * if(row != null) {
261+ * System.out.println(row.getKey().toStringUtf8());
262+ * for(RowCell cell : row.getCells()) {
263+ * System.out.printf("Family: %s Qualifier: %s Value: %s", cell.getFamily(),
264+ * cell.getQualifier().toStringUtf8(), cell.getValue().toStringUtf8());
265+ * }
266+ * }
267+ * } catch(ApiException e) {
268+ * e.printStackTrace();
269+ * }
270+ * }</pre>
271+ *
272+ * @throws com.google.api.gax.rpc.ApiException when a serverside error occurs
273+ */
274+ public Row readRow (String tableId , ByteString rowKey , @ Nullable Filter filter ) {
275+ return ApiExceptions .callAndTranslateApiException (readRowAsync (tableId , rowKey , filter ));
198276 }
199277
200278 /**
@@ -228,7 +306,7 @@ public Row readRow(String tableId, String rowKey) {
228306 * }</pre>
229307 */
230308 public ApiFuture <Row > readRowAsync (String tableId , String rowKey ) {
231- return readRowAsync (tableId , ByteString .copyFromUtf8 (rowKey ));
309+ return readRowAsync (tableId , ByteString .copyFromUtf8 (rowKey ), null );
232310 }
233311
234312 /**
@@ -262,11 +340,93 @@ public ApiFuture<Row> readRowAsync(String tableId, String rowKey) {
262340 * }</pre>
263341 */
264342 public ApiFuture <Row > readRowAsync (String tableId , ByteString rowKey ) {
265- return readRowsCallable ().first ().futureCall (Query .create (tableId ).rowKey (rowKey ));
343+ return readRowAsync (tableId , rowKey , null );
344+ }
345+
346+ /**
347+ * Convenience method for asynchronously reading a single row. If the row does not exist, the
348+ * future's value will be null.
349+ *
350+ * <p>Sample code:
351+ *
352+ * <pre>{@code
353+ * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]");
354+ * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) {
355+ * String tableId = "[TABLE]";
356+ *
357+ * // Build the filter expression
358+ * Filters.Filter filter = FILTERS.chain()
359+ * .filter(FILTERS.qualifier().regex("prefix.*"))
360+ * .filter(FILTERS.limit().cellsPerRow(10));
361+ *
362+ * ApiFuture<Row> futureResult = bigtableDataClient.readRowAsync(tableId, "key", filter);
363+ *
364+ * ApiFutures.addCallback(futureResult, new ApiFutureCallback<Row>() {
365+ * public void onFailure(Throwable t) {
366+ * if (t instanceof NotFoundException) {
367+ * System.out.println("Tried to read a non-existent table");
368+ * } else {
369+ * t.printStackTrace();
370+ * }
371+ * }
372+ * public void onSuccess(Row row) {
373+ * if (result != null) {
374+ * System.out.println("Got row: " + result);
375+ * }
376+ * }
377+ * }, MoreExecutors.directExecutor());
378+ * }
379+ * }</pre>
380+ */
381+ public ApiFuture <Row > readRowAsync (String tableId , String rowKey , @ Nullable Filter filter ) {
382+ return readRowAsync (tableId , ByteString .copyFromUtf8 (rowKey ), filter );
383+ }
384+
385+ /**
386+ * Convenience method for asynchronously reading a single row. If the row does not exist, the
387+ * future's value will be null.
388+ *
389+ * <p>Sample code:
390+ *
391+ * <pre>{@code
392+ * InstanceName instanceName = InstanceName.of("[PROJECT]", "[INSTANCE]");
393+ * try (BigtableDataClient bigtableDataClient = BigtableDataClient.create(instanceName)) {
394+ * String tableId = "[TABLE]";
395+ *
396+ * // Build the filter expression
397+ * Filters.Filter filter = FILTERS.chain()
398+ * .filter(FILTERS.qualifier().regex("prefix.*"))
399+ * .filter(FILTERS.limit().cellsPerRow(10));
400+ *
401+ * ApiFuture<Row> futureResult = bigtableDataClient.readRowAsync(tableId, ByteString.copyFromUtf8("key"), filter);
402+ *
403+ * ApiFutures.addCallback(futureResult, new ApiFutureCallback<Row>() {
404+ * public void onFailure(Throwable t) {
405+ * if (t instanceof NotFoundException) {
406+ * System.out.println("Tried to read a non-existent table");
407+ * } else {
408+ * t.printStackTrace();
409+ * }
410+ * }
411+ * public void onSuccess(Row row) {
412+ * if (result != null) {
413+ * System.out.println("Got row: " + result);
414+ * }
415+ * }
416+ * }, MoreExecutors.directExecutor());
417+ * }
418+ * }</pre>
419+ */
420+ public ApiFuture <Row > readRowAsync (String tableId , ByteString rowKey , @ Nullable Filter filter ) {
421+ Query query = Query .create (tableId ).rowKey (rowKey );
422+ if (filter != null ) {
423+ query = query .filter (filter );
424+ }
425+ return readRowsCallable ().first ().futureCall (query );
266426 }
267427
268428 /**
269- * Convenience method for synchronous streaming the results of a {@link Query}.
429+ * Convenience method for synchronously streaming the results of a {@link Query}.
270430 *
271431 * <p>Sample code:
272432 *
@@ -304,7 +464,7 @@ public ServerStream<Row> readRows(Query query) {
304464 }
305465
306466 /**
307- * Convenience method for asynchronous streaming the results of a {@link Query}.
467+ * Convenience method for asynchronously streaming the results of a {@link Query}.
308468 *
309469 * <p>Sample code:
310470 *
0 commit comments