Kinetica C# API  Version 7.0.19.0
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Pages
KineticaType.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using Avro;
5 using Newtonsoft.Json.Linq;
6 
7 namespace kinetica
8 {
9  public class KineticaType
10  {
11  public class Column
12  {
13  public enum ColumnType
14  {
15  BYTES = Avro.EnumSchema.Type.Bytes,
16  DOUBLE = Avro.EnumSchema.Type.Double,
17  FLOAT = Avro.EnumSchema.Type.Float,
18  INT = Avro.EnumSchema.Type.Int,
19  LONG = Avro.EnumSchema.Type.Long,
20  STRING = Avro.EnumSchema.Type.String,
21  DEFAULT = Avro.EnumSchema.Type.Error
22  };
23 
24  private string m_name;
25  private ColumnType m_type;
26  private bool m_isNullable;
27  private IList<string> m_properties;
28 
35  public Column(string name, ColumnType type, IList<string> properties = null)
36  {
37  m_name = name;
38  m_type = type;
39  m_isNullable = false;
40  m_properties = properties ?? new List<string>();
41 
42  initialize();
43  }
44 
49  public string getName() { return m_name; }
50 
55  public ColumnType getType() { return m_type; }
56 
61  public bool isNullable() { return m_isNullable; }
62 
67  public IList<string> getProperties() { return m_properties; }
68 
69  internal void setIsNullable( bool val ) { m_isNullable = val; }
70 
75  public string getTypeString()
76  {
77  switch (m_type)
78  {
79  case ColumnType.BYTES:
80  return "bytes";
81  case ColumnType.DOUBLE:
82  return "double";
83  case ColumnType.FLOAT:
84  return "float";
85  case ColumnType.INT:
86  return "int";
87  case ColumnType.LONG:
88  return "long";
89  case ColumnType.STRING:
90  return "string";
91  default:
92  throw new KineticaException( "Unsupported column type: " + m_type );
93  }
94  } // end getTypeString()
95 
96  private void initialize()
97  {
98  if (string.IsNullOrEmpty(m_name))
99  {
100  throw new ArgumentException("Name must not be empty.");
101  }
102 
103  switch (m_type)
104  {
105  case ColumnType.BYTES:
106  case ColumnType.DOUBLE:
107  case ColumnType.FLOAT:
108  case ColumnType.INT:
109  case ColumnType.LONG:
110  case ColumnType.STRING:
111  break;
112 
113  default:
114  throw new ArgumentException("Column " + m_name + " must be of type BYTES, DOUBLE, FLOAT, INT, LONG or STRING.");
115  }
116 
117  foreach (var it in m_properties)
118  {
119  if (string.IsNullOrEmpty(it))
120  {
121  throw new ArgumentException("Properties must not be empty.");
122  }
123 
124  if (!m_isNullable && (it == ColumnProperty.NULLABLE))
125  {
126  m_isNullable = true;
127  }
128  }
129  }
130 
131  public override string ToString()
132  {
133  return $"{m_name} ({m_type.ToString()})";
134  }
135  } // end class Column
136 
137  private class TypeData
138  {
139  public string label;
140  public IList<Column> columns = new List<Column>();
141  public Dictionary<string, int> columnMap = new Dictionary<string, int>();
142  public string schemaString = null;
143  public Schema schema = null;
144  public Type sourceType = null;
145  }
146 
147  private TypeData m_data = new TypeData();
148  private IDictionary<string, IList<string>> m_properties = new Dictionary<string, IList<string>>();
149  private string m_type_id = null;
150 
157  public static KineticaType fromTable(Kinetica kinetica, string tableName)
158  {
159  var response = kinetica.showTable(tableName);
160  var typeIdCount = response.type_ids.Count;
161 
162  if (typeIdCount == 0)
163  {
164  throw new KineticaException("Table " + tableName + " does not exist.");
165  }
166 
167  string typeID = response.type_ids[0];
168  if (typeIdCount > 1)
169  {
170  for (int i = 1; i < typeIdCount; ++i)
171  {
172  if (response.type_ids[i] != typeID)
173  {
174  throw new KineticaException("Table " + tableName + " is not homogeneous.");
175  }
176  }
177  }
178 
179  return new KineticaType(response.type_labels[0], response.type_schemas[0], response.properties[0], typeID );
180  }
181 
188  public static KineticaType fromTypeID(Kinetica kinetica, string typeId)
189  {
190  var response = kinetica.showTypes(typeId, "");
191 
192  if (response.type_ids.Count < 1)
193  {
194  throw new KineticaException("Type " + typeId + " does not exist.");
195  }
196 
197  return new KineticaType(response.labels[0], response.type_schemas[0], response.properties[0]);
198  }
199 
200 
208  public static KineticaType fromDynamicSchema( string dynamic_table_schema_string,
209  Object[] column_headers, Object[] column_types )
210  {
211  // Make sure that the lists of column names and types are of the same length
212  if ( column_headers.Length != column_types.Length )
213  throw new KineticaException( "List of column names and types are not of the same length." );
214 
215  // Parse the schema string so that we can later check if a given column is nullable
216  JObject dynamic_schema_json;
217  try
218  {
219  dynamic_schema_json = JObject.Parse( dynamic_table_schema_string );
220  }
221  catch ( Exception ex )
222  {
223  throw new KineticaException( ex.ToString() );
224  }
225 
226  // Create a delegate for checking if a field/column is nullable
227  // ------------------------------------------------------------
228  // The first parameter is the column name, the second is the JSON object
229  var is_column_nulllable = new Func<string, JObject, bool>( (column_name, schema_json) => {
230  // Find the appropriate field
231  bool found_field = false;
232  foreach ( var field in schema_json["fields"] )
233  {
234  if ( (string)field[ "name" ] == column_name )
235  {
236  found_field = true; // found it!
237  // Get the type and see if it's a nullable type
238  // (each field is an array of the column type; so need
239  // to extract the type element first)
240  var type_element = field["type"]["items"];
241  if ( type_element is JValue ) // not an array, so can't be nullable
242  return false;
243  // If the type is an array and the second value is 'null', then it's a nullable
244  if ( (type_element is JArray) && ((string)((JArray)type_element)[ 1 ] == "null") )
245  return true;
246  return false;
247  } // end if
248  } // end foreach
249  if ( !found_field )
250  throw new KineticaException( $"Could not find the field named '{column_name}'" );
251  return false; // shouldn't ever get here
252  } );
253 
254  // Create appropriate columns and column properties
255  // ------------------------------------------------
256  IList<Column> columns = new List<Column>();
257  IDictionary<string, IList<string>> column_properties = new Dictionary<string, IList<string>>();
258  for ( int i = 0; i < column_headers.Length; ++i )
259  {
260  // Get the column's name
261  string column_name = column_headers[ i ].ToString();
262 
263  // Get the column's type in string format, which might be a property and not a primitive type
264  // (if so, then we'll have to infer the primitive type and save the property)
265  string column_type_string = column_types[ i ].ToString();
266 
267  // Need to create a list for the properties of the column (we'll
268  // extract at most one from the column type)
269  IList<string> column_property = new List<string>();
270 
271  // We need to also infer the primitive type for this column
272  Column.ColumnType column_type = Column.ColumnType.DEFAULT;
273 
274  // Infer the type and property from the given 'type'
275  switch ( column_type_string )
276  {
277  // Primitive type string (and all properties based on it)
278  case "string":
279  column_type = Column.ColumnType.STRING;
280  break;
281 
282  // All properties allowed for the primitive string type
283  case ColumnProperty.CHAR1:
284  case ColumnProperty.CHAR2:
285  case ColumnProperty.CHAR4:
286  case ColumnProperty.CHAR8:
287  case ColumnProperty.CHAR16:
288  case ColumnProperty.CHAR32:
289  case ColumnProperty.CHAR64:
290  case ColumnProperty.CHAR128:
291  case ColumnProperty.CHAR256:
292  case ColumnProperty.DATE:
293  case ColumnProperty.DATETIME:
294  case ColumnProperty.DECIMAL:
295  case ColumnProperty.IPV4:
296  case ColumnProperty.TIME:
297  column_type = Column.ColumnType.STRING;
298  column_property.Add( column_type_string );
299  break;
300 
301  // Primitive type integer
302  case "int":
303  column_type = Column.ColumnType.INT;
304  break;
305 
306  // Properties allowed for the primitive integer type
307  case ColumnProperty.INT8:
308  case ColumnProperty.INT16:
309  column_type = Column.ColumnType.INT;
310  column_property.Add( column_type_string );
311  break;
312 
313  // Primitive type long
314  case "long":
315  column_type = Column.ColumnType.LONG;
316  break;
317 
318  // Properties allowed for the long type
319  case ColumnProperty.TIMESTAMP:
320  column_type = Column.ColumnType.LONG;
321  column_property.Add( column_type_string );
322  break;
323 
324  // Primitive type float
325  case "float":
326  column_type = Column.ColumnType.FLOAT;
327  break;
328 
329  // Primitive type double
330  case "double":
331  column_type = Column.ColumnType.DOUBLE;
332  break;
333 
334  // Primitive type bytes
335  case "bytes":
336  column_type = Column.ColumnType.BYTES;
337  break;
338 
339  default:
340  throw new KineticaException( "Unknown data type/property: " + column_type_string );
341  } // end switch
342 
343  // Check if the column is nullable (where the column name is "column_#" as returned by Kinetica)
344  if ( is_column_nulllable( $"column_{i + 1}", dynamic_schema_json ) )
345  column_property.Add( ColumnProperty.NULLABLE );
346 
347  // Now that we have the name, the type and potentially a property for the column,
348  // create a Column type and add it to the list
349  Column column = new Column( column_name, column_type, column_property );
350  columns.Add( column );
351 
352  // Also, save the column property in the column name->property map
353  column_properties.Add( column_name, column_property );
354  } // end looping over column headers and types
355 
356 
357  // Create and return the KineticaType object based on the columns and properties
358  return new KineticaType( "", columns, column_properties );
359  } // end fromDynamicSchema()
360 
361 
362 
378  public static KineticaType fromClass( Type recordClass, IDictionary<string, IList<string>> properties = null )
379  {
380  return fromClass( recordClass, "", properties );
381  } // end fromClass()
382 
383 
393  public static KineticaType fromClass( Type recordClass, string label, IDictionary<string, IList<string>> properties = null )
394  {
395  // Get the fields in order (******skipping properties inherited from base classes******)
396  // (fields only from this type, i.e. do not include any inherited fields), and public types only
397  System.Reflection.PropertyInfo[] type_properties = recordClass.GetProperties( System.Reflection.BindingFlags.DeclaredOnly |
398  System.Reflection.BindingFlags.Instance |
399  System.Reflection.BindingFlags.Public );
400  Array.Sort( type_properties, delegate ( System.Reflection.PropertyInfo p1, System.Reflection.PropertyInfo p2 )
401  { return p1.MetadataToken.CompareTo( p2.MetadataToken ); } );
402 
403  // Need to have a list of columns
404  List<Column> columns = new List<Column>();
405  List<string> column_names = new List<string>();
406 
407  // Per property, check that it is one of: int, long, float, double, string, bytes
408  foreach ( var property in type_properties )
409  {
410  string column_name = "";
411  Column.ColumnType column_type = Column.ColumnType.DEFAULT;
412  IList<string> column_properties = null;
413  bool is_column_nullable = false;
414 
415  // Get the column name
416  column_name = property.Name;
417 
418  Type prop_type = property.PropertyType;
419 
420  // Check if the field is nullable (declared as T? or Nullable<T>)
421  if ( property.PropertyType.IsGenericType &&
422  ( property.PropertyType.GetGenericTypeDefinition() == typeof( Nullable<> ) ) )
423  { // the field is a nullable field
424  is_column_nullable = true;
425  // Change the property type to be the underlying type
426  prop_type = Nullable.GetUnderlyingType( prop_type );
427  }
428 
429  // Check the column data type (must be one of int, long, float, double, string, and bytes)
430  if ( prop_type == typeof( System.String ) )
431  {
432  column_type = Column.ColumnType.STRING;
433  }
434  else if ( prop_type == typeof( System.Int32 ) )
435  {
436  column_type = Column.ColumnType.INT;
437  }
438  else if ( prop_type == typeof( System.Int64 ) )
439  {
440  column_type = Column.ColumnType.LONG;
441  }
442  else if ( prop_type == typeof( float ) )
443  {
444  column_type = Column.ColumnType.FLOAT;
445  }
446  else if ( prop_type == typeof( double ) )
447  {
448  column_type = Column.ColumnType.DOUBLE;
449  }
450  else if ( prop_type == typeof( byte ) )
451  {
452  column_type = Column.ColumnType.BYTES;
453  }
454  else
455  throw new KineticaException( "Unsupported data type for " + prop_type.Name +
456  ": " + prop_type +
457  " (must be one of int, long, float, double, string, and byte)" );
458 
459  // Extract the given column's properties, if any
460  if ( properties != null )
461  {
462  // This column has properties given
463  properties.TryGetValue( column_name, out column_properties );
464  }
465 
466  // Keep a list of the column names for checking the properties
467  column_names.Add( column_name );
468 
469  // Create the column
470  Column column = new Column( column_name, column_type, column_properties );
471  if ( is_column_nullable ) // Set the appropriate nullable flag for the column
472  column.setIsNullable( true );
473 
474  // Save the column
475  columns.Add( column );
476  } // end looping over all members of the class type
477 
478  // Check for extraneous properties
479  if ( properties != null )
480  {
481  IEnumerable<string> property_keys = properties.Keys;
482  var unknown_columns = property_keys.Where( e => !column_names.Contains( e ) );
483  // Check if any property is provided for wrong/non-existing columns
484  if ( unknown_columns.Any() )
485  throw new KineticaException( "Properties specified for unknown columns." );
486  }
487 
488  // Create the kinetica type
489  KineticaType kType = new KineticaType( label, columns, properties );
490 
491  // Save the class information in the type
492  kType.saveSourceType( recordClass );
493 
494  return kType;
495  } // end fromClass()
496 
497 
506  public static KineticaType fromObject( Object recordObj, IDictionary<string, IList<string>> properties = null )
507  {
508  return fromObject( recordObj, "", properties );
509  } // end fromObject()
510 
511 
521  public static KineticaType fromObject(Object recordObj, string label = "", IDictionary<string, IList<string>> properties = null)
522  {
523  // Create the type schema from the object
524  // --------------------------------------
525  // Get the class type
526  Type object_type = recordObj.GetType();
527 
528  return fromClass( object_type, label, properties );
529  } // end fromObject()
530 
535  public KineticaType(IList<Column> columns)
536  {
537  m_data.columns = columns;
538  initialize();
539  createSchema(); // create the schema from columns
540  }
541 
547  public KineticaType(string label, IList<Column> columns) : this(columns)
548  {
549  m_data.label = label;
550  }
551 
558  public KineticaType( string label, IList<Column> columns, IDictionary<string, IList<string>> properties ) : this( label, columns )
559  {
560  m_properties = properties ?? new Dictionary<string, IList<string>>();
561  }
562 
567  public KineticaType(string typeSchema)
568  {
569  m_data.schemaString = typeSchema;
570  createSchemaFromString( typeSchema );
571  createSchema();
572  }
573 
581  public KineticaType(string label, string typeSchema, IDictionary<string, IList<string>> properties, string typeID = null )
582  {
583  m_properties = properties;
584  m_type_id = typeID;
585  m_data.label = label;
586  m_data.schemaString = typeSchema;
587  createSchemaFromString(typeSchema, properties);
588  createSchema();
589  }
590 
591  public string getLabel() { return m_data.label; }
592  public IList<Column> getColumns() { return m_data.columns; }
593  public Column getColumn(int index) { return m_data.columns[index]; }
594  public Column getColumn(string name) { return m_data.columns[getColumnIndex(name)]; }
595  public int getColumnCount() { return m_data.columns.Count; }
596  public int getColumnIndex(string name) { return m_data.columnMap[name]; }
597  public bool hasColumn(string name) { return m_data.columnMap.ContainsKey(name); }
598  public Schema getSchema() { return m_data.schema; }
599  public string getSchemaString() { return m_data.schemaString; }
600  public string getTypeID() { return m_type_id; }
601 
606  public void saveSourceType( Type sourceType )
607  {
608  this.m_data.sourceType = sourceType;
609  } // end saveSourceType
610 
611 
618  public string create(Kinetica kinetica)
619  {
620  // Save the association between this KineticaType's source and itself in the Kinetica object
621  // for future reference (it helps with encoding and decoding records)
622  if ( this.m_data.sourceType != null )
623  kinetica.SetKineticaSourceClassToTypeMapping( this.m_data.sourceType, this );
624 
625  // Register the type with Kinetica
626  CreateTypeResponse response = kinetica.createType( m_data.schemaString, m_data.label, m_properties);
627  return response.type_id;
628  } // end create()
629 
630  private KineticaType() { }
631 
636  private void initialize()
637  {
638  int columnCount = m_data.columns.Count;
639 
640  if (columnCount == 0)
641  {
642  throw new ArgumentException("At least one column must be specified.");
643  }
644 
645  for (int i = 0; i < columnCount; ++i)
646  {
647  string columnName = m_data.columns[i].getName();
648 
649  if (m_data.columnMap.ContainsKey(columnName))
650  {
651  throw new ArgumentException("Duplicate column name " + columnName + " specified.");
652  }
653 
654  m_data.columnMap[columnName] = i;
655  }
656  } // end initialize()
657 
658 
664  private void createSchemaFromString( string typeSchema,
665  IDictionary<string, IList<string>> properties = null)
666  {
667  // Create the avro schema from the string and save it
668  try
669  {
670  m_data.schema = RecordSchema.Parse(typeSchema);
671  }
672  catch (Exception ex)
673  {
674  throw new KineticaException(ex.ToString());
675  }
676 
677  var root = JObject.Parse(typeSchema);
678 
679  var rootType = root["type"];
680  if ((null == rootType) || !rootType.ToString().Contains("record"))
681  {
682  throw new ArgumentException("Schema must be of type record.");
683  }
684 
685  var fields = root["fields"];
686  if ((null == fields) || !fields.HasValues)
687  {
688  throw new ArgumentException("Schema has no fields.");
689  }
690 
691  foreach (var field in fields)
692  {
693  //if (!field->first.empty() || field->second.empty())
694  //{
695  // throw std::invalid_argument("Schema has invalid field.");
696  //}
697 
698  // Do NOT use ToString 'cause it includes the double quotes (turns it into a JSON representation)
699  var fieldName = (string) field["name"];
700  if (string.IsNullOrEmpty(fieldName))
701  {
702  throw new ArgumentException("Schema has unnamed field.");
703  }
704 
705  if (m_data.columnMap.ContainsKey(fieldName))
706  {
707  throw new ArgumentException($"Duplicate field name {fieldName}.");
708  }
709 
710  var fieldType = field["type"];
711  if (null == fieldType)
712  {
713  throw new ArgumentException($"Field {fieldName} has no type.");
714  }
715 
716  // Flag for nullability
717  bool is_column_nullable = false;
718 
719  if (fieldType.HasValues) // If it has children
720  {
721  var fieldTypeArray = fieldType;
722 
723  foreach (var fieldTypeElement in fieldTypeArray.Children())
724  {
725  bool valid = false;
726  //if (fieldTypeElement->first.empty())
727  {
728  var fieldTypeElementString = fieldTypeElement.ToString();
729 
730  if (!string.IsNullOrEmpty(fieldTypeElementString))
731  {
732  if (fieldTypeElementString == "null" || fieldTypeElementString == "\"null\"")
733  {
734  is_column_nullable = true;
735  valid = true;
736  }
737  else //if (fieldType->empty())
738  {
739  fieldType = fieldTypeElement; // fieldTypeElementString;
740  valid = true;
741  }
742  }
743  }
744 
745  if (!valid)
746  {
747  throw new ArgumentException("Field {fieldName} has invalid type.");
748  }
749  }
750 
751  //if (fieldType->empty())
752  //{
753  // throw new ArgumentException("Field " + *fieldName + " has invalid type.");
754  //}
755  }
756 
757  Column.ColumnType columnType;
758 
759  if (fieldType.ToString().Equals("bytes") || fieldType.ToString().Equals("\"bytes\""))
760  {
761  columnType = Column.ColumnType.BYTES;
762  }
763  else if (fieldType.ToString().Equals("double") || fieldType.ToString().Equals("\"double\""))
764  {
765  columnType = Column.ColumnType.DOUBLE;
766  }
767  else if (fieldType.ToString().Equals("float") || fieldType.ToString().Equals("\"float\""))
768  {
769  columnType = Column.ColumnType.FLOAT;
770  }
771  else if (fieldType.ToString().Equals("int") || fieldType.ToString().Equals("\"int\""))
772  {
773  columnType = Column.ColumnType.INT;
774  }
775  else if (fieldType.ToString().Equals("long") || fieldType.ToString().Equals("\"long\""))
776  {
777  columnType = Column.ColumnType.LONG;
778  }
779  else if (fieldType.ToString().Equals("string") || fieldType.ToString().Equals("\"string\""))
780  {
781  columnType = Column.ColumnType.STRING;
782  }
783  else
784  {
785  throw new ArgumentException("Field {fieldName} must be of type bytes, double, float, int, long or string.");
786  }
787 
788  IList<string> columnProperties = null;
789  if (null != properties) properties.TryGetValue(fieldName, out columnProperties);
790  // Check the column properties for nullability
791  if ( ( null != columnProperties ) &&
792  ( columnProperties.Contains( ColumnProperty.NULLABLE ) ) )
793  is_column_nullable = true;
794 
795  // Create the column to be added
796  Column column = new Column( fieldName, columnType, columnProperties );
797 
798  // Set the "nullability"
799  column.setIsNullable( is_column_nullable );
800 
801  m_data.columns.Add( column );
802 
803  m_data.columnMap[fieldName] = m_data.columns.Count - 1;
804  }
805  } // end createSchemaFromString()
806 
810  private void createSchema()
811  {
812  // First, check if the schema has already been created
813  if (m_data.schema != null)
814  {
815  // nothing to do
816  return;
817  }
818 
819  // Check if the schema string exists, if so, create the schema from that
820  if (m_data.schemaString != null)
821  {
822  try
823  {
824  m_data.schema = RecordSchema.Parse(m_data.schemaString);
825  return;
826  }
827  catch (Exception ex)
828  {
829  throw new KineticaException(ex.ToString());
830  }
831  } // done creating the schema from the schema string
832 
833  // Since the shortcuts didn't apply, create a JSON object from the columns
834  // and then create the schema and the schema string off it
835  // --------------------------------------------------------------------------
836  // Create the json string for the type
837  string schema_string = "";
838  // Create the json string opening with empty fields (with a generic 'type_name' (because the
839  // server always replaces the name with this string anyway) )
840  string schema_opening = "{'type':'record','name':'type_name','fields':[";
841  // Create the json string closing
842  string schema_closing = "]}";
843 
844  schema_string += schema_opening;
845 
846  // Create the json substrings for the columns
847  foreach (var column in m_data.columns)
848  {
849  // Add the name
850  string field_name = ("'name':'" + column.getName() + "'");
851 
852  // Add the type
853  string field_type = "";
854  if (column.isNullable())
855  { // the column is nullable, so we need a union
856  field_type = ("['" + column.getTypeString() + "','null']");
857  }
858  else // regular type, no union needed
859  {
860  field_type = ( "'" + column.getTypeString() + "'" );
861  }
862  field_type = ("'type':" + field_type);
863 
864  // Put the field together
865  string field = ("{" + field_name + "," + field_type + "},");
866  schema_string += field;
867  } // end looping over the fields
868 
869  // Trim the trailing comma from the fields
870  char[] comma = { ',' };
871  schema_string = schema_string.TrimEnd(comma);
872  // Add the ending of the json string
873  schema_string += schema_closing;
874 
875  // Create the RecordSchema from the JSON string
876  try
877  {
878  m_data.schema = RecordSchema.Parse(schema_string);
879  }
880  catch (Exception ex)
881  {
882  throw new KineticaException(ex.ToString());
883  }
884 
885  // Save the schema string
886  m_data.schemaString = m_data.schema.ToString();
887  return;
888  } // end createSchema()
889  } // end class KineticaType
890 } // end namespace kinetica
ColumnType getType()
Returns the enumeration for the column type.
Definition: KineticaType.cs:55
bool hasColumn(string name)
KineticaType(string typeSchema)
Create a KineticaType object using the string-formatted schema for the type.
static KineticaType fromObject(Object recordObj, string label="", IDictionary< string, IList< string >> properties=null)
Create a KineticaType object from properties of a record object and Kinetica column properties...
KineticaType(string label, IList< Column > columns)
Create a KineticaType object with the given column and label information.
int getColumnIndex(string name)
static KineticaType fromTable(Kinetica kinetica, string tableName)
Create a KineticaType object based on an existing table in the database.
static KineticaType fromTypeID(Kinetica kinetica, string typeId)
Create a KineticaType object based on an existing type in the database.
Column getColumn(int index)
string getTypeString()
Returns the string format of the data type.
Definition: KineticaType.cs:75
KineticaType(string label, IList< Column > columns, IDictionary< string, IList< string >> properties)
Create a KineticaType object with the given column, label, and property information.
Column(string name, ColumnType type, IList< string > properties=null)
Creates a Column object from the given name, type, and properties.
Definition: KineticaType.cs:35
IList< string > getProperties()
Returns the properties for the column.
Definition: KineticaType.cs:67
IList< Column > getColumns()
static KineticaType fromClass(Type recordClass, string label, IDictionary< string, IList< string >> properties=null)
Create a KineticaType object from properties of a record class and Kinetica column properties...
void saveSourceType(Type sourceType)
Saves the given type as this KineticaType&#39;s source type.
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...
KineticaType(string label, string typeSchema, IDictionary< string, IList< string >> properties, string typeID=null)
Create a KineticaType object using the string-formatted schema and properties for its columns...
bool isNullable()
Returns if the column is nullable.
Definition: KineticaType.cs:61
Column getColumn(string name)
static KineticaType fromObject(Object recordObj, IDictionary< string, IList< string >> properties=null)
Create a KineticaType object from properties of a record object and Kinetica column properties...
string create(Kinetica kinetica)
Given a handle to the server, creates a type in the database based on this data type.
string getName()
Returns the name of the column.
Definition: KineticaType.cs:49
static KineticaType fromDynamicSchema(string dynamic_table_schema_string, Object[] column_headers, Object[] column_types)
Create a KineticaType object based on information provided in a dynamic schema.
override string ToString()
KineticaType(IList< Column > columns)
Create a KineticaType object with the given column information.
const string NULLABLE
This property indicates that this column is nullable.
A set of results returned by Kinetica.createType(string,string,IDictionary{string, IList{string}},IDictionary{string, string}).
Definition: CreateType.cs:1024
API to talk to Kinetica Database
Definition: Kinetica.cs:40