3 using System.Data.Common;
5 using NetTopologySuite.Geometries;
12 public static class StringExt
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");
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} }}";
const string SHARD_KEY
This property indicates that this column will be part of (or the entire) shard key.
CreateTableResponse createTable(CreateTableRequest request_)
Creates a new table with the given type (definition of columns).
A set of parameters for Kinetica.clearTable.
Column properties used for Kinetica types.
AggregateGroupByResponse aggregateGroupBy(AggregateGroupByRequest request_)
Calculates unique combinations (groups) of values for the given columns in a given table or view and ...
IList< IDictionary< string, IList< string > > > properties
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 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.
const string TIMESTAMP
Valid only for 'long' columns.
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)
FilterResponse filter(FilterRequest request_)
Filters data based on the specified expression.
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.
const string CHAR4
This property provides optimized memory, disk and query performance for string columns.
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.
A set of results returned by Kinetica.showTypes.
const string PRIMARY_KEY
This property indicates that this column will be part of (or the entire) primary key.
API to talk to Kinetica Database
const string GET_SIZES
If TRUE then the number of records in each table, along with a cumulative count, will be returned; bl...
Manages the insertion into GPUdb of large numbers of records in bulk, with automatic batch management...