Kinetica   C#   API  Version 7.2.3.0
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  if ( args.Length < 1)
34  {
35  Console.WriteLine("Missing URL as command-line parameter; e.g.: http://localhost:9191");
36  return;
37  }
38 
39  try
40  {
41  string serverUrl = args[0];
42  Console.WriteLine($"URL: {serverUrl}\n");
43 
44  Kinetica.Options _ServerOptions = new()
45  {
46  Username = args[1],
47  Password = args[2]
48  };
49 
50  string JdbcDriverPath = "";
51  if( args.Length > 3) {
52  JdbcDriverPath = args[3];
53  }
54 
55  // Run the various example functions
56  JdbcExample(JdbcDriverPath, serverUrl, _ServerOptions.Username, _ServerOptions.Password);
57  RunExample( serverUrl, _ServerOptions );
58  RunSeriesExample( serverUrl, _ServerOptions );
59  RunMultiheadIngestExample( serverUrl, _ServerOptions );
60  }
61  catch (Exception ex)
62  {
63  Console.WriteLine($"Caught Exception: {ex} {ex.Message} {ex.StackTrace}\n");
64  }
65 
66  // We're done
67  Console.WriteLine("=============================");
68  Console.WriteLine("= Example C# Project - Done =");
69  Console.WriteLine("=============================");
70  }
71 
72  #region Constants
73  private const int columnWidth = 23;
74  private const int displayLimit = 50;
75  #endregion
76 
77  #region Console Method
78  private static string AlignCenter(string text, int width)
79  {
80  text = text.Length > width ? string.Concat(text.AsSpan(0, width - 3), "...") : text;
81 
82  return !string.IsNullOrEmpty(text)
83  ? text.PadRight(width - (width - text.Length) / 2).PadLeft(width)
84  : new string(' ', width);
85  }
86 
87  private static void PrintRow(string[] columns, bool header = false)
88  {
89  var row = "|";
90  var line = "+";
91 
92  foreach (var column in columns)
93  {
94  row += AlignCenter(column, columnWidth) + "|";
95  line += new string('-', columnWidth) + "+";
96  }
97 
98  if (header)
99  {
100  Console.WriteLine(line);
101  Console.WriteLine(row);
102  Console.WriteLine(line.Replace('-', '='));
103  }
104  else
105  {
106  Console.WriteLine(row);
107  Console.WriteLine(line);
108  }
109  }
110  #endregion
111 
112  private static void PrintResult(DbDataReader reader)
113  {
114  var columns = new List<string>();
115 
116  for (var i = 0; i < reader.FieldCount; i++)
117  {
118  columns.Add(reader.GetName(i));
119  }
120 
121  PrintRow([.. columns], true);
122 
123  while (reader.Read())
124  {
125  var items = new List<string>();
126 
127  for (var i = 0; i < reader.FieldCount; i++)
128  {
129  items.Add(reader.GetString(i));
130  }
131 
132  PrintRow([.. items]);
133  }
134 
135  Console.WriteLine();
136  }
137 
138  private static string GenerateRandomId()
139  {
140  Random random = new();
141  int randomNumber = random.Next(1000, 9999); // Generates a random number between 1000 and 9999
142  return $"ID_{randomNumber}";
143  }
144 
145  private static string GenerateRandomUrl()
146  {
147  string[] domains = ["com", "net", "org", "io", "dev"];
148  string chars = "abcdefghijklmnopqrstuvwxyz0123456789";
149  Random random = new();
150 
151  string randomSubdomain = new(
152  [.. new char[8].Select(_ => chars[random.Next(chars.Length)])]);
153 
154  string randomDomain = new(
155  [.. new char[5].Select(_ => chars[random.Next(chars.Length)])]);
156 
157  string randomPath = new(
158  [.. new char[6].Select(_ => chars[random.Next(chars.Length)])]);
159 
160  string domainExtension = domains[random.Next(domains.Length)];
161 
162  return $"https://{randomSubdomain}.{randomDomain}.{domainExtension}/{randomPath}";
163  }
164 
165  private static string GenerateRandomName()
166  {
167  string[] firstNames = ["Alice", "Bob", "Charlie", "David", "Eve", "Frank", "Grace", "Helen", "Ivy", "Jack"];
168  string[] lastNames = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"];
169 
170  Random random = new();
171  string firstName = firstNames[random.Next(firstNames.Length)];
172  string lastName = lastNames[random.Next(lastNames.Length)];
173 
174  return $"{firstName} {lastName}";
175  }
176 
177  private static string GenerateGeometry() {
178  GeometryFactory factory = new();
179 
180  // Create a Polygon
181  Polygon polygon = factory.CreatePolygon(
182  [
183  new Coordinate(0, 0),
184  new Coordinate(10, 0),
185  new Coordinate(10, 10),
186  new Coordinate(0, 10),
187  new Coordinate(0, 0) // Closing the polygon
188  ]);
189  return polygon.AsText();
190 
191  }
192 
193  private static string GenerateRandomPolygon()
194  {
195  GeometryFactory factory = new();
196  Random rand = new();
197 
198  // Generate a random number of vertices (between 3 and 10)
199  int numVertices = rand.Next(3, 11);
200 
201  // Generate random coordinate bounds
202  double minX = rand.NextDouble() * 50; // Min X in range [0, 50]
203  double maxX = minX + rand.NextDouble() * 50; // Max X in range [minX, minX + 50]
204  double minY = rand.NextDouble() * 50; // Min Y in range [0, 50]
205  double maxY = minY + rand.NextDouble() * 50; // Max Y in range [minY, minY + 50]
206 
207  Coordinate[] coordinates = new Coordinate[numVertices + 1];
208 
209  for (int i = 0; i < numVertices; i++)
210  {
211  double x = rand.NextDouble() * (maxX - minX) + minX;
212  double y = rand.NextDouble() * (maxY - minY) + minY;
213  coordinates[i] = new Coordinate(x, y);
214  }
215 
216  // Ensure the polygon is closed (first and last point must be the same)
217  coordinates[numVertices] = coordinates[0];
218 
219  // Create LinearRing and Polygon
220  LinearRing ring = factory.CreateLinearRing(coordinates);
221  Polygon polygon = factory.CreatePolygon(ring);
222 
223  return polygon.AsText();
224  }
225 
226  private static DateTime GenerateRandomDate(DateTime start, DateTime end)
227  {
228  Random random = new();
229  int range = (int)(end - start).TotalSeconds; // Get total seconds between the two dates
230  return start.AddSeconds(random.Next(range));
231  }
232 
243  private static void JdbcExample(string driverPath, string serverUrl, string username, string password)
244  {
245  Console.WriteLine();
246  Console.WriteLine("Example Using a JDBC Bridge Library and the Kinetica JDBC Driver");
247  Console.WriteLine("================================================================");
248  Console.WriteLine();
249 
250  if ( driverPath.Length == 0)
251  {
252  Console.WriteLine("No Kinetica JDBC driver given; e.g.: kinetica-jdbc-7.2.2.8-jar-with-dependencies.jar\n");
253  return;
254  }
255 
256  var builder = new JdbcConnectionStringBuilder
257  {
258  DriverPath = driverPath,
259  DriverClass = "com.kinetica.jdbc.Driver",
260  JdbcUrl = $"jdbc:kinetica:URL={serverUrl};UID={username};PWD={password}"
261  };
262 
263  using var connection = new JdbcConnection(builder);
264  Console.WriteLine("Establishing connection...");
265  connection.Open();
266  Console.WriteLine("Connection established!\n");
267 
268  using JdbcCommand command = connection.CreateCommand();
269 
270  Console.WriteLine("Creating table...");
271  try
272  {
273  string ddl = @"CREATE OR REPLACE TABLE csharp_example_jdbc
274  (
275  object_id VARCHAR NOT NULL,
276  name VARCHAR NOT NULL,
277  url VARCHAR NOT NULL,
278  bounding_box GEOMETRY NOT NULL,
279  created_at DATETIME NOT NULL,
280  updated_at DATETIME NOT NULL,
281  PRIMARY KEY (object_id)
282  )
283  ";
284 
285  command.CommandText = ddl;
286 
287  command.ExecuteNonQuery();
288  }
289  catch (Exception e)
290  {
291  Console.WriteLine($"Error creating table: {e}\n");
292  return;
293  }
294 
295  Console.WriteLine("Inserting data...");
296  try
297  {
298  command.CommandText = "INSERT INTO csharp_example_jdbc VALUES (@ObjectId, @Name, @Url, @BoundingBox, @CreatedAt, @UpdatedAt)";
299  command.Parameters.Clear();
300 
301  int rowsInserted = 0;
302  for (int i = 0; i < 10; i++)
303  {
304  command.Parameters.AddWithValue("@ObjectId", GenerateRandomId());
305  command.Parameters.AddWithValue("@Name", GenerateRandomName());
306  command.Parameters.AddWithValue("@Url", GenerateRandomUrl());
307  command.Parameters.AddWithValue("@BoundingBox", GenerateRandomPolygon());
308  command.Parameters.AddWithValue("@CreatedAt", GenerateRandomDate(new DateTime(2024, 1, 1), DateTime.Now).ToString("yyyy-MM-dd HH:mm:ss"));
309  command.Parameters.AddWithValue("@UpdatedAt", GenerateRandomDate(new DateTime(2024, 1, 1), DateTime.Now).ToString("yyyy-MM-dd HH:mm:ss"));
310 
311  int rowsAffected = command.ExecuteNonQuery();
312  command.Parameters.Clear();
313  rowsInserted += rowsAffected + 1;
314  }
315  Console.WriteLine($"Rows inserted: {rowsInserted}\n");
316  }
317  catch (System.Data.Common.DbException ex)
318  {
319  Console.WriteLine($"Error inserting data: {ex}\n");
320  return;
321  }
322 
323  Console.WriteLine("Executing query...");
324  try
325  {
326  command.CommandText = "SELECT * FROM csharp_example_jdbc ORDER BY object_id";
327  command.Parameters.Clear();
328 
329  using var reader = command.ExecuteReader();
330 
331  PrintResult(reader);
332  }
333  catch (System.Data.Common.DbException ex)
334  {
335  Console.WriteLine($"Error executing query: {ex}\n");
336  return;
337  }
338 
339  Console.WriteLine("Updating data...");
340  try
341  {
342  command.CommandText = "UPDATE csharp_example_jdbc SET url = 'https://www.kinetica.com' WHERE object_id = (SELECT MIN(object_id) FROM csharp_example_jdbc)";
343  int rowsUpdated = command.ExecuteNonQuery();
344  Console.WriteLine($"Rows updated: {rowsUpdated}\n");
345  }
346  catch (System.Data.Common.DbException ex)
347  {
348  Console.WriteLine($"Error updating data: {ex}\n");
349  return;
350  }
351 
352  Console.WriteLine("Deleting data...");
353  try
354  {
355  command.CommandText = "DELETE FROM csharp_example_jdbc WHERE object_id = (SELECT MAX(object_id) FROM csharp_example_jdbc)";
356  int rowsDeleted = command.ExecuteNonQuery();
357  Console.WriteLine($"Rows deleted: {rowsDeleted}\n");
358  }
359  catch (System.Data.Common.DbException ex)
360  {
361  Console.WriteLine($"Error updating data: {ex}\n");
362  }
363 
364  Console.WriteLine("Checking data after modifications...");
365  try
366  {
367  command.CommandText = "SELECT * FROM csharp_example_jdbc ORDER BY object_id";
368  command.Parameters.Clear();
369 
370  using var reader = command.ExecuteReader();
371 
372  PrintResult(reader);
373  }
374  catch (System.Data.Common.DbException ex)
375  {
376  Console.WriteLine($"Error checking data: {ex}\n");
377  return;
378  }
379  }
380 
390  private static void RunExample(string serverUrl, Kinetica.Options serverOptions)
391  {
392  Console.WriteLine();
393  Console.WriteLine("Example with a Record Type with Nullable Columns, Primary Keys and Shard Keys");
394  Console.WriteLine("=============================================================================");
395  Console.WriteLine();
396 
397  // Establish a connection with Kinetica
398  Kinetica kdb = new(serverUrl, serverOptions);
399 
400  string tableName = "csharp_example_table";
401 
402  // Create a type for our exampleRecord class
403  Console.WriteLine("Creating the type in kinetica...");
404  // Add some interesting properties for some of the data types
405  Dictionary<string, IList<string>> columnProperties = new()
406  {
407  // And a composite primary key on two columns
408  {"A", [ColumnProperty.PRIMARY_KEY]},
411  {"E", [ColumnProperty.NULLABLE]}
412  };
413 
414  // Create the KineticaType object which facilitates creating types in the database
415  KineticaType exampleType = KineticaType.fromClass( typeof( ExampleRecord ), columnProperties );
416 
417  // Create the type in the database
418  string exampleTypeId = exampleType.create(kdb);
419  Console.WriteLine($"ID of the created type: {exampleTypeId}\n");
420 
421  // Show the type information (fetched from Kinetica)
422  Console.WriteLine("Fetching the newly created type information...");
423  ShowTypesResponse responseShowTypes = kdb.showTypes(exampleTypeId, "");
424  Console.WriteLine("Type properties:");
425  foreach ( var x in responseShowTypes.properties[0] )
426  Console.WriteLine($"\t{x.Key}: {String.Join(",", x.Value)}");
427  Console.WriteLine();
428 
429  // Clear any previously made table with the same name
430  Console.WriteLine($"Clearing any existing table named '{tableName}'...\n");
431  kdb.clearTable(tableName, "", new Dictionary<string, string> { [ClearTableRequest.Options.NO_ERROR_IF_NOT_EXISTS] = ClearTableRequest.Options.TRUE });
432 
433  // Create a table of the given type
434  Console.WriteLine($"Creating table named '{tableName}'...\n");
435  kdb.createTable( tableName, exampleTypeId );
436 
437  // Call /show/table on the table just created
438  Dictionary<string, string> optionsShowTable = new() { [ShowTableRequest.Options.GET_SIZES] = ShowTableRequest.Options.TRUE };
439  Console.WriteLine($"Calling ShowTable on '{tableName}'...");
440  var responseShowTable = kdb.showTable(tableName, optionsShowTable);
441  Console.WriteLine($"Total size: {responseShowTable.total_size}");
442  Console.WriteLine($"Sizes: {string.Join(", ", responseShowTable.sizes)}\n");
443 
444  // Create some data to be added to the table
445  List<ExampleRecord> newData = [
446  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 },
447  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 },
448  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 }
449  ];
450 
451  // Insert the data into the table
452  Console.WriteLine($"Inserting some data in '{tableName}'...");
453  var responseInsert = kdb.insertRecords( tableName, newData );
454  Console.WriteLine($"Inserted {responseInsert.count_inserted + responseInsert.count_updated} records\n");
455 
456  // Call /show/table on the table after adding data
457  Console.WriteLine($"Calling ShowTable on '{tableName}' after adding data...");
458  responseShowTable = kdb.showTable(tableName, optionsShowTable);
459  Console.WriteLine($"Total size: {responseShowTable.total_size}");
460  Console.WriteLine($"Sizes: {string.Join( ", ", responseShowTable.sizes )}\n");
461 
462  // Fetch the data back out of the DB using /get/records
463  Console.WriteLine($"Getting records from table '{tableName}'...");
464  var responseGetRecords = kdb.getRecords<ExampleRecord>( tableName, 0, 100 );
465  Console.WriteLine($"GetRecords got {responseGetRecords.data.Count} records:");
466  foreach ( var r in responseGetRecords.data )
467  Console.WriteLine($"\t{r}");
468  Console.WriteLine();
469 
470  // Do a filter operation
471  Console.WriteLine($"Filtering data from table '{tableName}'...");
472  string filterName = "csharp_example_filter";
473  string filterExpression = "E > 0";
474  var filterResponse = kdb.filter( tableName, filterName, filterExpression );
475  Console.WriteLine($"Filtered {filterResponse.count} records into '{filterName}'\n");
476 
477  // Do an /aggregate/groupby operation on the data
478  Console.WriteLine($"Performing a group-by aggregate operation on table '{tableName}'...");
479  IList<string> columnNames = ["A", "D"];
480  var responseGroupBy = kdb.aggregateGroupBy( tableName, columnNames, 0, 100 );
481  Console.WriteLine($"Group by got {responseGroupBy.total_number_of_records} records:");
482  // Print the decoded data out to the console
483  ( ( List<KineticaRecord> ) ( responseGroupBy.data ) ).ForEach( r => Console.WriteLine($"\t{r.ContentsToString()}") );
484  Console.WriteLine();
485 
486  // Do an /aggregate/unique operation on column F
487  string columnName = "F";
488  Console.WriteLine($"Performing a unique aggregate operation on column '{tableName}.{columnName}'...");
489  var uniqueResponse = kdb.aggregateUnique( tableName, columnName, 0, 100 );
490  // Print the decoded data out to the console
491  ( ( List<KineticaRecord> ) ( uniqueResponse.data ) ).ForEach( r => Console.WriteLine($"\t{r.ContentsToString()}") );
492  Console.WriteLine();
493 
494  // Fetch the data back out of the DB using /get/records/bycolumn
495  Console.WriteLine($"Getting records out (using /get/records/bycolumn) on table '{tableName}'...");
496  columnNames = ["B", "C", "E"];
497  var responseGetRecordsByColumn = kdb.getRecordsByColumn( tableName, columnNames, 0, 100 );
498  Console.WriteLine($"GetRecordsByColumn got {responseGetRecordsByColumn.data.Count} records:");
499  foreach ( var r in responseGetRecordsByColumn.data )
500  Console.WriteLine($"\t{r.ContentsToString()}");
501  Console.WriteLine("\n");
502  } // end RunExample
503 
504 
505 
515  private static void RunSeriesExample( string serverUrl, Kinetica.Options serverOptions )
516  {
517  Console.WriteLine();
518  Console.WriteLine("Example showcasing a record with a series type column");
519  Console.WriteLine("=====================================================");
520  Console.WriteLine();
521 
522  // Establish a connection with Kinetica
523  Kinetica kdb = new( serverUrl, serverOptions );
524 
525  // Create the series type record in Kinetica
526  KineticaType seriesType = KineticaType.fromClass( typeof( SeriesRecord ) );
527  string seriesTypeId = seriesType.create( kdb );
528  Console.WriteLine($"ID of the created series type: {seriesTypeId}\n");
529 
530  // Clear any previously made table with the same name
531  string tableName = "csharp_example_series_table";
532  Console.WriteLine($"Clearing any existing table named '{tableName}'...\n");
533  kdb.clearTable(tableName, "", new Dictionary<string, string> { [ClearTableRequest.Options.NO_ERROR_IF_NOT_EXISTS] = ClearTableRequest.Options.TRUE });
534 
535  // Create a table of the given type
536  Console.WriteLine($"Creating table named '{tableName}'...\n");
537  kdb.createTable( tableName, seriesTypeId );
538 
539  // Create some data to be added to the table
540  string series1 = "series_1";
541  string series2 = "series_2";
542  List<SeriesRecord> seriesData =
543  [
544  // Five series points moving horizontally
545  new SeriesRecord() { x = 30, y = 40, TRACKID = series1, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
546  new SeriesRecord() { x = 35, y = 40, TRACKID = series1, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
547  new SeriesRecord() { x = 40, y = 40, TRACKID = series1, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
548  new SeriesRecord() { x = 45, y = 40, TRACKID = series1, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
549  new SeriesRecord() { x = 50, y = 40, TRACKID = series1, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
550  // Five series points moving vertically
551  new SeriesRecord() { x = -30, y = -40, TRACKID = series2, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
552  new SeriesRecord() { x = -30, y = -45, TRACKID = series2, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
553  new SeriesRecord() { x = -30, y = -50, TRACKID = series2, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
554  new SeriesRecord() { x = -30, y = -55, TRACKID = series2, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
555  new SeriesRecord() { x = -30, y = -60, TRACKID = series2, TIMESTAMP= (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds },
556  ];
557 
558  // Insert the data into the table
559  Console.WriteLine($"Inserting some data in '{tableName}'...");
560  var responseInsert = kdb.insertRecords(tableName, seriesData);
561  Console.WriteLine($"Inserted {responseInsert.count_inserted + responseInsert.count_updated} records\n");
562 
563 
564  // Fetch the data back out of the DB using /get/records
565  Console.WriteLine($"Getting records from table '{tableName}'...");
566  var responseGetRecords = kdb.getRecords<SeriesRecord>(tableName);
567  Console.WriteLine($"GetRecords got {responseGetRecords.data.Count} records:");
568  foreach (var r in responseGetRecords.data)
569  Console.WriteLine($"\t{r}");
570  Console.WriteLine();
571 
572 
573  // Filter the series data such that only a few series point from only one of the series
574  // are in the view
575  Console.WriteLine($"Filtering data from {tableName} so that only some points from {series1} make it...");
576  string filterName = "csharp_example_series_filter";
577  // Only the first, second, and third records from the first series should survive this filter
578  // (for track/series type records, we're filtering the "line segments", so records just outside the
579  // filtered box will also be captured)
580  var responseFilter = kdb.filterByBox( tableName, filterName, "x", 33, 37, "y", 35, 45 );
581  Console.WriteLine($"Filtered {responseFilter.count} records into '{filterName}'\n");
582 
583  // Show the filtered objects
584  responseGetRecords = kdb.getRecords<SeriesRecord>( filterName );
585  Console.WriteLine($"GetRecords got {responseGetRecords.data.Count} records from '{filterName}':");
586  foreach ( var r in responseGetRecords.data )
587  Console.WriteLine($"\t{r}");
588  Console.WriteLine();
589 
590 
591  // Extract the entire series from the source table (based on which ones are in the view)
592  Console.WriteLine($"Getting records belonging to one series out from table '{tableName}' using the partial series in filter '{filterName}'...");
593  var getRecordsBySeriesResp = kdb.getRecordsBySeries<SeriesRecord>( filterName, tableName );
594  Console.WriteLine($"GetRecordsBySeries got {getRecordsBySeriesResp.data.Count} list of records (should get one list of five records in it):");
595  foreach ( var rSeries in getRecordsBySeriesResp.data )
596  foreach ( var r in rSeries ) Console.WriteLine($"\t{r}");
597  Console.WriteLine("\n");
598  } // end RunSeriesExample()
599 
600 
609  private static void RunMultiheadIngestExample( string serverUrl, Kinetica.Options serverOptions )
610  {
611  Console.WriteLine();
612  Console.WriteLine("Example showcasing multihead ingestion(one shard key, two primary keys)");
613  Console.WriteLine("=======================================================================");
614  Console.WriteLine();
615 
616  // Establish a connection with Kinetica
617  Kinetica kdb = new( serverUrl, serverOptions );
618 
619  // Create a type for our exampleRecord class
620  // Add some interesting properties for some of the data types
621  Dictionary<string, IList<string>> columnProperties = new()
622  {
623  // Add a primary key
624  { "A", [ColumnProperty.PRIMARY_KEY] },
625 
626  // And a shard key (must be part of the primary keys, if specified--which we have)
628  };
629 
630  // Create the KineticaType object which facilitates creating types in the database
631  KineticaType exampleType = KineticaType.fromClass( typeof( ExampleRecord ), columnProperties );
632 
633  // Create the type in the database
634  string exampleTypeId = exampleType.create( kdb );
635 
636  // Clear any previously made table with the same name
637  string tableName = "csharp_example_multihead_table";
638  Console.WriteLine($"Clearing any existing table named '{tableName}'...\n");
639  kdb.clearTable(tableName, "", new Dictionary<string, string> { [ClearTableRequest.Options.NO_ERROR_IF_NOT_EXISTS] = ClearTableRequest.Options.TRUE });
640 
641  // Create a table of the given type
642  Console.WriteLine($"Creating table named '{tableName}'...\n");
643  kdb.createTable( tableName, exampleTypeId );
644 
645  // Create the ingestor (we're not giving any worker IP addresses; the ingestor class will figure it
646  // out by itself)
647  int batchSize = 100;
648  KineticaIngestor<ExampleRecord> ingestor = new( kdb, tableName, batchSize, exampleType );
649 
650  // Generate data to be inserted
651  int totalRecords = batchSize * 5;
652  List<ExampleRecord> records = [];
653  Random rng = new();
654  double nullProbability = 0.2;
655  for ( int i = 0; i < totalRecords; ++i )
656  {
657  // Restricting string length to 256
658  int maxStringLength = rng.Next( 0, 256 );
659  ExampleRecord record = new ()
660  {
661  A = rng.Next(),
662  B = rng.Next(),
663  C = System.IO.Path.GetRandomFileName().Truncate( maxStringLength ),
664  D = System.IO.Path.GetRandomFileName().Truncate( maxStringLength ),
665  E = (1.0F / rng.Next()),
666  F = ( rng.NextDouble() < nullProbability ) ? null : ( double? ) ( rng.NextDouble() * (1.0F / rng.Next()) ),
667  TIMESTAMP = (long)rng.Next( -306102240, 293795424 ) * rng.Next( 100000 )
668  };
669 
670  records.Add( record );
671  } // end for loop
672 
673  Console.WriteLine( $"Generated {totalRecords} records.\n" );
674 
675  // Insert the records into the ingestor
676  Console.WriteLine( $"Inserting {totalRecords} records..." );
677  ingestor.insert( records );
678 
679  // Flush the ingestor (which actually inserts the records)
680  Console.WriteLine( "Flushing any remaining records..." );
681  ingestor.flush();
682 
683  // Call /show/table on the table after adding data
684  Console.WriteLine($"Calling ShowTable on '{tableName}' after adding data...");
685  var responseShowTable = kdb.showTable(tableName, new Dictionary<string,string> { [ShowTableRequest.Options.GET_SIZES] = ShowTableRequest.Options.TRUE });
686  Console.WriteLine($"Total size: {responseShowTable.total_size}");
687 
688  Console.WriteLine("\n");
689  } // end run_multihead_ingest_example()
690 
691 
692  private class ExampleRecord
693  {
694  public int A { get; set; }
695  public int B { get; set; }
696  public string? C { get; set; }
697  public string? D { get; set; }
698  public float E { get; set; }
699  public double? F { get; set; }
700  public long TIMESTAMP { get; set; }
701 
702  public override string ToString()
703  {
704  string f;
705  if ( F != null )
706  f = $"{F}";
707  else
708  f = "<null>";
709  return $"{{ A={A}, B={B}, C={C}, D={D}, E={E}, F={f}, TIMESTAMP={TIMESTAMP} }}";
710  }
711  } // end class exampleRecord
712 
713 
714  private class SeriesRecord
715  {
716  public double x { get; set; }
717  public double y { get; set; }
718  public string? TRACKID { get; set; }
719  public long TIMESTAMP { get; set; }
720 
721  public override string ToString()
722  {
723  return $"{{ x={x}, y={y}, TRACKID={TRACKID}, TIMESTAMP={TIMESTAMP} }}";
724  }
725  } // end class record_type_series
726  }
727 }
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:112
CreateTableResponse createTable(CreateTableRequest request_)
Creates a new table.
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.
A set of string constants for the parameter options.
Definition: ClearTable.cs:24
Connection Options
Definition: Kinetica.cs:50
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
Extension to string that has a truncate function.
Definition: Example.cs:12
ShowTypesResponse showTypes(ShowTypesRequest request_)
Retrieves information for the specified data type ID or type label.
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
const string NULLABLE
This property indicates that this column is nullable.
A set of results returned by Kinetica.showTypes.
Definition: ShowTypes.cs:126
API to talk to Kinetica Database
Definition: Kinetica.cs:40
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.