Kinetica   C#   API  Version 7.2.3.1
Example.cs
Go to the documentation of this file.
1 using JDBC.NET.Data;
2 using kinetica;
3 using System.Data.Common;
4 using System.Data;
5 using NetTopologySuite.Geometries;
6 
7 namespace Example
8 {
12  public static class StringExt
13  {
14  public static string Truncate( this string value, int maxLength )
15  {
16  if ( string.IsNullOrEmpty( value ) )
17  return value;
18 
19  return ( value.Length <= maxLength ) ? value : value[..maxLength];
20  }
21  }
22 
23 
24  class Example
25  {
26  static void Main(string[] args)
27  {
28  Console.WriteLine("================================");
29  Console.WriteLine("= Example C# Project - Running =");
30  Console.WriteLine("================================");
31  Console.WriteLine();
32 
33  // Handle special commands first (before requiring URL)
34  if (args.Length > 0 && args[0].StartsWith("--"))
35  {
36  HandleCommand(args);
37  return;
38  }
39 
40  if ( args.Length < 1)
41  {
42  PrintUsage();
43  return;
44  }
45 
46  try
47  {
48  string serverUrl = args[0];
49  Console.WriteLine($"URL: {serverUrl}\n");
50 
51  Kinetica.Options _ServerOptions = new()
52  {
53  Username = args[1],
54  Password = args[2]
55  };
56 
57  string JdbcDriverPath = "";
58  if( args.Length > 3) {
59  JdbcDriverPath = args[3];
60  }
61 
62  // Run the various example functions
63  if (JdbcDriverPath.Length > 0)
64  {
65  try { JdbcExample(JdbcDriverPath, serverUrl, _ServerOptions.Username, _ServerOptions.Password); }
66  catch (Exception ex) { Console.WriteLine($"JDBC Example failed: {ex.Message}\n"); }
67  }
68 
69  try { RunExample( serverUrl, _ServerOptions ); }
70  catch (Exception ex) { Console.WriteLine($"RunExample failed: {ex.Message}\n"); }
71 
72  try { RunSeriesExample( serverUrl, _ServerOptions ); }
73  catch (Exception ex) { Console.WriteLine($"RunSeriesExample failed: {ex.Message}\n"); }
74 
75  try { RunMultiheadIngestExample( serverUrl, _ServerOptions ); }
76  catch (Exception ex) { Console.WriteLine($"RunMultiheadIngestExample failed: {ex.Message}\n"); }
77 
78  // Run the comprehensive all-types example with BulkInserter and RecordRetriever
79  try { AllTypesExample.RunAsync(serverUrl, _ServerOptions.Username, _ServerOptions.Password).GetAwaiter().GetResult(); }
80  catch (Exception ex) { Console.WriteLine($"AllTypesExample failed: {ex.Message}\n"); }
81 
82  // Run the shard key example with RecordRetriever for multi-head retrieval
83  try { ShardKeyExample.RunAsync(serverUrl, _ServerOptions.Username, _ServerOptions.Password).GetAwaiter().GetResult(); }
84  catch (Exception ex) { Console.WriteLine($"ShardKeyExample failed: {ex.Message}\n"); }
85 
86  // Run the ADO.NET batch insert example
87  try { AdoBatchInsertExample.RunAsync(serverUrl, _ServerOptions.Username, _ServerOptions.Password).GetAwaiter().GetResult(); }
88  catch (Exception ex) { Console.WriteLine($"AdoBatchInsertExample failed: {ex.Message}\n"); }
89  }
90  catch (Exception ex)
91  {
92  Console.WriteLine($"Caught Exception: {ex} {ex.Message} {ex.StackTrace}\n");
93  }
94 
95  // We're done
96  Console.WriteLine("=============================");
97  Console.WriteLine("= Example C# Project - Done =");
98  Console.WriteLine("=============================");
99  }
100 
104  static void HandleCommand(string[] args)
105  {
106  var command = args[0].ToLower();
107  var extraArgs = args.Length > 1 ? args[1..] : Array.Empty<string>();
108 
109  switch (command)
110  {
111  case "--help":
112  case "-h":
113  PrintUsage();
114  break;
115 
116  case "--dashboard":
117  BulkInserterDashboardExample.RunAsync().GetAwaiter().GetResult();
118  break;
119 
120  case "--integration":
121  BulkInserterFullIntegrationExample.RunAsync().GetAwaiter().GetResult();
122  break;
123 
124  case "--clear-table":
125  var tableName = extraArgs.Length > 0 ? extraArgs[0] : "";
126  ClearTableExample.RunAsync(tableName).GetAwaiter().GetResult();
127  break;
128 
129  case "--cleanup-all":
130  var schemaPattern = extraArgs.Length > 0 ? extraArgs[0] : "test_schema";
131  CleanupAllExample.RunAsync(schemaPattern).GetAwaiter().GetResult();
132  break;
133 
134  case "--show-tables":
135  var schemaFilter = extraArgs.Length > 0 ? extraArgs[0] : "";
136  ShowTablesExample.Run(schemaFilter);
137  break;
138 
139  case "--truncate":
140  var truncateTable = extraArgs.Length > 0 ? extraArgs[0] : "";
141  TruncateTableExample.RunAsync(truncateTable).GetAwaiter().GetResult();
142  break;
143 
144  case "--schema-demo":
145  SchemaBuilderDemo.Run();
146  break;
147 
148  default:
149  Console.WriteLine($"Unknown command: {command}");
150  PrintUsage();
151  break;
152  }
153  }
154 
158  static void PrintUsage()
159  {
160  Console.WriteLine("Usage:");
161  Console.WriteLine(" dotnet run --project Example -- <url> <user> <password> [jdbc_driver_path]");
162  Console.WriteLine();
163  Console.WriteLine("Or use one of these commands:");
164  Console.WriteLine(" --help Show this help message");
165  Console.WriteLine(" --dashboard Run BulkInserter monitoring dashboard example");
166  Console.WriteLine(" --integration Run BulkInserter full integration example");
167  Console.WriteLine(" --clear-table <name> Clear all data from a table");
168  Console.WriteLine(" --cleanup-all [pat] Drop all tables matching pattern (default: test_schema)");
169  Console.WriteLine(" --show-tables [pat] List all tables (optionally filter by schema)");
170  Console.WriteLine(" --truncate <name> Truncate a table (faster than clear-table)");
171  Console.WriteLine(" --schema-demo Show schema builder examples and reference");
172  Console.WriteLine();
173  Console.WriteLine("Environment variables for commands:");
174  Console.WriteLine(" KINETICA_URL Server URL (default: http://localhost:9191)");
175  Console.WriteLine(" KINETICA_USER Username (default: admin)");
176  Console.WriteLine(" KINETICA_PASSWORD Password (default: secret)");
177  Console.WriteLine();
178  Console.WriteLine("Examples:");
179  Console.WriteLine(" dotnet run --project Example -- http://localhost:9191 admin secret");
180  Console.WriteLine(" dotnet run --project Example -- --dashboard");
181  Console.WriteLine(" dotnet run --project Example -- --integration");
182  Console.WriteLine(" dotnet run --project Example -- --clear-table test_schema.my_table");
183  }
184 
185  #region Constants
186  private const int columnWidth = 23;
187  private const int displayLimit = 50;
188  #endregion
189 
190  #region Console Method
191  private static string AlignCenter(string text, int width)
192  {
193  text = text.Length > width ? string.Concat(text.AsSpan(0, width - 3), "...") : text;
194 
195  return !string.IsNullOrEmpty(text)
196  ? text.PadRight(width - (width - text.Length) / 2).PadLeft(width)
197  : new string(' ', width);
198  }
199 
200  private static void PrintRow(string[] columns, bool header = false)
201  {
202  var row = "|";
203  var line = "+";
204 
205  foreach (var column in columns)
206  {
207  row += AlignCenter(column, columnWidth) + "|";
208  line += new string('-', columnWidth) + "+";
209  }
210 
211  if (header)
212  {
213  Console.WriteLine(line);
214  Console.WriteLine(row);
215  Console.WriteLine(line.Replace('-', '='));
216  }
217  else
218  {
219  Console.WriteLine(row);
220  Console.WriteLine(line);
221  }
222  }
223  #endregion
224 
225  private static void PrintResult(DbDataReader reader)
226  {
227  var columns = new List<string>();
228 
229  for (var i = 0; i < reader.FieldCount; i++)
230  {
231  columns.Add(reader.GetName(i));
232  }
233 
234  PrintRow([.. columns], true);
235 
236  while (reader.Read())
237  {
238  var items = new List<string>();
239 
240  for (var i = 0; i < reader.FieldCount; i++)
241  {
242  items.Add(reader.GetString(i));
243  }
244 
245  PrintRow([.. items]);
246  }
247 
248  Console.WriteLine();
249  }
250 
251  private static string GenerateRandomId()
252  {
253  Random random = new();
254  int randomNumber = random.Next(1000, 9999); // Generates a random number between 1000 and 9999
255  return $"ID_{randomNumber}";
256  }
257 
258  private static string GenerateRandomUrl()
259  {
260  string[] domains = ["com", "net", "org", "io", "dev"];
261  string chars = "abcdefghijklmnopqrstuvwxyz0123456789";
262  Random random = new();
263 
264  string randomSubdomain = new(
265  [.. new char[8].Select(_ => chars[random.Next(chars.Length)])]);
266 
267  string randomDomain = new(
268  [.. new char[5].Select(_ => chars[random.Next(chars.Length)])]);
269 
270  string randomPath = new(
271  [.. new char[6].Select(_ => chars[random.Next(chars.Length)])]);
272 
273  string domainExtension = domains[random.Next(domains.Length)];
274 
275  return $"https://{randomSubdomain}.{randomDomain}.{domainExtension}/{randomPath}";
276  }
277 
278  private static string GenerateRandomName()
279  {
280  string[] firstNames = ["Alice", "Bob", "Charlie", "David", "Eve", "Frank", "Grace", "Helen", "Ivy", "Jack"];
281  string[] lastNames = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"];
282 
283  Random random = new();
284  string firstName = firstNames[random.Next(firstNames.Length)];
285  string lastName = lastNames[random.Next(lastNames.Length)];
286 
287  return $"{firstName} {lastName}";
288  }
289 
290  private static string GenerateGeometry() {
291  GeometryFactory factory = new();
292 
293  // Create a Polygon
294  Polygon polygon = factory.CreatePolygon(
295  [
296  new Coordinate(0, 0),
297  new Coordinate(10, 0),
298  new Coordinate(10, 10),
299  new Coordinate(0, 10),
300  new Coordinate(0, 0) // Closing the polygon
301  ]);
302  return polygon.AsText();
303 
304  }
305 
306  private static string GenerateRandomPolygon()
307  {
308  GeometryFactory factory = new();
309  Random rand = new();
310 
311  // Generate a random number of vertices (between 3 and 10)
312  int numVertices = rand.Next(3, 11);
313 
314  // Generate random coordinate bounds
315  double minX = rand.NextDouble() * 50; // Min X in range [0, 50]
316  double maxX = minX + rand.NextDouble() * 50; // Max X in range [minX, minX + 50]
317  double minY = rand.NextDouble() * 50; // Min Y in range [0, 50]
318  double maxY = minY + rand.NextDouble() * 50; // Max Y in range [minY, minY + 50]
319 
320  Coordinate[] coordinates = new Coordinate[numVertices + 1];
321 
322  for (int i = 0; i < numVertices; i++)
323  {
324  double x = rand.NextDouble() * (maxX - minX) + minX;
325  double y = rand.NextDouble() * (maxY - minY) + minY;
326  coordinates[i] = new Coordinate(x, y);
327  }
328 
329  // Ensure the polygon is closed (first and last point must be the same)
330  coordinates[numVertices] = coordinates[0];
331 
332  // Create LinearRing and Polygon
333  LinearRing ring = factory.CreateLinearRing(coordinates);
334  Polygon polygon = factory.CreatePolygon(ring);
335 
336  return polygon.AsText();
337  }
338 
339  private static DateTime GenerateRandomDate(DateTime start, DateTime end)
340  {
341  Random random = new();
342  int range = (int)(end - start).TotalSeconds; // Get total seconds between the two dates
343  return start.AddSeconds(random.Next(range));
344  }
345 
356  private static void JdbcExample(string driverPath, string serverUrl, string username, string password)
357  {
358  Console.WriteLine();
359  Console.WriteLine("Example Using a JDBC Bridge Library and the Kinetica JDBC Driver");
360  Console.WriteLine("================================================================");
361  Console.WriteLine();
362 
363  if ( driverPath.Length == 0)
364  {
365  Console.WriteLine("No Kinetica JDBC driver given; e.g.: kinetica-jdbc-7.2.2.8-jar-with-dependencies.jar\n");
366  return;
367  }
368 
369  var builder = new JdbcConnectionStringBuilder
370  {
371  DriverPath = driverPath,
372  DriverClass = "com.kinetica.jdbc.Driver",
373  JdbcUrl = $"jdbc:kinetica:URL={serverUrl};UID={username};PWD={password}"
374  };
375 
376  using var connection = new JdbcConnection(builder);
377  Console.WriteLine("Establishing connection...");
378  connection.Open();
379  Console.WriteLine("Connection established!\n");
380 
381  using JdbcCommand command = connection.CreateCommand();
382 
383  Console.WriteLine("Creating table...");
384  try
385  {
386  string ddl = @"CREATE OR REPLACE TABLE csharp_example_jdbc
387  (
388  object_id VARCHAR NOT NULL,
389  name VARCHAR NOT NULL,
390  url VARCHAR NOT NULL,
391  bounding_box GEOMETRY NOT NULL,
392  created_at DATETIME NOT NULL,
393  updated_at DATETIME NOT NULL,
394  PRIMARY KEY (object_id)
395  )
396  ";
397 
398  command.CommandText = ddl;
399 
400  command.ExecuteNonQuery();
401  }
402  catch (Exception e)
403  {
404  Console.WriteLine($"Error creating table: {e}\n");
405  return;
406  }
407 
408  Console.WriteLine("Inserting data...");
409  try
410  {
411  command.CommandText = "INSERT INTO csharp_example_jdbc VALUES (@ObjectId, @Name, @Url, @BoundingBox, @CreatedAt, @UpdatedAt)";
412  command.Parameters.Clear();
413 
414  int rowsInserted = 0;
415  for (int i = 0; i < 10; i++)
416  {
417  command.Parameters.AddWithValue("@ObjectId", GenerateRandomId());
418  command.Parameters.AddWithValue("@Name", GenerateRandomName());
419  command.Parameters.AddWithValue("@Url", GenerateRandomUrl());
420  command.Parameters.AddWithValue("@BoundingBox", GenerateRandomPolygon());
421  command.Parameters.AddWithValue("@CreatedAt", GenerateRandomDate(new DateTime(2024, 1, 1), DateTime.Now).ToString("yyyy-MM-dd HH:mm:ss"));
422  command.Parameters.AddWithValue("@UpdatedAt", GenerateRandomDate(new DateTime(2024, 1, 1), DateTime.Now).ToString("yyyy-MM-dd HH:mm:ss"));
423 
424  int rowsAffected = command.ExecuteNonQuery();
425  command.Parameters.Clear();
426  rowsInserted += rowsAffected + 1;
427  }
428  Console.WriteLine($"Rows inserted: {rowsInserted}\n");
429  }
430  catch (System.Data.Common.DbException ex)
431  {
432  Console.WriteLine($"Error inserting data: {ex}\n");
433  return;
434  }
435 
436  Console.WriteLine("Executing query...");
437  try
438  {
439  command.CommandText = "SELECT * FROM csharp_example_jdbc ORDER BY object_id";
440  command.Parameters.Clear();
441 
442  using var reader = command.ExecuteReader();
443 
444  PrintResult(reader);
445  }
446  catch (System.Data.Common.DbException ex)
447  {
448  Console.WriteLine($"Error executing query: {ex}\n");
449  return;
450  }
451 
452  Console.WriteLine("Updating data...");
453  try
454  {
455  command.CommandText = "UPDATE csharp_example_jdbc SET url = 'https://www.kinetica.com' WHERE object_id = (SELECT MIN(object_id) FROM csharp_example_jdbc)";
456  int rowsUpdated = command.ExecuteNonQuery();
457  Console.WriteLine($"Rows updated: {rowsUpdated}\n");
458  }
459  catch (System.Data.Common.DbException ex)
460  {
461  Console.WriteLine($"Error updating data: {ex}\n");
462  return;
463  }
464 
465  Console.WriteLine("Deleting data...");
466  try
467  {
468  command.CommandText = "DELETE FROM csharp_example_jdbc WHERE object_id = (SELECT MAX(object_id) FROM csharp_example_jdbc)";
469  int rowsDeleted = command.ExecuteNonQuery();
470  Console.WriteLine($"Rows deleted: {rowsDeleted}\n");
471  }
472  catch (System.Data.Common.DbException ex)
473  {
474  Console.WriteLine($"Error updating data: {ex}\n");
475  }
476 
477  Console.WriteLine("Checking data after modifications...");
478  try
479  {
480  command.CommandText = "SELECT * FROM csharp_example_jdbc ORDER BY object_id";
481  command.Parameters.Clear();
482 
483  using var reader = command.ExecuteReader();
484 
485  PrintResult(reader);
486  }
487  catch (System.Data.Common.DbException ex)
488  {
489  Console.WriteLine($"Error checking data: {ex}\n");
490  return;
491  }
492  }
493 
503  private static void RunExample(string serverUrl, Kinetica.Options serverOptions)
504  {
505  Console.WriteLine();
506  Console.WriteLine("Example with a Record Type with Nullable Columns, Primary Keys and Shard Keys");
507  Console.WriteLine("=============================================================================");
508  Console.WriteLine();
509 
510  // Establish a connection with Kinetica
511  Kinetica kdb = new(serverUrl, serverOptions);
512 
513  string tableName = "csharp_example_table";
514 
515  // Create a type for our exampleRecord class
516  Console.WriteLine("Creating the type in kinetica...");
517  // Add some interesting properties for some of the data types
518  Dictionary<string, IList<string>> columnProperties = new()
519  {
520  // And a composite primary key on two columns
521  {"A", [ColumnProperty.PRIMARY_KEY]},
524  {"E", [ColumnProperty.NULLABLE]}
525  };
526 
527  // Create the KineticaType object which facilitates creating types in the database
528  KineticaType exampleType = KineticaType.fromClass( typeof( ExampleRecord ), columnProperties );
529 
530  // Create the type in the database
531  string exampleTypeId = exampleType.create(kdb);
532  Console.WriteLine($"ID of the created type: {exampleTypeId}\n");
533 
534  // Show the type information (fetched from Kinetica)
535  Console.WriteLine("Fetching the newly created type information...");
536  ShowTypesResponse responseShowTypes = kdb.showTypes(exampleTypeId, "");
537  Console.WriteLine("Type properties:");
538  foreach ( var x in responseShowTypes.properties[0] )
539  Console.WriteLine($"\t{x.Key}: {String.Join(",", x.Value)}");
540  Console.WriteLine();
541 
542  // Clear any previously made table with the same name
543  Console.WriteLine($"Clearing any existing table named '{tableName}'...\n");
544  kdb.clearTable(tableName, "", new Dictionary<string, string> { [ClearTableRequest.Options.NO_ERROR_IF_NOT_EXISTS] = ClearTableRequest.Options.TRUE });
545 
546  // Create a table of the given type
547  Console.WriteLine($"Creating table named '{tableName}'...\n");
548  kdb.createTable( tableName, exampleTypeId );
549 
550  // Call /show/table on the table just created
551  Dictionary<string, string> optionsShowTable = new() { [ShowTableRequest.Options.GET_SIZES] = ShowTableRequest.Options.TRUE };
552  Console.WriteLine($"Calling ShowTable on '{tableName}'...");
553  var responseShowTable = kdb.showTable(tableName, optionsShowTable);
554  Console.WriteLine($"Total size: {responseShowTable.total_size}");
555  Console.WriteLine($"Sizes: {string.Join(", ", responseShowTable.sizes)}\n");
556 
557  // Create some data to be added to the table
558  List<ExampleRecord> newData = [
559  new ExampleRecord() { A=99, B=11, C="T0_lksdjfokdj92", D="D01", E= 2.34F, F=null, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
560  new ExampleRecord() { A=2, B=3, C="T1_asdfghjkl", D=null, E= 5.67F, F=null, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
561  new ExampleRecord() { A=99, B=999, C="T2_oierlwk", D="D244", E=-45.1F, F=9899.1, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds }
562  ];
563 
564  // Insert the data into the table
565  Console.WriteLine($"Inserting some data in '{tableName}'...");
566  var responseInsert = kdb.insertRecords( tableName, newData );
567  Console.WriteLine($"Inserted {responseInsert.count_inserted + responseInsert.count_updated} records\n");
568 
569  // Call /show/table on the table after adding data
570  Console.WriteLine($"Calling ShowTable on '{tableName}' after adding data...");
571  responseShowTable = kdb.showTable(tableName, optionsShowTable);
572  Console.WriteLine($"Total size: {responseShowTable.total_size}");
573  Console.WriteLine($"Sizes: {string.Join( ", ", responseShowTable.sizes )}\n");
574 
575  // Fetch the data back out of the DB using /get/records
576  Console.WriteLine($"Getting records from table '{tableName}'...");
577  var responseGetRecords = kdb.getRecords<ExampleRecord>( tableName, 0, 100 );
578  Console.WriteLine($"GetRecords got {responseGetRecords.data.Count} records:");
579  foreach ( var r in responseGetRecords.data )
580  Console.WriteLine($"\t{r}");
581  Console.WriteLine();
582 
583  // Do a filter operation
584  Console.WriteLine($"Filtering data from table '{tableName}'...");
585  string filterName = "csharp_example_filter";
586  string filterExpression = "E > 0";
587  var filterResponse = kdb.filter( tableName, filterName, filterExpression );
588  Console.WriteLine($"Filtered {filterResponse.count} records into '{filterName}'\n");
589 
590  // Do an /aggregate/groupby operation on the data
591  Console.WriteLine($"Performing a group-by aggregate operation on table '{tableName}'...");
592  IList<string> columnNames = ["A", "D"];
593  var responseGroupBy = kdb.aggregateGroupBy( tableName, columnNames, 0, 100 );
594  Console.WriteLine($"Group by got {responseGroupBy.total_number_of_records} records:");
595  // Print the decoded data out to the console
596  ( ( List<KineticaRecord> ) ( responseGroupBy.data ) ).ForEach( r => Console.WriteLine($"\t{r.ContentsToString()}") );
597  Console.WriteLine();
598 
599  // Do an /aggregate/unique operation on column F
600  string columnName = "F";
601  Console.WriteLine($"Performing a unique aggregate operation on column '{tableName}.{columnName}'...");
602  var uniqueResponse = kdb.aggregateUnique( tableName, columnName, 0, 100 );
603  // Print the decoded data out to the console
604  ( ( List<KineticaRecord> ) ( uniqueResponse.data ) ).ForEach( r => Console.WriteLine($"\t{r.ContentsToString()}") );
605  Console.WriteLine();
606 
607  // Fetch the data back out of the DB using /get/records/bycolumn
608  Console.WriteLine($"Getting records out (using /get/records/bycolumn) on table '{tableName}'...");
609  columnNames = ["B", "C", "E"];
610  var responseGetRecordsByColumn = kdb.getRecordsByColumn( tableName, columnNames, 0, 100 );
611  Console.WriteLine($"GetRecordsByColumn got {responseGetRecordsByColumn.data.Count} records:");
612  foreach ( var r in responseGetRecordsByColumn.data )
613  Console.WriteLine($"\t{r.ContentsToString()}");
614  Console.WriteLine("\n");
615  } // end RunExample
616 
617 
618 
628  private static void RunSeriesExample( string serverUrl, Kinetica.Options serverOptions )
629  {
630  Console.WriteLine();
631  Console.WriteLine("Example showcasing a record with a series type column");
632  Console.WriteLine("=====================================================");
633  Console.WriteLine();
634 
635  // Establish a connection with Kinetica
636  Kinetica kdb = new( serverUrl, serverOptions );
637 
638  Dictionary<string, IList<string>> columnProperties = new()
639  {
640  // And a composite primary key on two columns
641  {"x", [ColumnProperty.DECIMAL]},
642  };
643 
644  // Create the series type record in Kinetica
645  KineticaType seriesType = KineticaType.fromClass( typeof( SeriesRecord ), columnProperties );
646  string seriesTypeId = seriesType.create( kdb );
647  Console.WriteLine($"ID of the created series type: {seriesTypeId}\n");
648 
649  // Clear any previously made table with the same name
650  string tableName = "csharp_example_series_table";
651  Console.WriteLine($"Clearing any existing table named '{tableName}'...\n");
652  kdb.clearTable(tableName, "", new Dictionary<string, string> { [ClearTableRequest.Options.NO_ERROR_IF_NOT_EXISTS] = ClearTableRequest.Options.TRUE });
653 
654  // Create a table of the given type
655  Console.WriteLine($"Creating table named '{tableName}'...\n");
656  kdb.createTable( tableName, seriesTypeId );
657 
658  // Create some data to be added to the table
659  string series1 = "series_1";
660  string series2 = "series_2";
661  List<SeriesRecord> seriesData =
662  [
663  // Five series points moving horizontally
664  new SeriesRecord() { x = decimal.Parse("30").ToString("F4"), y = 40, TRACKID = series1, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
665  new SeriesRecord() { x = decimal.Parse("35").ToString("F4"), y = 40, TRACKID = series1, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
666  new SeriesRecord() { x = decimal.Parse("40").ToString("F4"), y = 40, TRACKID = series1, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
667  new SeriesRecord() { x = decimal.Parse("45").ToString("F4"), y = 40, TRACKID = series1, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
668  new SeriesRecord() { x = decimal.Parse("50").ToString("F4"), y = 40, TRACKID = series1, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
669  // Five series points moving vertically
670  new SeriesRecord() { x = decimal.Parse("-30").ToString("F4"), y = -40, TRACKID = series2, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
671  new SeriesRecord() { x = decimal.Parse("-30").ToString("F4"), y = -45, TRACKID = series2, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
672  new SeriesRecord() { x = decimal.Parse("-30").ToString("F4"), y = -50, TRACKID = series2, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
673  new SeriesRecord() { x = decimal.Parse("-30").ToString("F4"), y = -55, TRACKID = series2, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
674  new SeriesRecord() { x = decimal.Parse("-30").ToString("F4"), y = -60, TRACKID = series2, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
675  ];
676 
677  // Insert the data into the table
678  Console.WriteLine($"Inserting some data in '{tableName}'...");
679  var responseInsert = kdb.insertRecords(tableName, seriesData);
680  Console.WriteLine($"Inserted {responseInsert.count_inserted + responseInsert.count_updated} records\n");
681 
682 
683  // Fetch the data back out of the DB using /get/records
684  Console.WriteLine($"Getting records from table '{tableName}'...");
685  var responseGetRecords = kdb.getRecords<SeriesRecord>(tableName);
686  Console.WriteLine($"GetRecords got {responseGetRecords.data.Count} records:");
687  foreach (var r in responseGetRecords.data)
688  Console.WriteLine($"\t{r}");
689  Console.WriteLine();
690 
691 
692  // Filter the series data such that only a few series point from only one of the series
693  // are in the view
694  Console.WriteLine($"Filtering data from {tableName} so that only some points from {series1} make it...");
695  string filterName = "csharp_example_series_filter";
696  // Only the first, second, and third records from the first series should survive this filter
697  // (for track/series type records, we're filtering the "line segments", so records just outside the
698  // filtered box will also be captured)
699  var responseFilter = kdb.filterByBox( tableName, filterName, "x", 33, 37, "y", 35, 45 );
700  Console.WriteLine($"Filtered {responseFilter.count} records into '{filterName}'\n");
701 
702  // Show the filtered objects
703  responseGetRecords = kdb.getRecords<SeriesRecord>( filterName );
704  Console.WriteLine($"GetRecords got {responseGetRecords.data.Count} records from '{filterName}':");
705  foreach ( var r in responseGetRecords.data )
706  Console.WriteLine($"\t{r}");
707  Console.WriteLine();
708 
709 
710  // Extract the entire series from the source table (based on which ones are in the view)
711  Console.WriteLine($"Getting records belonging to one series out from table '{tableName}' using the partial series in filter '{filterName}'...");
712  var getRecordsBySeriesResp = kdb.getRecordsBySeries<SeriesRecord>( filterName, tableName );
713  Console.WriteLine($"GetRecordsBySeries got {getRecordsBySeriesResp.data.Count} list of records (should get one list of five records in it):");
714  foreach ( var rSeries in getRecordsBySeriesResp.data )
715  foreach ( var r in rSeries ) Console.WriteLine($"\t{r}");
716  Console.WriteLine("\n");
717  } // end RunSeriesExample()
718 
719 
728  private static void RunMultiheadIngestExample( string serverUrl, Kinetica.Options serverOptions )
729  {
730  Console.WriteLine();
731  Console.WriteLine("Example showcasing multihead ingestion(one shard key, two primary keys)");
732  Console.WriteLine("=======================================================================");
733  Console.WriteLine();
734 
735  // Establish a connection with Kinetica
736  Kinetica kdb = new( serverUrl, serverOptions );
737 
738  // Create a type for our exampleRecord class
739  // Add some interesting properties for some of the data types
740  Dictionary<string, IList<string>> columnProperties = new()
741  {
742  // Add a primary key
743  { "A", [ColumnProperty.PRIMARY_KEY] },
744 
745  // And a shard key (must be part of the primary keys, if specified--which we have)
747  };
748 
749  // Create the KineticaType object which facilitates creating types in the database
750  KineticaType exampleType = KineticaType.fromClass( typeof( ExampleRecord ), columnProperties );
751 
752  // Create the type in the database
753  string exampleTypeId = exampleType.create( kdb );
754 
755  // Clear any previously made table with the same name
756  string tableName = "csharp_example_multihead_table";
757  Console.WriteLine($"Clearing any existing table named '{tableName}'...\n");
758  kdb.clearTable(tableName, "", new Dictionary<string, string> { [ClearTableRequest.Options.NO_ERROR_IF_NOT_EXISTS] = ClearTableRequest.Options.TRUE });
759 
760  // Create a table of the given type
761  Console.WriteLine($"Creating table named '{tableName}'...\n");
762  kdb.createTable( tableName, exampleTypeId );
763 
764  // Create the ingestor (we're not giving any worker IP addresses; the ingestor class will figure it
765  // out by itself)
766  int batchSize = 100;
767  KineticaIngestor<ExampleRecord> ingestor = new( kdb, tableName, batchSize, exampleType );
768 
769  // Generate data to be inserted
770  int totalRecords = batchSize * 5;
771  List<ExampleRecord> records = [];
772  Random rng = new();
773  double nullProbability = 0.2;
774  for ( int i = 0; i < totalRecords; ++i )
775  {
776  // Restricting string length to 256
777  int maxStringLength = rng.Next( 0, 256 );
778  ExampleRecord record = new ()
779  {
780  A = rng.Next(),
781  B = rng.Next(),
782  C = System.IO.Path.GetRandomFileName().Truncate( maxStringLength ),
783  D = System.IO.Path.GetRandomFileName().Truncate( maxStringLength ),
784  E = (1.0F / rng.Next()),
785  F = ( rng.NextDouble() < nullProbability ) ? null : ( double? ) ( rng.NextDouble() * (1.0F / rng.Next()) ),
786  TIMESTAMP = (long)rng.Next( -306102240, 293795424 ) * rng.Next( 100000 )
787  };
788 
789  records.Add( record );
790  } // end for loop
791 
792  Console.WriteLine( $"Generated {totalRecords} records.\n" );
793 
794  // Insert the records into the ingestor
795  Console.WriteLine( $"Inserting {totalRecords} records..." );
796  ingestor.insert( records );
797 
798  // Flush the ingestor (which actually inserts the records)
799  Console.WriteLine( "Flushing any remaining records..." );
800  ingestor.flush();
801 
802  // Call /show/table on the table after adding data
803  Console.WriteLine($"Calling ShowTable on '{tableName}' after adding data...");
804  var responseShowTable = kdb.showTable(tableName, new Dictionary<string,string> { [ShowTableRequest.Options.GET_SIZES] = ShowTableRequest.Options.TRUE });
805  Console.WriteLine($"Total size: {responseShowTable.total_size}");
806 
807  Console.WriteLine("\n");
808  } // end run_multihead_ingest_example()
809 
810 
811  private class ExampleRecord
812  {
813  public int A { get; set; }
814  public int B { get; set; }
815  public string? C { get; set; }
816  public string? D { get; set; }
817  public float E { get; set; }
818  public double? F { get; set; }
819  public long TIMESTAMP { get; set; }
820 
821  public override string ToString()
822  {
823  string f;
824  if ( F != null )
825  f = $"{F}";
826  else
827  f = "<null>";
828  return $"{{ A={A}, B={B}, C={C}, D={D}, E={E}, F={f}, TIMESTAMP={TIMESTAMP} }}";
829  }
830  } // end class exampleRecord
831 
832 
833  private class SeriesRecord
834  {
835  public string? x { get; set; }
836  public double y { get; set; }
837  public string? TRACKID { get; set; }
838  public long TIMESTAMP { get; set; }
839 
840  public override string ToString()
841  {
842  return $"{{ x={x}, y={y}, TRACKID={TRACKID}, TIMESTAMP={TIMESTAMP} }}";
843  }
844  } // end class record_type_series
845  }
846 }
void insert(T record)
Queues a record for insertion into Kinetica.
const string PRIMARY_KEY
This property indicates that this column will be part of (or the entire) primary key.
const string GET_SIZES
If TRUE then the number of records in each table, along with a cumulative count, will be returned; bl...
Definition: ShowTable.cs:128
IList< IDictionary< string, IList< string > > > properties
Definition: ShowTypes.cs:134
CreateTableResponse createTable(CreateTableRequest request_)
Creates a new table with the given type (definition of columns).
A set of parameters for Kinetica.clearTable.
Definition: ClearTable.cs:19
Column properties used for Kinetica types.
const string TIMESTAMP
Valid only for 'long' columns.
const string CHAR4
This property provides optimized memory, disk and query performance for string columns.
AggregateGroupByResponse aggregateGroupBy(AggregateGroupByRequest request_)
Calculates unique combinations (groups) of values for the given columns in a given table or view and ...
const string DECIMAL
Valid only for 'string' columns.
A set of string constants for the parameter options.
Definition: ClearTable.cs:24
ClearTableResponse clearTable(ClearTableRequest request_)
Clears (drops) one or all tables in the database cluster.
ShowTableResponse showTable(ShowTableRequest request_)
Retrieves detailed information about a table, view, or schema, specified in table_name.
static KineticaType fromClass(Type recordClass, IDictionary< string, IList< string >> properties=null)
Create a KineticaType object from properties of a record class and Kinetica column properties.
A set of parameters for Kinetica.showTable.
Definition: ShowTable.cs:43
const string SHARD_KEY
This property indicates that this column will be part of (or the entire) shard key.
A set of string constants for the parameter options.
Definition: ShowTable.cs:48
string create(Kinetica kinetica)
Given a handle to the server, creates a type in the database based on this data type.
static string Truncate(this string value, int maxLength)
Definition: Example.cs:14
FilterResponse filter(FilterRequest request_)
Filters data based on the specified expression.
Failover to clusters in a random order (default)
AggregateUniqueResponse aggregateUnique(AggregateUniqueRequest request_)
Returns all the unique values from a particular column (specified by column_name) of a particular tab...
ShowTypesResponse showTypes(ShowTypesRequest request_)
Retrieves information for the specified data type ID or type label.
GetRecordsByColumnResponse getRecordsByColumn(GetRecordsByColumnRequest request_)
For a given table, retrieves the values from the requested column(s).
FilterByBoxResponse filterByBox(FilterByBoxRequest request_)
Calculates how many objects within the given table lie in a rectangular box.
const string NO_ERROR_IF_NOT_EXISTS
If TRUE and if the table specified in table_name does not exist no error is returned.
Definition: ClearTable.cs:40
DateTime in YYYY-MM-DD HH:MM:SS.mmm format
const string NULLABLE
This property indicates that this column is nullable.
A set of results returned by Kinetica.showTypes.
Definition: ShowTypes.cs:126
Manages the insertion into GPUdb of large numbers of records in bulk, with automatic batch management...
void flush()
Ensures that all queued records are inserted into Kinetica.