Kinetica C# API  Version 6.1.0.0
Test.cs
Go to the documentation of this file.
1 
7 using System;
8 using System.Collections.Generic;
9 using System.Linq;
10 using System.Text.RegularExpressions;
11 
12 using kinetica;
13 
14 namespace Test
15 {
19  public static class StringExt
20  {
21  public static string Truncate( this string value, int maxLength )
22  {
23  if ( string.IsNullOrEmpty( value ) )
24  return value;
25 
26  return ( value.Length <= maxLength ) ? value : value.Substring( 0, maxLength );
27  }
28  }
29 
30 
36  class Test
37  {
38  static void Main( string[] args )
39  {
40  Console.WriteLine( "Testing C# Project - Running" );
41  Console.WriteLine();
42 
43  if ( args.Length < 1 )
44  {
45  Console.WriteLine( "Missing URL as command-line parameter." );
46  Console.WriteLine( "E.g., http://kinetica:9191" );
47  return;
48  }
49 
50  try
51  {
52  string server_url = args[0];
53  Console.WriteLine( "URL: {0}", server_url );
54  Console.WriteLine();
55 
56  // Run various multihead ingest tests
57  // ----------------------------------
58  test_authentication( server_url );
59  test_all_types_allshard( server_url );
60  test_all_types_3pk_3shard( server_url );
61  test_all_types_ip_regex_3shard_0pk( server_url );
62  test_all_types_3pk_0shard( server_url );
63  }
64  catch ( kinetica.KineticaIngestor<record_type_all>.InsertException<record_type_all> ex )
65  {
66  Console.WriteLine( "Caught InsertException: {0}", ex.Message );
67  }
68  catch ( KineticaException ex )
69  {
70  Console.WriteLine( "Caught KineticaException: {0}", ex.Message );
71  }
72  catch ( Exception ex )
73  {
74  Console.WriteLine( "Caught Exception: {0}", ex.Message );
75  }
76 
77  // We're done
78  Console.WriteLine();
79  Console.WriteLine( "Testing C# Project - Done" );
80  Console.WriteLine();
81  Console.WriteLine( "Enter any 7-digit prime number to continue: " );
82  Console.ReadLine();
83  } // end Main
84 
85 
86  private class record_type_short
87  {
88  public int i { get; set; }
89  public int i8 { get; set; }
90 
91  public override string ToString()
92  {
93  return $"{{ i={i}, i8={i8} }}";
94  }
95  } // end class record_type_short
96 
97 
98  private static void test_authentication( string server_url )
99  {
100  Console.WriteLine( "\n\n" );
101  Console.WriteLine( "Test Authentication" );
102  Console.WriteLine( "===================" );
103  Console.WriteLine();
104 
105  Console.WriteLine( "This test is done dynamically:" );
106  Console.WriteLine( "------------------------------" );
107  Console.WriteLine( "* First run--create the user with the 'correct' username" );
108  Console.WriteLine( "* Second run--comment out user creation; run with 'correct'" );
109  Console.WriteLine( " username and make sure that the endpoints go through" );
110  Console.WriteLine( "* Third run--comment out user creation; run with 'wrong'" );
111  Console.WriteLine( " username and make sure that we get an 'insufficient credentials'" );
112  Console.WriteLine( " error thrown from the server." );
113  Console.WriteLine();
114 
115  string username = "abcdef"; // correct
116  //string username = "abcdefg"; // wrong
117  string password = "ghijkl123_";
118 
119  // Establish a connection with Kinetica
120  // Create a user
121  Kinetica kdb_ = new Kinetica( server_url );
122  Console.WriteLine( $"Creating a user {username}" );
123  Console.WriteLine();
124  IDictionary <string, string> options = new Dictionary<string, string>();
125  try
126  {
127  kdb_.createUserInternal( username, password, options );
128  }
129  catch ( KineticaException ex )
130  {
131  Console.WriteLine( "Caught exception: " + ex.Message );
132  }
133 
134  // Establish another connection with Kinetica with authentication information
135  Console.WriteLine( "Creating a DB handle with the proper username and password" );
136  Kinetica.Options db_options = new Kinetica.Options();
137  db_options.Username = username;
138  db_options.Password = password;
139  Kinetica kdb = new Kinetica( server_url, db_options );
140 
141  // Create the KineticaType object which facilitates creating types in the database
142  KineticaType type1 = KineticaType.fromClass( typeof( record_type_short ) );
143 
144  // Create the type in the database
145  string type_id = type1.create( kdb );
146 
147  string table_name = "csharp_example_table_01_auth";
148  // Clear any previously made table with the same name
149  Console.WriteLine( "Clearing any existing table named '{0}'", table_name );
150  try { kdb.clearTable( table_name, null ); } catch ( Exception ex ) { /* I don't care if the table doesn't already exists! */ }
151  Console.WriteLine();
152 
153  // Create a table of the given type
154  Console.WriteLine( $"Creating table named '{table_name}'" );
155  kdb.createTable( table_name, type_id );
156  Console.WriteLine();
157 
158 
159  int num_records = 5000;
160  kdb.insertRecordsRandom( table_name, num_records );
161  Console.WriteLine( $"Generated {num_records} records." );
162  } // end test_authentication()
163 
164 
165  private class record_type_all
166  {
167  public int? i { get; set; }
168  public int? i8 { get; set; }
169  public int? i16 { get; set; }
170  public long l { get; set; } // not making nullable here so that can be used as a primary key
171  public float? f { get; set; }
172  public double? d { get; set; } // nullable
173  public string s { get; set; }
174  public string c1 { get; set; }
175  public string c2 { get; set; }
176  public string c4 { get; set; }
177  public string c8 { get; set; }
178  public string c16 { get; set; }
179  public string c32 { get; set; }
180  public string c64 { get; set; }
181  public string c128 { get; set; }
182  public string c256 { get; set; }
183  public string date { get; set; }
184  public string datetime { get; set; }
185  public string decimal_ { get; set; }
186  public string ipv4 { get; set; }
187  public string time { get; set; }
188  public long? timestamp { get; set; }
189 
190  public override string ToString()
191  {
192  string d_;
193  if ( d != null )
194  d_ = $"{d}";
195  else
196  d_ = "<null>";
197  return $"{{ i={i}, i8={i8}, i16={i16}, l={l}, f={f}, d={d_}, s={s}, c1={c1}, c2={c2}, c4={c4}, c8={c8}, c16={c16}, c32={c32}, c64={c64}, c128={c128}, c256={c256}, date={date}, datetime={datetime}, decimal_={decimal_}, ipv4={ipv4}, time={time}, timestamp={timestamp} }}";
198  }
199  } // end class record_type_all
200 
201 
202  private static void test_all_types_allshard( string server_url )
203  {
204  // Establish a connection with Kinetica
205  Kinetica kdb = new Kinetica( server_url );
206 
207  Console.WriteLine( "\n\n" );
208  Console.WriteLine( "Test Multihead Ingest: One column per Type; All are Shard Keys, 0 Primary Keys" );
209  Console.WriteLine( "==============================================================================" );
210  Console.WriteLine();
211 
212  Console.WriteLine( "Creating a type with all column types (all are nullable and shard columns).\n" );
213 
214  // Create a type for our record_type_1 class
215  // Add some interesting properties for some of the data types
216  IDictionary<string, IList<string>> column_properties = new Dictionary<string, IList<string>>();
217 
218  // Integer shard key
219  List<string> i_props = new List<string>();
220  i_props.Add( ColumnProperty.SHARD_KEY );
221  column_properties.Add( "i", i_props );
222 
223  // Integer8 shard key
224  List<string> i8_props = new List<string>();
225  i8_props.Add( ColumnProperty.SHARD_KEY );
226  i8_props.Add( ColumnProperty.INT8 );
227  column_properties.Add( "i8", i8_props );
228  // Integer16 shard key
229  List<string> i16_props = new List<string>();
230  i16_props.Add( ColumnProperty.SHARD_KEY );
231  i16_props.Add( ColumnProperty.INT16 );
232  column_properties.Add( "i16", i16_props );
233 
234  // Double shard key
235  List<string> d_props = new List<string>();
236  d_props.Add( ColumnProperty.SHARD_KEY );
237  column_properties.Add( "d", d_props );
238 
239  // Float shard key
240  List<string> f_props = new List<string>();
241  f_props.Add( ColumnProperty.SHARD_KEY );
242  column_properties.Add( "f", f_props );
243 
244  // Long shard key
245  List<string> l_props = new List<string>();
246  l_props.Add( ColumnProperty.SHARD_KEY );
247  l_props.Add( ColumnProperty.NULLABLE );
248  column_properties.Add( "l", l_props );
249 
250  // string nullable shard key
251  List<string> s_props = new List<string>();
252  s_props.Add( ColumnProperty.SHARD_KEY );
253  s_props.Add( ColumnProperty.NULLABLE );
254  column_properties.Add( "s", s_props );
255 
256  // char1 shard key, nullable
257  List<string> c1_props = new List<string>();
258  c1_props.Add( ColumnProperty.SHARD_KEY );
259  c1_props.Add( ColumnProperty.NULLABLE );
260  c1_props.Add( ColumnProperty.CHAR1 );
261  column_properties.Add( "c1", c1_props );
262 
263  // char2 shard key, nullable
264  List<string> c2_props = new List<string>();
265  c2_props.Add( ColumnProperty.SHARD_KEY );
266  c2_props.Add( ColumnProperty.NULLABLE );
267  c2_props.Add( ColumnProperty.CHAR2 );
268  column_properties.Add( "c2", c2_props );
269 
270  // char4 shard key, nullable
271  List<string> c4_props = new List<string>();
272  c4_props.Add( ColumnProperty.SHARD_KEY );
273  c4_props.Add( ColumnProperty.NULLABLE );
274  c4_props.Add( ColumnProperty.CHAR4 );
275  column_properties.Add( "c4", c4_props );
276 
277  // char8 shard key, nullable
278  List<string> c8_props = new List<string>();
279  c8_props.Add( ColumnProperty.SHARD_KEY );
280  c8_props.Add( ColumnProperty.NULLABLE );
281  c8_props.Add( ColumnProperty.CHAR8 );
282  column_properties.Add( "c8", c8_props );
283 
284  // char16 shard key, nullable
285  List<string> c16_props = new List<string>();
286  c16_props.Add( ColumnProperty.SHARD_KEY );
287  c16_props.Add( ColumnProperty.NULLABLE );
288  c16_props.Add( ColumnProperty.CHAR16 );
289  column_properties.Add( "c16", c16_props );
290 
291  // char32 shard key, nullable
292  List<string> c32_props = new List<string>();
293  c32_props.Add( ColumnProperty.SHARD_KEY );
294  c32_props.Add( ColumnProperty.NULLABLE );
295  c32_props.Add( ColumnProperty.CHAR32 );
296  column_properties.Add( "c32", c32_props );
297 
298  // char64 shard key, nullable
299  List<string> c64_props = new List<string>();
300  c64_props.Add( ColumnProperty.SHARD_KEY );
301  c64_props.Add( ColumnProperty.NULLABLE );
302  c64_props.Add( ColumnProperty.CHAR64 );
303  column_properties.Add( "c64", c64_props );
304 
305  // char128 shard key, nullable
306  List<string> c128_props = new List<string>();
307  c128_props.Add( ColumnProperty.SHARD_KEY );
308  c128_props.Add( ColumnProperty.NULLABLE );
309  c128_props.Add( ColumnProperty.CHAR128 );
310  column_properties.Add( "c128", c128_props );
311 
312  // char256 shard key, nullable
313  List<string> c256_props = new List<string>();
314  c256_props.Add( ColumnProperty.SHARD_KEY );
315  c256_props.Add( ColumnProperty.NULLABLE );
316  c256_props.Add( ColumnProperty.CHAR256 );
317  column_properties.Add( "c256", c256_props );
318 
319  // date shard key, nullable
320  List<string> date_props = new List<string>();
321  date_props.Add( ColumnProperty.DATE );
322  date_props.Add( ColumnProperty.SHARD_KEY );
323  date_props.Add( ColumnProperty.NULLABLE );
324  column_properties.Add( "date", date_props );
325 
326  // datetime shard key, nullable
327  List<string> datetime_props = new List<string>();
328  datetime_props.Add( ColumnProperty.DATETIME );
329  datetime_props.Add( ColumnProperty.SHARD_KEY );
330  datetime_props.Add( ColumnProperty.NULLABLE );
331  column_properties.Add( "datetime", datetime_props );
332 
333  // decimal shard key, nullable
334  List<string> decimal_props = new List<string>();
335  decimal_props.Add(ColumnProperty.DECIMAL);
336  decimal_props.Add(ColumnProperty.SHARD_KEY);
337  decimal_props.Add( ColumnProperty.NULLABLE );
338  column_properties.Add( "decimal_", decimal_props );
339 
340  // IPv4 shard key, nullable
341  List<string> ipv4_props = new List<string>();
342  ipv4_props.Add( ColumnProperty.IPV4 );
343  ipv4_props.Add( ColumnProperty.SHARD_KEY );
344  ipv4_props.Add( ColumnProperty.NULLABLE );
345  column_properties.Add( "ipv4", ipv4_props );
346 
347  // time shard key, nullable
348  List<string> time_props = new List<string>();
349  time_props.Add( ColumnProperty.TIME );
350  time_props.Add( ColumnProperty.SHARD_KEY );
351  time_props.Add( ColumnProperty.NULLABLE );
352  column_properties.Add( "time", time_props );
353 
354  // timestamp shard key, already nullable
355  List<string> timestamp_props = new List<string>();
356  timestamp_props.Add( ColumnProperty.TIMESTAMP );
357  timestamp_props.Add( ColumnProperty.SHARD_KEY );
358  column_properties.Add( "timestamp", timestamp_props );
359 
360  // Create the KineticaType object which facilitates creating types in the database
361  KineticaType type1 = KineticaType.fromClass( typeof( record_type_all ), column_properties );
362 
363  // Create the type in the database
364  string type_id = type1.create( kdb );
365  //Console.WriteLine( "ID of the created type: " + type_id );
366  //Console.WriteLine();
367  Console.WriteLine( "Created type.\n" );
368 
369  string table_name = "csharp_example_table_all_shards";
370  // Clear any previously made table with the same name
371  Console.WriteLine( "Clearing any existing table named '{0}'\n", table_name );
372  try { kdb.clearTable( table_name, null ); } catch ( Exception ex ) { /* I don't care if the table doesn't already exists! */ }
373  Console.WriteLine();
374 
375  // Create a table of the given type
376  Console.WriteLine( $"Creating table named '{table_name}'\n" );
377  kdb.createTable( table_name, type_id );
378  Console.WriteLine();
379 
380  // Create the ingestor
381  int batch_size = 1000;
382  KineticaIngestor<record_type_all> ingestor = new KineticaIngestor<record_type_all>( kdb, table_name, batch_size, type1 );
383 
384 
385  // Generate data to be inserted
386  int num_records = batch_size * 100;
387  Console.WriteLine( $"Starting to generate {num_records} records.\n" );
388  List<record_type_all> records = new List<record_type_all>();
389  Random rng = new Random();
390  double null_probability = 0.15; // 15% chance of creating nulls
391  for ( int i = 0; i < num_records; ++i )
392  {
393  // Restricting string length to 256
394  int max_str_len = rng.Next( 0, 256 );
395  record_type_all record = new record_type_all()
396  {
397  i = ( rng.NextDouble() < null_probability ) ? null : (int?) rng.Next(),
398  i8 = ( rng.NextDouble() < null_probability ) ? null : (int?) rng.Next( -128, 128 ), // upper exclusive
399  i16 = ( rng.NextDouble() < null_probability ) ? null : (int?) rng.Next( -32768, 32768), // upper exclusive
400  l = (long)rng.Next(),
401  //l = ( rng.NextDouble() < null_probability ) ? null : (long)rng.Next(), // can't be made nullable if not declared as long?
402  f = ( rng.NextDouble() < null_probability ) ? null : (float?)(rng.NextDouble() * rng.Next()),
403  d = ( rng.NextDouble() < null_probability ) ? null : ( double? ) ( rng.NextDouble() * rng.Next() ),
404  s = ( rng.NextDouble() < null_probability ) ? null : System.IO.Path.GetRandomFileName().Truncate( max_str_len ),
405  c1 = ( rng.NextDouble() < null_probability ) ? null : System.IO.Path.GetRandomFileName().Truncate( 1 ),
406  c2 = ( rng.NextDouble() < null_probability ) ? null : System.IO.Path.GetRandomFileName().Truncate( 2 ),
407  c4 = ( rng.NextDouble() < null_probability ) ? null : System.IO.Path.GetRandomFileName().Truncate( rng.Next( 0, 5) ), // any size between empty string to 4 length
408  c8 = ( rng.NextDouble() < null_probability ) ? null : System.IO.Path.GetRandomFileName().Truncate( rng.Next( 0, 9) ), // any size between empty string to 8 length
409  c16 = ( rng.NextDouble() < null_probability ) ? null : System.IO.Path.GetRandomFileName().Truncate( rng.Next( 0, 17) ), // any size between empty string to 16 length
410  c32 = ( rng.NextDouble() < null_probability ) ? null : System.IO.Path.GetRandomFileName().Truncate( rng.Next( 5, 33) ), // any size between [5, 32] in length
411  c64 = ( rng.NextDouble() < null_probability ) ? null : System.IO.Path.GetRandomFileName().Truncate( rng.Next( 10, 65) ), // any size between [10, 64] in length
412  c128 = ( rng.NextDouble() < null_probability ) ? null : System.IO.Path.GetRandomFileName().Truncate( rng.Next( 10, 129) ), // any size between [10, 128] in length
413  c256 = ( rng.NextDouble() < null_probability ) ? null : System.IO.Path.GetRandomFileName().Truncate( rng.Next( 25, 257) ), // any size between [25, 256] in length
414  date = ( rng.NextDouble() < null_probability ) ? null : Test.generate_date( rng ),
415  datetime = (rng.NextDouble() < null_probability) ? null : Test.generate_datetime(rng),
416  decimal_ = (rng.NextDouble() < null_probability) ? null : Test.generate_decimal(rng),
417  ipv4 = ( rng.NextDouble() < null_probability ) ? null : Test.generate_IPv4( rng ),
418  time = (rng.NextDouble() < null_probability) ? null : Test.generate_time(rng),
419  timestamp = ( rng.NextDouble() < null_probability ) ? null : ((long?)rng.Next( -306102240, 293795424 ) * rng.Next( 100000 ))
420  };
421 
422  //Console.WriteLine( "#" + i + ": " + record.ToString() + "\n" ); // debug~~~~~~~~
423  //records.Add( record );
424  ingestor.insert( record );
425  } // end for loop
426 
427  Console.WriteLine( $"Generated {num_records} records." );
428 
430  //Console.WriteLine( $"Inserting {num_records} records..." );
431  //ingestor.insert( records );
432 
433  // Flush the ingestor (which actually inserts the records)
434  Console.WriteLine( "\nFlushing any remaining records." );
435  ingestor.flush();
436  } // end test_all_types_allshard()
437 
438 
439  private static void test_all_types_ip_regex_3shard_0pk( string server_url )
440  {
441  // Establish a connection with Kinetica
442  Kinetica kdb = new Kinetica( server_url );
443 
444  Console.WriteLine( "\n\n" );
445  Console.WriteLine( "Test Multihead Ingest with a Regex Given for Worker IP Addresses (3 shard keys, no PKs)" );
446  Console.WriteLine( "=======================================================================================" );
447  Console.WriteLine();
448 
449  // Create a type for our record_type_1 class
450  // Add some interesting properties for some of the data types
451  IDictionary<string, IList<string>> column_properties = new Dictionary<string, IList<string>>();
452  // Integer shard key
453  List<string> i_props = new List<string>();
454  i_props.Add( ColumnProperty.SHARD_KEY );
455  column_properties.Add( "i", i_props );
456  // Double shard key
457  List<string> d_props = new List<string>();
458  d_props.Add( ColumnProperty.SHARD_KEY );
459  column_properties.Add( "d", d_props );
460  // Short shard key
461  List<string> i16_props = new List<string>();
462  i16_props.Add( ColumnProperty.SHARD_KEY );
463  column_properties.Add( "i16", i16_props );
464 
465  // Create the KineticaType object which facilitates creating types in the database
466  KineticaType type1 = KineticaType.fromClass( typeof( record_type_all ), column_properties );
467 
468  // Create the type in the database
469  string type_id = type1.create( kdb );
470 
471  string table_name = "csharp_example_table_3s0pk";
472  // Clear any previously made table with the same name
473  Console.WriteLine( "Clearing any existing table named '{0}'", table_name );
474  try { kdb.clearTable( table_name, null ); } catch ( Exception ex ) { /* I don't care if the table doesn't already exists! */ }
475  Console.WriteLine();
476 
477  // Create a table of the given type
478  Console.WriteLine( $"Creating table named '{table_name}'" );
479  kdb.createTable( table_name, type_id );
480  Console.WriteLine();
481 
482  // Create the ingestor
483  int batch_size = 100;
484  Regex ip_regex = new Regex( "172.30.*" );
486  KineticaIngestor<record_type_all> ingestor = new KineticaIngestor<record_type_all>( kdb, table_name, batch_size, type1, null, worker_list );
487 
488  // Generate data to be inserted
489  int num_records = batch_size * 5;
490  List<record_type_all> records = new List<record_type_all>();
491  Random rng = new Random();
492  double null_probability = 0.2;
493  for ( int i = 0; i < num_records; ++i )
494  {
495  // Restricting string length to 256
496  int max_str_len = rng.Next( 0, 256 );
497  record_type_all record = new record_type_all()
498  {
499  i = rng.Next(),
500  i8 = rng.Next(),
501  i16 = rng.Next(),
502  l = (long)rng.Next(),
503  f = (float)(rng.NextDouble() * rng.Next()),
504  d = ( rng.NextDouble() < null_probability ) ? null : ( double? ) ( rng.NextDouble() * rng.Next() ),
505  s = System.IO.Path.GetRandomFileName().Truncate( max_str_len ),
506  c1 = System.IO.Path.GetRandomFileName().Truncate( 1 ),
507  c2 = System.IO.Path.GetRandomFileName().Truncate( 2 ),
508  c4 = System.IO.Path.GetRandomFileName().Truncate( 4 ),
509  c8 = System.IO.Path.GetRandomFileName().Truncate( 8 ),
510  c16 = System.IO.Path.GetRandomFileName().Truncate( 16 ),
511  c32 = System.IO.Path.GetRandomFileName().Truncate( 32 ),
512  c64 = System.IO.Path.GetRandomFileName().Truncate( 64 ),
513  c128 = System.IO.Path.GetRandomFileName().Truncate( 128 ),
514  c256 = System.IO.Path.GetRandomFileName().Truncate( 256 ),
515  date = Test.generate_date( rng ),
516  datetime = Test.generate_datetime( rng ),
517  decimal_ = Test.generate_decimal( rng ),
518  ipv4 = Test.generate_IPv4( rng ),
519  time = Test.generate_time( rng ),
520  timestamp = (long) rng.Next()
521  };
522 
523  //Console.WriteLine( record.ToString() ); // debug~~~~~~~~
524  records.Add( record );
525  } // end for loop
526 
527  Console.WriteLine( $"Generated {num_records} records." );
528 
529  // Insert the records into the ingestor
530  Console.WriteLine( $"Inserting {num_records} records..." );
531  ingestor.insert( records );
532 
533  // Flush the ingestor (which actually inserts the records)
534  Console.WriteLine( "\nFlushing any remaining records." );
535  ingestor.flush();
536  } // end test_all_types_ip_regex_3shard_0pk()
537 
538 
539 
540 
541  private static void test_all_types_3pk_3shard( string server_url )
542  {
543  // Establish a connection with Kinetica
544  Kinetica kdb = new Kinetica( server_url );
545 
546  Console.WriteLine( "\n\n" );
547  Console.WriteLine( "Test Multihead Ingest: One column per Type; 3 Primary Keys, 3 Shard Keys" );
548  Console.WriteLine( "========================================================================" );
549  Console.WriteLine();
550 
551  // Create a type for our record_type_1 class
552  // Add some interesting properties for some of the data types
553  IDictionary<string, IList<string>> column_properties = new Dictionary<string, IList<string>>();
554 
555  // long shard key, also primary key
556  List<string> l_props = new List<string>();
557  l_props.Add( ColumnProperty.PRIMARY_KEY );
558  l_props.Add( ColumnProperty.SHARD_KEY );
559  column_properties.Add( "l", l_props );
560 
561  // date primary key as well as shard key
562  List<string> date_props = new List<string>();
563  date_props.Add( ColumnProperty.DATE );
564  date_props.Add( ColumnProperty.PRIMARY_KEY );
565  date_props.Add( ColumnProperty.SHARD_KEY );
566  column_properties.Add( "date", date_props );
567 
568  // time primary key as well as shard
569  List<string> time_props = new List<string>();
570  time_props.Add( ColumnProperty.TIME );
571  time_props.Add( ColumnProperty.PRIMARY_KEY );
572  time_props.Add( ColumnProperty.SHARD_KEY );
573  column_properties.Add( "time", time_props );
574 
575  // Create the KineticaType object which facilitates creating types in the database
576  KineticaType type1 = KineticaType.fromClass( typeof( record_type_all ), column_properties );
577 
578  // Create the type in the database
579  string type_id = type1.create( kdb );
580  //Console.WriteLine( "ID of the created type: " + type_id );
581  //Console.WriteLine();
582 
583  string table_name = "csharp_example_table_3s3pk";
584  // Clear any previously made table with the same name
585  Console.WriteLine( "Clearing any existing table named '{0}'", table_name );
586  try { kdb.clearTable( table_name, null ); } catch ( Exception ex ) { /* I don't care if the table doesn't already exists! */ }
587  Console.WriteLine();
588 
589  // Create a table of the given type
590  Console.WriteLine( $"Creating table named '{table_name}'" );
591  kdb.createTable( table_name, type_id );
592  Console.WriteLine();
593 
594  // Create the ingestor
595  int batch_size = 100;
596  KineticaIngestor<record_type_all> ingestor = new KineticaIngestor<record_type_all>( kdb, table_name, batch_size, type1 );
597 
598  // Generate data to be inserted
599  int num_records = batch_size * 50;
600  Random rng = new Random();
601  double null_probability = 0.2;
602  for ( int i = 0; i < num_records; ++i )
603  {
604  // Restricting string length to 256
605  int max_str_len = rng.Next( 0, 256 );
606  record_type_all record = new record_type_all()
607  {
608  i = rng.Next(),
609  i8 = rng.Next(),
610  i16 = rng.Next(),
611  l = (long)rng.Next(),
612  f = (float)(rng.NextDouble() * rng.Next()),
613  d = ( rng.NextDouble() < null_probability ) ? null : ( double? ) ( rng.NextDouble() * rng.Next() ),
614  s = System.IO.Path.GetRandomFileName().Truncate( max_str_len ),
615  c1 = System.IO.Path.GetRandomFileName().Truncate( 1 ),
616  c2 = System.IO.Path.GetRandomFileName().Truncate( 2 ),
617  c4 = System.IO.Path.GetRandomFileName().Truncate( 4 ),
618  c8 = System.IO.Path.GetRandomFileName().Truncate( 8 ),
619  c16 = System.IO.Path.GetRandomFileName().Truncate( 16 ),
620  c32 = System.IO.Path.GetRandomFileName().Truncate( 32 ),
621  c64 = System.IO.Path.GetRandomFileName().Truncate( 64 ),
622  c128 = System.IO.Path.GetRandomFileName().Truncate( 128 ),
623  c256 = System.IO.Path.GetRandomFileName().Truncate( 256 ),
624  date = Test.generate_date( rng ),
625  datetime = Test.generate_datetime( rng ),
626  decimal_ = Test.generate_decimal( rng ),
627  ipv4 = Test.generate_IPv4( rng ),
628  time = Test.generate_time( rng ),
629  timestamp = (long) rng.Next()
630  };
631 
632  //Console.WriteLine( record.ToString() ); // debug~~~~~~~~
633  ingestor.insert( record );
634  } // end for loop
635 
636  Console.WriteLine( $"Generated {num_records} records." );
637 
638  // Flush the ingestor (which actually inserts the records)
639  Console.WriteLine( "\nFlushing any remaining records." );
640  ingestor.flush();
641  } // end test_all_types_3pk_3shard()
642 
643 
644 
645  private static void test_all_types_3pk_0shard( string server_url )
646  {
647  // Establish a connection with Kinetica
648  Kinetica kdb = new Kinetica( server_url );
649 
650  Console.WriteLine( "\n\n" );
651  Console.WriteLine( "Test Multihead Ingest: One column per type; 3 Primary Keys, No Shard Key" );
652  Console.WriteLine( "========================================================================" );
653  Console.WriteLine();
654 
655  // Create a type for our record_type_1 class
656  // Add some interesting properties for some of the data types
657  IDictionary<string, IList<string>> column_properties = new Dictionary<string, IList<string>>();
658 
659  // long primary key
660  List<string> l_props = new List<string>();
661  l_props.Add( ColumnProperty.PRIMARY_KEY );
662  column_properties.Add( "l", l_props );
663 
664  // date primary key
665  List<string> date_props = new List<string>();
666  date_props.Add( ColumnProperty.PRIMARY_KEY );
667  column_properties.Add( "date", date_props );
668 
669  // time primary key as well as shard
670  List<string> time_props = new List<string>();
671  time_props.Add( ColumnProperty.PRIMARY_KEY );
672  column_properties.Add( "time", time_props );
673 
674  // Create the KineticaType object which facilitates creating types in the database
675  KineticaType type1 = KineticaType.fromClass( typeof( record_type_all ), column_properties );
676 
677  // Create the type in the database
678  string type_id = type1.create( kdb );
679  //Console.WriteLine( "ID of the created type: " + type_id );
680  //Console.WriteLine();
681 
682  string table_name = "csharp_example_table_0s3pk";
683  // Clear any previously made table with the same name
684  Console.WriteLine( "Clearing any existing table named '{0}'", table_name );
685  try { kdb.clearTable( table_name, null ); } catch ( Exception ex ) { /* I don't care if the table doesn't already exists! */ }
686  Console.WriteLine();
687 
688  // Create a table of the given type
689  Console.WriteLine( $"Creating table named '{table_name}'" );
690  kdb.createTable( table_name, type_id );
691  Console.WriteLine();
692 
693  // Create the ingestor
694  int batch_size = 100;
695  KineticaIngestor<record_type_all> ingestor = new KineticaIngestor<record_type_all>( kdb, table_name, batch_size, type1 );
696 
697  // Generate data to be inserted
698  int num_records = batch_size * 50;
699  Random rng = new Random();
700  double null_probability = 0.2;
701  for ( int i = 0; i < num_records; ++i )
702  {
703  // Restricting string length to 256
704  int max_str_len = rng.Next( 0, 256 );
705  record_type_all record = new record_type_all()
706  {
707  i = rng.Next(),
708  i8 = rng.Next(),
709  i16 = rng.Next(),
710  l = (long)rng.Next(),
711  f = (float)(rng.NextDouble() * rng.Next()),
712  d = ( rng.NextDouble() < null_probability ) ? null : ( double? ) ( rng.NextDouble() * rng.Next() ),
713  s = System.IO.Path.GetRandomFileName().Truncate( max_str_len ),
714  c1 = System.IO.Path.GetRandomFileName().Truncate( 1 ),
715  c2 = System.IO.Path.GetRandomFileName().Truncate( 2 ),
716  c4 = System.IO.Path.GetRandomFileName().Truncate( 4 ),
717  c8 = System.IO.Path.GetRandomFileName().Truncate( 8 ),
718  c16 = System.IO.Path.GetRandomFileName().Truncate( 16 ),
719  c32 = System.IO.Path.GetRandomFileName().Truncate( 32 ),
720  c64 = System.IO.Path.GetRandomFileName().Truncate( 64 ),
721  c128 = System.IO.Path.GetRandomFileName().Truncate( 128 ),
722  c256 = System.IO.Path.GetRandomFileName().Truncate( 256 ),
723  date = Test.generate_date( rng ),
724  datetime = Test.generate_datetime( rng ),
725  decimal_ = Test.generate_decimal( rng ),
726  ipv4 = Test.generate_IPv4( rng ),
727  time = Test.generate_time( rng ),
728  timestamp = (long) rng.Next()
729  };
730 
731  //Console.WriteLine( record.ToString() ); // debug~~~~~~~~
732  ingestor.insert( record );
733  } // end for loop
734 
735  Console.WriteLine( $"Generated {num_records} records." );
736 
737  // Flush the ingestor (which actually inserts the records)
738  Console.WriteLine( "\nFlushing any remaining records." );
739  ingestor.flush();
740  } // end test_all_types_3pk_0shard()
741 
742 
743 
749  public static string generate_date( Random rng )
750  {
751  int past_range = -90 * 365; //980 years
752  int future_range = 20 * 365; // 20 years
753  int offset = rng.Next( past_range, future_range );
754  DateTime random_date = DateTime.Today.AddDays( offset );
755  return String.Format( "{0:yyyy-MM-dd}", random_date );
756  } // end generate_date
757 
758 
759 
765  public static string generate_datetime( Random rng )
766  {
767  int past_range = -90 * 365; //980 years
768  int future_range = 20 * 365; // 20 years
769  int offset = rng.Next( past_range, future_range );
770  int year = rng.Next(1900, 2500);
771  int month = rng.Next(1, 12);
772  int day = rng.Next(1, 28);
773  int hour = rng.Next(0, 23);
774  int minute = rng.Next(0, 59);
775  int second = rng.Next(0, 59);
776  int msecond = rng.Next(0, 999);
777 
778  DateTime random_datetime = new DateTime( year, month, day,
779  hour, minute, second, msecond );
780 
781  // We don't have to have any time component
782  int time_chance_percent = 90;
783  if (rng.Next(101) > time_chance_percent)
784  return String.Format("{0:yyyy-MM-dd}", random_datetime);
785  else
786  {
787  // Don't have to have the millisecond
788  int num_ms_digits = rng.Next(7);
789  switch (num_ms_digits)
790  {
791  case 0:
792  return String.Format("{0:yyyy-MM-dd HH:mm:ss}", random_datetime);
793  case 1:
794  return String.Format("{0:yyyy-MM-dd HH:mm:ss.F}", random_datetime);
795  case 2:
796  return String.Format("{0:yyyy-MM-dd HH:mm:ss.FF}", random_datetime);
797  case 3:
798  return String.Format("{0:yyyy-MM-dd HH:mm:ss.FFF}", random_datetime);
799  case 4:
800  return String.Format("{0:yyyy-MM-dd HH:mm:ss.FFFF}", random_datetime);
801  case 5:
802  return String.Format("{0:yyyy-MM-dd HH:mm:ss.FFFFF}", random_datetime);
803  case 6:
804  default: // not necessary, but the stupid compiler complains
805  return String.Format("{0:yyyy-MM-dd HH:mm:ss.FFFFFF}", random_datetime);
806  }
807  }
808  } // end generate_datetime
809 
810 
811 
812  private static readonly string numbers = "0123456789";
813 
820  public static string generate_decimal( Random rng )
821  {
822  string sign = (rng.Next( 2 ) == 0) ? "-" : "";
823  // Using up to 14 integral digits to keep things simple since the decimal
824  // range is [-922337203685477.5808, 922337203685477.5807]
825  string precision = new string( Enumerable.Repeat( '1', rng.Next( 15 ) ).Select( i => Test.numbers[ rng.Next( numbers.Length ) ] ).ToArray() );
826  string scale = rng.Next( 0, 10000 ).ToString();
827  return ( sign + precision + "." + scale );
828  } // end generate_decimal
829 
830 
831 
837  public static string generate_IPv4( Random rng )
838  {
839  string n1 = rng.Next( 256 ).ToString();
840  string n2 = rng.Next( 256 ).ToString();
841  string n3 = rng.Next( 256 ).ToString();
842  string n4 = rng.Next( 256 ).ToString();
843  string dot = ".";
844  return ( n1 + dot + n2 + dot + n3 + dot + n4 );
845  } // end generate_ipv4
846 
847 
848 
854  public static string generate_time( Random rng )
855  {
856  int max_miliseconds = 86400000;
857  DateTime time = DateTime.Today;
858  //Console.WriteLine( time.ToLongTimeString() ); // debug~~~~~~~~
859  time = time.Add( TimeSpan.FromMilliseconds( rng.Next( max_miliseconds ) ) );
860  //Console.WriteLine( String.Format( "{0:HH}:{0:mm}:{0:ss}.{0:FFF}", time ) ); // debug~~~~~~
861  string time_str;
862  if ( (time.Millisecond > 0) && (rng.Next( 1, 6 ) > 3) ) // two in five will get the milliseconds
863  time_str = String.Format( "{0:HH}:{0:mm}:{0:ss}.{0:FFF}", time );
864  else
865  time_str = String.Format( "{0:HH}:{0:mm}:{0:ss}", time );
866  return time_str;
867  } // end generate_time
868 
869 
870  } // end class Test
871 } // end namespace Test
872 
873 
874 
875 
876 
877 
878 
879 
880 
881 
882 
883 
884 
885 
886 
887 
const string CHAR1
This property provides optimized memory, disk and query performance for string columns.
static string generate_decimal(Random rng)
Generate a random decimal value (up to 15 digits of precision and up to four digits of scale)...
Definition: Test.cs:820
const string DATETIME
Valid only for &#39;string&#39; columns.
const string INT16
This property provides optimized memory and query performance for int columns.
static string generate_time(Random rng)
Generate a random time of the format HH:MM:SS[.mmm].
Definition: Test.cs:854
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.
static string generate_date(Random rng)
Generate a random date.
Definition: Test.cs:749
const string CHAR128
This property provides optimized memory, disk and query performance for string columns.
static string generate_IPv4(Random rng)
Generate a random IPv4 address.
Definition: Test.cs:837
CreateTableResponse createTable(CreateTableRequest request_)
Creates a new table or collection.
Column properties used for Kinetica types.
const string TIMESTAMP
Valid only for &#39;long&#39; columns.
const string CHAR16
This property provides optimized memory, disk and query performance for string columns.
static string generate_datetime(Random rng)
Generate a random datetime.
Definition: Test.cs:765
A list of worker URLs to use for multi-head ingest.
Extension to string that has a truncate function.
Definition: Test.cs:19
const string CHAR64
This property provides optimized memory, disk and query performance for string columns.
const string CHAR4
This property provides optimized memory, disk and query performance for string columns.
const string CHAR2
This property provides optimized memory, disk and query performance for string columns.
const string DATE
Valid only for &#39;string&#39; columns.
const string CHAR8
This property provides optimized memory, disk and query performance for string columns.
const string DECIMAL
Valid only for &#39;string&#39; columns.
const string CHAR32
This property provides optimized memory, disk and query performance for string columns.
Connection Options
Definition: Kinetica.cs:50
const string IPV4
This property provides optimized memory, disk and query performance for string columns representing I...
CreateUserInternalResponse createUserInternal(CreateUserInternalRequest request_)
Creates a new internal user (a user whose credentials are managed by the database system)...
ClearTableResponse clearTable(ClearTableRequest request_)
Clears (drops) one or all tables in the database cluster.
Definition: Test.cs:14
const string CHAR256
This property provides optimized memory, disk and query performance for string columns.
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...
const string SHARD_KEY
This property indicates that this column will be part of (or the entire) shard key.
const string INT8
This property provides optimized memory and query performance for int columns.
static string Truncate(this string value, int maxLength)
Definition: Test.cs:21
string create(Kinetica kinetica)
Given a handle to the server, creates a type in the database based on this data type.
string Username
Optional: User Name for Kinetica security
Definition: Kinetica.cs:55
InsertRecordsRandomResponse insertRecordsRandom(InsertRecordsRandomRequest request_)
Generates a specified number of random records and adds them to the given table.
const string TIME
Valid only for &#39;string&#39; columns.
const string NULLABLE
This property indicates that this column is nullable.
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.