3 using System.Data.Common;
5 using NetTopologySuite.Geometries;
14 public static string Truncate(
this string value,
int maxLength )
16 if (
string.IsNullOrEmpty( value ) )
19 return ( value.Length <= maxLength ) ? value : value[..maxLength];
26 static void Main(
string[] args)
28 Console.WriteLine(
"================================");
29 Console.WriteLine(
"= Example C# Project - Running =");
30 Console.WriteLine(
"================================");
35 Console.WriteLine(
"Missing URL as command-line parameter; e.g.: http://localhost:9191");
41 string serverUrl = args[0];
42 Console.WriteLine($
"URL: {serverUrl}\n");
50 string JdbcDriverPath =
"";
51 if( args.Length > 3) {
52 JdbcDriverPath = args[3];
56 JdbcExample(JdbcDriverPath, serverUrl, _ServerOptions.Username, _ServerOptions.Password);
57 RunExample( serverUrl, _ServerOptions );
58 RunSeriesExample( serverUrl, _ServerOptions );
59 RunMultiheadIngestExample( serverUrl, _ServerOptions );
63 Console.WriteLine($
"Caught Exception: {ex} {ex.Message} {ex.StackTrace}\n");
67 Console.WriteLine(
"=============================");
68 Console.WriteLine(
"= Example C# Project - Done =");
69 Console.WriteLine(
"=============================");
73 private const int columnWidth = 23;
74 private const int displayLimit = 50;
77 #region Console Method 78 private static string AlignCenter(
string text,
int width)
80 text = text.Length > width ?
string.Concat(text.AsSpan(0, width - 3),
"...") : text;
82 return !
string.IsNullOrEmpty(text)
83 ? text.PadRight(width - (width - text.Length) / 2).PadLeft(width)
84 :
new string(
' ', width);
87 private static void PrintRow(
string[] columns,
bool header =
false)
92 foreach (var column
in columns)
94 row += AlignCenter(column, columnWidth) +
"|";
95 line +=
new string(
'-', columnWidth) +
"+";
100 Console.WriteLine(line);
101 Console.WriteLine(row);
102 Console.WriteLine(line.Replace(
'-',
'='));
106 Console.WriteLine(row);
107 Console.WriteLine(line);
112 private static void PrintResult(DbDataReader reader)
114 var columns =
new List<string>();
116 for (var i = 0; i < reader.FieldCount; i++)
118 columns.Add(reader.GetName(i));
121 PrintRow([.. columns],
true);
123 while (reader.Read())
125 var items =
new List<string>();
127 for (var i = 0; i < reader.FieldCount; i++)
129 items.Add(reader.GetString(i));
132 PrintRow([.. items]);
138 private static string GenerateRandomId()
140 Random random =
new();
141 int randomNumber = random.Next(1000, 9999);
142 return $
"ID_{randomNumber}";
145 private static string GenerateRandomUrl()
147 string[] domains = [
"com",
"net",
"org",
"io",
"dev"];
148 string chars =
"abcdefghijklmnopqrstuvwxyz0123456789";
149 Random random =
new();
151 string randomSubdomain =
new(
152 [..
new char[8].Select(_ => chars[random.Next(chars.Length)])]);
154 string randomDomain =
new(
155 [..
new char[5].Select(_ => chars[random.Next(chars.Length)])]);
157 string randomPath =
new(
158 [..
new char[6].Select(_ => chars[random.Next(chars.Length)])]);
160 string domainExtension = domains[random.Next(domains.Length)];
162 return $
"https://{randomSubdomain}.{randomDomain}.{domainExtension}/{randomPath}";
165 private static string GenerateRandomName()
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"];
170 Random random =
new();
171 string firstName = firstNames[random.Next(firstNames.Length)];
172 string lastName = lastNames[random.Next(lastNames.Length)];
174 return $
"{firstName} {lastName}";
177 private static string GenerateGeometry() {
178 GeometryFactory factory =
new();
181 Polygon polygon = factory.CreatePolygon(
183 new Coordinate(0, 0),
184 new Coordinate(10, 0),
185 new Coordinate(10, 10),
186 new Coordinate(0, 10),
189 return polygon.AsText();
193 private static string GenerateRandomPolygon()
195 GeometryFactory factory =
new();
199 int numVertices = rand.Next(3, 11);
202 double minX = rand.NextDouble() * 50;
203 double maxX = minX + rand.NextDouble() * 50;
204 double minY = rand.NextDouble() * 50;
205 double maxY = minY + rand.NextDouble() * 50;
207 Coordinate[] coordinates =
new Coordinate[numVertices + 1];
209 for (
int i = 0; i < numVertices; i++)
211 double x = rand.NextDouble() * (maxX - minX) + minX;
212 double y = rand.NextDouble() * (maxY - minY) + minY;
213 coordinates[i] =
new Coordinate(x, y);
217 coordinates[numVertices] = coordinates[0];
220 LinearRing ring = factory.CreateLinearRing(coordinates);
221 Polygon polygon = factory.CreatePolygon(ring);
223 return polygon.AsText();
226 private static DateTime GenerateRandomDate(DateTime start, DateTime end)
228 Random random =
new();
229 int range = (int)(end - start).TotalSeconds;
230 return start.AddSeconds(random.Next(range));
243 private static void JdbcExample(
string driverPath,
string serverUrl,
string username,
string password)
246 Console.WriteLine(
"Example Using a JDBC Bridge Library and the Kinetica JDBC Driver");
247 Console.WriteLine(
"================================================================");
250 if ( driverPath.Length == 0)
252 Console.WriteLine(
"No Kinetica JDBC driver given; e.g.: kinetica-jdbc-7.2.2.8-jar-with-dependencies.jar\n");
256 var builder =
new JdbcConnectionStringBuilder
258 DriverPath = driverPath,
259 DriverClass =
"com.kinetica.jdbc.Driver",
260 JdbcUrl = $
"jdbc:kinetica:URL={serverUrl};UID={username};PWD={password}" 263 using var connection =
new JdbcConnection(builder);
264 Console.WriteLine(
"Establishing connection...");
266 Console.WriteLine(
"Connection established!\n");
268 using JdbcCommand command = connection.CreateCommand();
270 Console.WriteLine(
"Creating table...");
273 string ddl =
@"CREATE OR REPLACE TABLE csharp_example_jdbc 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) 285 command.CommandText = ddl;
287 command.ExecuteNonQuery();
291 Console.WriteLine($
"Error creating table: {e}\n");
295 Console.WriteLine(
"Inserting data...");
298 command.CommandText =
"INSERT INTO csharp_example_jdbc VALUES (@ObjectId, @Name, @Url, @BoundingBox, @CreatedAt, @UpdatedAt)";
299 command.Parameters.Clear();
301 int rowsInserted = 0;
302 for (
int i = 0; i < 10; i++)
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"));
311 int rowsAffected = command.ExecuteNonQuery();
312 command.Parameters.Clear();
313 rowsInserted += rowsAffected + 1;
315 Console.WriteLine($
"Rows inserted: {rowsInserted}\n");
317 catch (System.Data.Common.DbException ex)
319 Console.WriteLine($
"Error inserting data: {ex}\n");
323 Console.WriteLine(
"Executing query...");
326 command.CommandText =
"SELECT * FROM csharp_example_jdbc ORDER BY object_id";
327 command.Parameters.Clear();
329 using var reader = command.ExecuteReader();
333 catch (System.Data.Common.DbException ex)
335 Console.WriteLine($
"Error executing query: {ex}\n");
339 Console.WriteLine(
"Updating data...");
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");
346 catch (System.Data.Common.DbException ex)
348 Console.WriteLine($
"Error updating data: {ex}\n");
352 Console.WriteLine(
"Deleting data...");
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");
359 catch (System.Data.Common.DbException ex)
361 Console.WriteLine($
"Error updating data: {ex}\n");
364 Console.WriteLine(
"Checking data after modifications...");
367 command.CommandText =
"SELECT * FROM csharp_example_jdbc ORDER BY object_id";
368 command.Parameters.Clear();
370 using var reader = command.ExecuteReader();
374 catch (System.Data.Common.DbException ex)
376 Console.WriteLine($
"Error checking data: {ex}\n");
390 private static void RunExample(
string serverUrl,
Kinetica.
Options serverOptions)
393 Console.WriteLine(
"Example with a Record Type with Nullable Columns, Primary Keys and Shard Keys");
394 Console.WriteLine(
"=============================================================================");
398 Kinetica kdb =
new(serverUrl, serverOptions);
400 string tableName =
"csharp_example_table";
403 Console.WriteLine(
"Creating the type in kinetica...");
405 Dictionary<string, IList<string>> columnProperties =
new()
418 string exampleTypeId = exampleType.
create(kdb);
419 Console.WriteLine($
"ID of the created type: {exampleTypeId}\n");
422 Console.WriteLine(
"Fetching the newly created type information...");
424 Console.WriteLine(
"Type properties:");
425 foreach ( var x
in responseShowTypes.properties[0] )
426 Console.WriteLine($
"\t{x.Key}: {String.Join(",
", x.Value)}");
430 Console.WriteLine($
"Clearing any existing table named '{tableName}'...\n");
434 Console.WriteLine($
"Creating table named '{tableName}'...\n");
435 kdb.createTable( tableName, exampleTypeId );
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");
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 }
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");
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");
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}");
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");
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:");
483 ( ( List<KineticaRecord> ) ( responseGroupBy.data ) ).ForEach( r => Console.WriteLine($
"\t{r.ContentsToString()}") );
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 );
491 ( ( List<KineticaRecord> ) ( uniqueResponse.data ) ).ForEach( r => Console.WriteLine($
"\t{r.ContentsToString()}") );
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");
515 private static void RunSeriesExample(
string serverUrl,
Kinetica.
Options serverOptions )
518 Console.WriteLine(
"Example showcasing a record with a series type column");
519 Console.WriteLine(
"=====================================================");
523 Kinetica kdb =
new( serverUrl, serverOptions );
527 string seriesTypeId = seriesType.
create( kdb );
528 Console.WriteLine($
"ID of the created series type: {seriesTypeId}\n");
531 string tableName =
"csharp_example_series_table";
532 Console.WriteLine($
"Clearing any existing table named '{tableName}'...\n");
536 Console.WriteLine($
"Creating table named '{tableName}'...\n");
540 string series1 =
"series_1";
541 string series2 =
"series_2";
542 List<SeriesRecord> seriesData =
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 },
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 },
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");
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}");
575 Console.WriteLine($
"Filtering data from {tableName} so that only some points from {series1} make it...");
576 string filterName =
"csharp_example_series_filter";
580 var responseFilter = kdb.
filterByBox( tableName, filterName,
"x", 33, 37,
"y", 35, 45 );
581 Console.WriteLine($
"Filtered {responseFilter.count} records into '{filterName}'\n");
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}");
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");
609 private static void RunMultiheadIngestExample(
string serverUrl,
Kinetica.
Options serverOptions )
612 Console.WriteLine(
"Example showcasing multihead ingestion(one shard key, two primary keys)");
613 Console.WriteLine(
"=======================================================================");
617 Kinetica kdb =
new( serverUrl, serverOptions );
621 Dictionary<string, IList<string>> columnProperties =
new()
634 string exampleTypeId = exampleType.
create( kdb );
637 string tableName =
"csharp_example_multihead_table";
638 Console.WriteLine($
"Clearing any existing table named '{tableName}'...\n");
642 Console.WriteLine($
"Creating table named '{tableName}'...\n");
651 int totalRecords = batchSize * 5;
652 List<ExampleRecord> records = [];
654 double nullProbability = 0.2;
655 for (
int i = 0; i < totalRecords; ++i )
658 int maxStringLength = rng.Next( 0, 256 );
659 ExampleRecord record =
new ()
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 )
670 records.Add( record );
673 Console.WriteLine( $
"Generated {totalRecords} records.\n" );
676 Console.WriteLine( $
"Inserting {totalRecords} records..." );
677 ingestor.
insert( records );
680 Console.WriteLine(
"Flushing any remaining records..." );
684 Console.WriteLine($
"Calling ShowTable on '{tableName}' after adding data...");
686 Console.WriteLine($
"Total size: {responseShowTable.total_size}");
688 Console.WriteLine(
"\n");
692 private class ExampleRecord
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; }
702 public override string ToString()
709 return $
"{{ A={A}, B={B}, C={C}, D={D}, E={E}, F={f}, TIMESTAMP={TIMESTAMP} }}";
714 private class SeriesRecord
716 public double x {
get;
set; }
717 public double y {
get;
set; }
718 public string? TRACKID {
get;
set; }
719 public long TIMESTAMP {
get;
set; }
721 public override string ToString()
723 return $
"{{ x={x}, y={y}, TRACKID={TRACKID}, TIMESTAMP={TIMESTAMP} }}";
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...
CreateTableResponse createTable(CreateTableRequest request_)
Creates a new table.
A set of parameters for Kinetica.clearTable.
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.
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.
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.
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)
Extension to string that has a truncate function.
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.
const string NULLABLE
This property indicates that this column is nullable.
A set of results returned by Kinetica.showTypes.
API to talk to Kinetica Database
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.