internal HelloWorld(HelloWorldSettings settings) { _settings = settings; _bigtableTableAdminClient = BigtableTableAdminClient.Create(); _bigtableClient = BigtableClient.Create(); _tableNameAdmin = new Google.Cloud.Bigtable.Admin.V2.TableName(_settings.ProjectId, _settings.InstanceId, _settings.TableName); _tableNameClient = new Google.Cloud.Bigtable.V2.TableName(_settings.ProjectId, _settings.InstanceId, _settings.TableName); }
private static void DoHelloWorld() { try { // BigtableTableAdminClient API lets us create, manage and delete tables. BigtableTableAdminClient bigtableTableAdminClient = BigtableTableAdminClient.Create(); // Create a table with a single column family. Console.WriteLine($"Create new table: {tableId} with column family: {columnFamily}, Instance: {instanceId}"); // Check whether a table with given TableName already exists. if (!TableExist(bigtableTableAdminClient)) { bigtableTableAdminClient.CreateTable( new InstanceName(projectId, instanceId), tableId, new Table { Granularity = Table.Types.TimestampGranularity.Millis, ColumnFamilies = { { columnFamily, new ColumnFamily { GcRule = new GcRule { MaxNumVersions = 1 } } } } }); // Confirm that table was created successfully. Console.WriteLine(TableExist(bigtableTableAdminClient) ? $"Table {tableId} created succsessfully\n" : $"There was a problem creating a table {tableId}"); } else { Console.WriteLine($"Table: {tableId} already exist"); } // BigtableClient API lets us read and write to a table. BigtableClient bigtableClient = BigtableClient.Create(); // Initialise Google.Cloud.Bigtable.V2.TableName object. Google.Cloud.Bigtable.V2.TableName tableNameClient = new Google.Cloud.Bigtable.V2.TableName(projectId, instanceId, tableId); // Write some rows /* Each row has a unique row key. * * Note: This example uses sequential numeric IDs for simplicity, but * this can result in poor performance in a production application. * Since rows are stored in sorted order by key, sequential keys can * result in poor distribution of operations across nodes. * * For more information about how to design a Bigtable schema for the * best performance, see the documentation: * * https://cloud.google.com/bigtable/docs/schema-design */ Console.WriteLine($"Write some greetings to the table {tableId}"); // Insert 1 row using MutateRow() s_greetingIndex = 0; try { bigtableClient.MutateRow(tableNameClient, rowKeyPrefix + s_greetingIndex, MutationBuilder(s_greetingIndex)); Console.WriteLine($"\tGreeting: -- {s_greetings[s_greetingIndex],-18}-- written successfully"); } catch (Exception ex) { Console.WriteLine($"\tFailed to write Greeting: --{s_greetings[s_greetingIndex]}"); Console.WriteLine(ex.Message); throw; } // Insert multiple rows using MutateRows() // Build a MutateRowsRequest (contains table name and a collection of entries). MutateRowsRequest request = new MutateRowsRequest { TableNameAsTableName = tableNameClient }; s_mapToOriginalGreetingIndex = new List <int>(); while (++s_greetingIndex < s_greetings.Length) { s_mapToOriginalGreetingIndex.Add(s_greetingIndex); // Build an entry for every greeting (consists of rowkey and a collection of mutations). string rowKey = rowKeyPrefix + s_greetingIndex; request.Entries.Add(Mutations.CreateEntry(rowKey, MutationBuilder(s_greetingIndex))); } // Make the request to write multiple rows. MutateRowsResponse response = bigtableClient.MutateRows(request); // Check the Status code of each entry to insure that it was written successfully foreach (MutateRowsResponse.Types.Entry entry in response.Entries) { s_greetingIndex = s_mapToOriginalGreetingIndex[(int)entry.Index]; if (entry.Status.Code == 0) { Console.WriteLine($"\tGreeting: -- {s_greetings[s_greetingIndex],-18}-- written successfully"); } else { Console.WriteLine($"\tFailed to write Greeting: --{s_greetings[s_greetingIndex]}"); Console.WriteLine(entry.Status.Message); } } // Read from the table. Console.WriteLine("Read the first row"); int rowIndex = 0; // Read a specific row. Apply filter to return latest only cell value accross entire row. Row rowRead = bigtableClient.ReadRow( tableNameClient, rowKey: rowKeyPrefix + rowIndex, filter: RowFilters.CellsPerRowLimit(1)); Console.WriteLine( $"\tRow key: {rowRead.Key.ToStringUtf8()} " + $" -- Value: {rowRead.Families[0].Columns[0].Cells[0].Value.ToStringUtf8(),-16} " + $" -- Time Stamp: {rowRead.Families[0].Columns[0].Cells[0].TimestampMicros}"); Console.WriteLine("Read all rows using streaming"); // stream the content of the whole table. Apply filter to return latest only cell values accross all rows. ReadRowsStream responseRead = bigtableClient.ReadRows(tableNameClient, filter: RowFilters.CellsPerRowLimit(1)); Task printRead = PrintReadRowsAsync(responseRead); printRead.Wait(); // Clean up. Delete the table. Console.WriteLine($"Delete table: {tableId}"); bigtableTableAdminClient.DeleteTable(name: new Google.Cloud.Bigtable.Admin.V2.TableName(projectId, instanceId, tableId)); if (!TableExist(bigtableTableAdminClient)) { Console.WriteLine($"Table: {tableId} deleted succsessfully"); } } catch (Exception ex) { Console.WriteLine($"Exception while running HelloWorld {ex.Message}"); } }
/// <summary> /// Returns the contents of the requested row, optionally applying the specified Reader filter. /// </summary> /// <remarks> /// <para> /// This method simply delegates to <see cref="ReadRowAsync(TableName, BigtableByteString, RowFilter, CallSettings)"/>. /// </para> /// </remarks> /// <param name="tableName"> /// The unique name of the table from which to read. Must not be null. /// </param> /// <param name="rowKey"> /// The key of the row to read. Must not be empty. /// </param> /// <param name="filter"> /// The filter to apply to the contents of the specified row. If null, /// reads the entirety of the row. /// </param> /// <param name="callSettings"> /// If not null, applies overrides to this RPC call. /// </param> /// <returns> /// The row from the server or null if it does not exist. /// </returns> public virtual Row ReadRow( TableName tableName, BigtableByteString rowKey, RowFilter filter = null, CallSettings callSettings = null) => Task.Run(() => ReadRowAsync(tableName, rowKey, filter, callSettings)).ResultWithUnwrappedExceptions();
/// <summary> /// Asynchronously mutates a row atomically. Cells already present in the row are left /// unchanged unless explicitly changed by <paramref name="mutations"/>. /// </summary> /// <remarks> /// <para> /// Note that string is implicitly convertible to <see cref="BigtableByteString"/>, so <paramref name="rowKey"/> can /// be specified using a string as well and its UTF-8 representations will be used. /// </para> /// <para> /// This method simply delegates to <see cref="MutateRowAsync(MutateRowRequest, CallSettings)"/>. /// </para> /// </remarks> /// <param name="tableName"> /// The unique name of the table to which the mutation should be applied. Must not be null. /// </param> /// <param name="rowKey"> /// The key of the row to which the mutation should be applied. Must not be empty. /// </param> /// <param name="mutations"> /// Changes to be atomically applied to the specified row. Entries are applied /// in order, meaning that earlier mutations can be masked by later ones. /// Must contain at least one entry and at most 100000. Must not be null, or contain null /// elements. /// </param> /// <returns> /// The response from mutating the row. /// </returns> public virtual Task <MutateRowResponse> MutateRowAsync( TableName tableName, BigtableByteString rowKey, params Mutation[] mutations) => MutateRowAsync( CreateMutateRowRequest(tableName, rowKey, mutations));
/// <summary> /// Asynchronously modifies a row atomically on the server. The method reads the latest existing version /// and value from the specified columns and writes a new entry based on /// pre-defined read/modify/write rules. The new value for the version is the /// greater of the previous value's version or the current server version. The method /// returns the new contents of all modified cells. /// </summary> /// <remarks> /// <para> /// Note that the server version is based on the current timestamp since the Unix epoch, so for /// columns which are updated using ReadModifyWriteRow, other reads and writes of those columns /// should use <see cref="BigtableVersion"/> values constructed from DateTime values, as opposed /// to using a custom versioning scheme with 64-bit values. /// </para> /// <para> /// Note that string is implicitly convertible to <see cref="BigtableByteString"/>, so <paramref name="rowKey"/> can /// be specified using a string as well and its UTF-8 representations will be used. /// </para> /// <para> /// This method simply delegates to <see cref="ReadModifyWriteRowAsync(ReadModifyWriteRowRequest, CallSettings)"/>. /// </para> /// </remarks> /// <param name="tableName"> /// The unique name of the table to which the read/modify/write rules should be /// applied. Must not be null. /// </param> /// <param name="rowKey"> /// The key of the row to which the read/modify/write rules should be applied. /// Must not be empty. /// </param> /// <param name="rules"> /// Rules specifying how the specified row's contents are to be transformed /// into writes. Entries are applied in order, meaning that earlier rules will /// affect the results of later ones. Must not be null, or contain null /// elements. /// </param> /// <returns> /// The response from modifying the row. /// </returns> public virtual Task <ReadModifyWriteRowResponse> ReadModifyWriteRowAsync( TableName tableName, BigtableByteString rowKey, params ReadModifyWriteRule[] rules) => ReadModifyWriteRowAsync( CreateReadModifyWriteRowRequest(tableName, rowKey, rules));
/// <summary> /// Mutates multiple rows in a batch. Each individual row is mutated /// atomically as in <see cref="MutateRow(MutateRowRequest, CallSettings)"/>, /// but the entire batch is not executed atomically. /// </summary> /// <remarks> /// <para> /// This method simply delegates to <see cref="MutateRowsAsync(TableName, IEnumerable{MutateRowsRequest.Types.Entry}, CallSettings)"/>. /// </para> /// </remarks> /// <param name="tableName"> /// The unique name of the table to which the mutations should be applied. Must not be null. /// </param> /// <param name="entries"> /// The row keys and corresponding mutations to be applied in bulk. /// Each entry is applied as an atomic mutation, but the entries may be /// applied in arbitrary order (even between entries for the same row). /// At least one entry must be specified, and in total the entries can /// contain at most 100000 mutations. /// </param> /// <returns> /// The response from mutating the rows. /// </returns> public virtual Task <MutateRowsResponse> MutateRowsAsync( TableName tableName, params MutateRowsRequest.Types.Entry[] entries) => MutateRowsAsync(tableName, entries, callSettings: null);
/// <summary> /// Mutates multiple rows in a batch. Each individual row is mutated /// atomically as in <see cref="MutateRow(MutateRowRequest, CallSettings)"/>, /// but the entire batch is not executed atomically. /// </summary> /// <remarks> /// <para> /// This method simply delegates to <see cref="MutateRowsAsync(MutateRowsRequest, CallSettings)"/>. /// </para> /// </remarks> /// <param name="tableName"> /// The unique name of the table to which the mutations should be applied. Must not be null. /// </param> /// <param name="entries"> /// The row keys and corresponding mutations to be applied in bulk. /// Each entry is applied as an atomic mutation, but the entries may be /// applied in arbitrary order (even between entries for the same row). /// At least one entry must be specified, and in total the entries can /// contain at most 100000 mutations. Must not be null, or contain null /// elements. /// </param> /// <param name="callSettings"> /// If not null, applies overrides to this RPC call. /// </param> /// <returns> /// The response from mutating the rows. /// </returns> public virtual Task <MutateRowsResponse> MutateRowsAsync( TableName tableName, IEnumerable <MutateRowsRequest.Types.Entry> entries, CallSettings callSettings = null) => MutateRowsAsync(CreateMutateRowRequest(tableName, entries), callSettings);
/// <summary> /// Mutates multiple rows in a batch. Each individual row is mutated /// atomically as in <see cref="MutateRow(MutateRowRequest, CallSettings)"/>, /// but the entire batch is not executed atomically. /// </summary> /// <remarks> /// <para> /// Note this method executes a server streaming RPC. It is not a synchronous call. The caller must process the responses from /// stream as they are returned from the server. Each response will indicate the status for one or more entry of mutations. /// </para> /// <para> /// This method simply delegates to <see cref="MutateRows(TableName, IEnumerable{MutateRowsRequest.Types.Entry}, CallSettings)"/>. /// </para> /// </remarks> /// <param name="tableName"> /// The unique name of the table to which the mutations should be applied. Must not be null. /// </param> /// <param name="entries"> /// The row keys and corresponding mutations to be applied in bulk. /// Each entry is applied as an atomic mutation, but the entries may be /// applied in arbitrary order (even between entries for the same row). /// At least one entry must be specified, and in total the entries can /// contain at most 100000 mutations. /// </param> /// <returns> /// The server stream. /// </returns> public virtual MutateRowsStream MutateRows( TableName tableName, params MutateRowsRequest.Types.Entry[] entries) => MutateRows(tableName, entries, callSettings: null);