Kinetica C# API  Version 6.0.1.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.DECIMAL:
294  case ColumnProperty.IPV4:
295  case ColumnProperty.TIME:
296  column_type = Column.ColumnType.STRING;
297  column_property.Add( column_type_string );
298  break;
299 
300  // Primitive type integer
301  case "int":
302  column_type = Column.ColumnType.INT;
303  break;
304 
305  // Properties allowed for the primitive integer type
306  case ColumnProperty.INT8:
307  case ColumnProperty.INT16:
308  column_type = Column.ColumnType.INT;
309  column_property.Add( column_type_string );
310  break;
311 
312  // Primitive type long
313  case "long":
314  column_type = Column.ColumnType.LONG;
315  break;
316 
317  // Properties allowed for the long type
318  case ColumnProperty.TIMESTAMP:
319  column_type = Column.ColumnType.LONG;
320  column_property.Add( column_type_string );
321  break;
322 
323  // Primitive type float
324  case "float":
325  column_type = Column.ColumnType.FLOAT;
326  break;
327 
328  // Primitive type double
329  case "double":
330  column_type = Column.ColumnType.DOUBLE;
331  break;
332 
333  // Primitive type bytes
334  case "bytes":
335  column_type = Column.ColumnType.BYTES;
336  break;
337 
338  default:
339  throw new KineticaException( "Unknown data type/property: " + column_type_string );
340  } // end switch
341 
342  // Check if the column is nullable (where the column name is "column_#" as returned by Kinetica)
343  if ( is_column_nulllable( $"column_{i + 1}", dynamic_schema_json ) )
344  column_property.Add( ColumnProperty.NULLABLE );
345 
346  // Now that we have the name, the type and potentially a property for the column,
347  // create a Column type and add it to the list
348  Column column = new Column( column_name, column_type, column_property );
349  columns.Add( column );
350 
351  // Also, save the column property in the column name->property map
352  column_properties.Add( column_name, column_property );
353  } // end looping over column headers and types
354 
355 
356  // Create and return the KineticaType object based on the columns and properties
357  return new KineticaType( "", columns, column_properties );
358  } // end fromDynamicSchema()
359 
360 
361 
370  public static KineticaType fromClass( Type recordClass, IDictionary<string, IList<string>> properties = null )
371  {
372  return fromClass( recordClass, "", properties );
373  } // end fromClass()
374 
375 
385  public static KineticaType fromClass( Type recordClass, string label, IDictionary<string, IList<string>> properties = null )
386  {
387  // Get the fields in order (******skipping properties inherited from base classes******)
388  // (fields only from this type, i.e. do not include any inherited fields), and public types only
389  System.Reflection.PropertyInfo[] type_properties = recordClass.GetProperties( System.Reflection.BindingFlags.DeclaredOnly |
390  System.Reflection.BindingFlags.Instance |
391  System.Reflection.BindingFlags.Public );
392  Array.Sort( type_properties, delegate ( System.Reflection.PropertyInfo p1, System.Reflection.PropertyInfo p2 )
393  { return p1.MetadataToken.CompareTo( p2.MetadataToken ); } );
394 
395  // Need to have a list of columns
396  List<Column> columns = new List<Column>();
397  List<string> column_names = new List<string>();
398 
399  // Per property, check that it is one of: int, long, float, double, string, bytes
400  foreach ( var property in type_properties )
401  {
402  string column_name = "";
403  Column.ColumnType column_type = Column.ColumnType.DEFAULT;
404  IList<string> column_properties = null;
405  bool is_column_nullable = false;
406 
407  // Get the column name
408  column_name = property.Name;
409 
410  Type prop_type = property.PropertyType;
411 
412  // Check if the field is nullable (declared as T? or Nullable<T>)
413  if ( property.PropertyType.IsGenericType &&
414  ( property.PropertyType.GetGenericTypeDefinition() == typeof( Nullable<> ) ) )
415  { // the field is a nullable field
416  is_column_nullable = true;
417  // Change the property type to be the underlying type
418  prop_type = Nullable.GetUnderlyingType( prop_type );
419  }
420 
421  // Check the column data type (must be one of int, long, float, double, string, and bytes)
422  if ( prop_type == typeof( System.String ) )
423  {
424  column_type = Column.ColumnType.STRING;
425  }
426  else if ( prop_type == typeof( System.Int32 ) )
427  {
428  column_type = Column.ColumnType.INT;
429  }
430  else if ( prop_type == typeof( System.Int64 ) )
431  {
432  column_type = Column.ColumnType.LONG;
433  }
434  else if ( prop_type == typeof( float ) )
435  {
436  column_type = Column.ColumnType.FLOAT;
437  }
438  else if ( prop_type == typeof( double ) )
439  {
440  column_type = Column.ColumnType.DOUBLE;
441  }
442  else if ( prop_type == typeof( byte ) )
443  {
444  column_type = Column.ColumnType.BYTES;
445  }
446  else
447  throw new KineticaException( "Unsupported data type for " + prop_type.Name +
448  ": " + prop_type +
449  " (must be one of int, long, float, double, string, and byte)" );
450 
451  // Extract the given column's properties, if any
452  if ( properties != null )
453  {
454  // This column has properties given
455  properties.TryGetValue( column_name, out column_properties );
456  }
457 
458  // Keep a list of the column names for checking the properties
459  column_names.Add( column_name );
460 
461  // Create the column
462  Column column = new Column( column_name, column_type, column_properties );
463  if ( is_column_nullable ) // Set the appropriate nullable flag for the column
464  column.setIsNullable( true );
465 
466  // Save the column
467  columns.Add( column );
468  } // end looping over all members of the class type
469 
470  // Check for extraneous properties
471  if ( properties != null )
472  {
473  IEnumerable<string> property_keys = properties.Keys;
474  var unknown_columns = property_keys.Where( e => !column_names.Contains( e ) );
475  // Check if any property is provided for wrong/non-existing columns
476  if ( unknown_columns.Any() )
477  throw new KineticaException( "Properties specified for unknown columns." );
478  }
479 
480  // Create the kinetica type
481  KineticaType kType = new KineticaType( label, columns, properties );
482 
483  // Save the class information in the type
484  kType.saveSourceType( recordClass );
485 
486  return kType;
487  } // end fromClass()
488 
489 
498  public static KineticaType fromObject( Object recordObj, IDictionary<string, IList<string>> properties = null )
499  {
500  return fromObject( recordObj, "", properties );
501  } // end fromObject()
502 
503 
513  public static KineticaType fromObject(Object recordObj, string label = "", IDictionary<string, IList<string>> properties = null)
514  {
515  // Create the type schema from the object
516  // --------------------------------------
517  // Get the class type
518  Type object_type = recordObj.GetType();
519 
520  return fromClass( object_type, label, properties );
521  } // end fromObject()
522 
527  public KineticaType(IList<Column> columns)
528  {
529  m_data.columns = columns;
530  initialize();
531  createSchema(); // create the schema from columns
532  }
533 
539  public KineticaType(string label, IList<Column> columns) : this(columns)
540  {
541  m_data.label = label;
542  }
543 
550  public KineticaType( string label, IList<Column> columns, IDictionary<string, IList<string>> properties ) : this( label, columns )
551  {
552  m_properties = properties ?? new Dictionary<string, IList<string>>();
553  }
554 
559  public KineticaType(string typeSchema)
560  {
561  m_data.schemaString = typeSchema;
562  createSchemaFromString( typeSchema );
563  createSchema();
564  }
565 
573  public KineticaType(string label, string typeSchema, IDictionary<string, IList<string>> properties, string typeID = null )
574  {
575  m_properties = properties;
576  m_type_id = typeID;
577  m_data.label = label;
578  m_data.schemaString = typeSchema;
579  createSchemaFromString(typeSchema, properties);
580  createSchema();
581  }
582 
583  public string getLabel() { return m_data.label; }
584  public IList<Column> getColumns() { return m_data.columns; }
585  public Column getColumn(int index) { return m_data.columns[index]; }
586  public Column getColumn(string name) { return m_data.columns[getColumnIndex(name)]; }
587  public int getColumnCount() { return m_data.columns.Count; }
588  public int getColumnIndex(string name) { return m_data.columnMap[name]; }
589  public bool hasColumn(string name) { return m_data.columnMap.ContainsKey(name); }
590  public Schema getSchema() { return m_data.schema; }
591  public string getSchemaString() { return m_data.schemaString; }
592  public string getTypeID() { return m_type_id; }
593 
598  public void saveSourceType( Type sourceType )
599  {
600  this.m_data.sourceType = sourceType;
601  } // end saveSourceType
602 
603 
610  public string create(Kinetica kinetica)
611  {
612  // Save the association between this KineticaType's source and itself in the Kinetica object
613  // for future reference (it helps with encoding and decoding records)
614  if ( this.m_data.sourceType != null )
615  kinetica.SetKineticaSourceClassToTypeMapping( this.m_data.sourceType, this );
616 
617  // Register the type with Kinetica
618  CreateTypeResponse response = kinetica.createType( m_data.schemaString, m_data.label, m_properties);
619  return response.type_id;
620  } // end create()
621 
622  private KineticaType() { }
623 
628  private void initialize()
629  {
630  int columnCount = m_data.columns.Count;
631 
632  if (columnCount == 0)
633  {
634  throw new ArgumentException("At least one column must be specified.");
635  }
636 
637  for (int i = 0; i < columnCount; ++i)
638  {
639  string columnName = m_data.columns[i].getName();
640 
641  if (m_data.columnMap.ContainsKey(columnName))
642  {
643  throw new ArgumentException("Duplicate column name " + columnName + " specified.");
644  }
645 
646  m_data.columnMap[columnName] = i;
647  }
648  } // end initialize()
649 
650 
656  private void createSchemaFromString( string typeSchema,
657  IDictionary<string, IList<string>> properties = null)
658  {
659  // Create the avro schema from the string and save it
660  try
661  {
662  m_data.schema = RecordSchema.Parse(typeSchema);
663  }
664  catch (Exception ex)
665  {
666  throw new KineticaException(ex.ToString());
667  }
668 
669  var root = JObject.Parse(typeSchema);
670 
671  var rootType = root["type"];
672  if ((null == rootType) || !rootType.ToString().Contains("record"))
673  {
674  throw new ArgumentException("Schema must be of type record.");
675  }
676 
677  var fields = root["fields"];
678  if ((null == fields) || !fields.HasValues)
679  {
680  throw new ArgumentException("Schema has no fields.");
681  }
682 
683  foreach (var field in fields)
684  {
685  //if (!field->first.empty() || field->second.empty())
686  //{
687  // throw std::invalid_argument("Schema has invalid field.");
688  //}
689 
690  // Do NOT use ToString 'cause it includes the double quotes (turns it into a JSON representation)
691  var fieldName = (string) field["name"];
692  if (string.IsNullOrEmpty(fieldName))
693  {
694  throw new ArgumentException("Schema has unnamed field.");
695  }
696 
697  if (m_data.columnMap.ContainsKey(fieldName))
698  {
699  throw new ArgumentException($"Duplicate field name {fieldName}.");
700  }
701 
702  var fieldType = field["type"];
703  if (null == fieldType)
704  {
705  throw new ArgumentException($"Field {fieldName} has no type.");
706  }
707 
708  // Flag for nullability
709  bool is_column_nullable = false;
710 
711  if (fieldType.HasValues) // If it has children
712  {
713  var fieldTypeArray = fieldType;
714 
715  foreach (var fieldTypeElement in fieldTypeArray.Children())
716  {
717  bool valid = false;
718  //if (fieldTypeElement->first.empty())
719  {
720  var fieldTypeElementString = fieldTypeElement.ToString();
721 
722  if (!string.IsNullOrEmpty(fieldTypeElementString))
723  {
724  if (fieldTypeElementString == "null" || fieldTypeElementString == "\"null\"")
725  {
726  is_column_nullable = true;
727  valid = true;
728  }
729  else //if (fieldType->empty())
730  {
731  fieldType = fieldTypeElement; // fieldTypeElementString;
732  valid = true;
733  }
734  }
735  }
736 
737  if (!valid)
738  {
739  throw new ArgumentException("Field {fieldName} has invalid type.");
740  }
741  }
742 
743  //if (fieldType->empty())
744  //{
745  // throw new ArgumentException("Field " + *fieldName + " has invalid type.");
746  //}
747  }
748 
749  Column.ColumnType columnType;
750 
751  if (fieldType.ToString().Equals("bytes") || fieldType.ToString().Equals("\"bytes\""))
752  {
753  columnType = Column.ColumnType.BYTES;
754  }
755  else if (fieldType.ToString().Equals("double") || fieldType.ToString().Equals("\"double\""))
756  {
757  columnType = Column.ColumnType.DOUBLE;
758  }
759  else if (fieldType.ToString().Equals("float") || fieldType.ToString().Equals("\"float\""))
760  {
761  columnType = Column.ColumnType.FLOAT;
762  }
763  else if (fieldType.ToString().Equals("int") || fieldType.ToString().Equals("\"int\""))
764  {
765  columnType = Column.ColumnType.INT;
766  }
767  else if (fieldType.ToString().Equals("long") || fieldType.ToString().Equals("\"long\""))
768  {
769  columnType = Column.ColumnType.LONG;
770  }
771  else if (fieldType.ToString().Equals("string") || fieldType.ToString().Equals("\"string\""))
772  {
773  columnType = Column.ColumnType.STRING;
774  }
775  else
776  {
777  throw new ArgumentException("Field {fieldName} must be of type bytes, double, float, int, long or string.");
778  }
779 
780  IList<string> columnProperties = null;
781  if (null != properties) properties.TryGetValue(fieldName, out columnProperties);
782  // Check the column properties for nullability
783  if ( ( null != columnProperties ) &&
784  ( columnProperties.Contains( ColumnProperty.NULLABLE ) ) )
785  is_column_nullable = true;
786 
787  // Create the column to be added
788  Column column = new Column( fieldName, columnType, columnProperties );
789 
790  // Set the "nullability"
791  column.setIsNullable( is_column_nullable );
792 
793  m_data.columns.Add( column );
794 
795  m_data.columnMap[fieldName] = m_data.columns.Count - 1;
796  }
797  } // end createSchemaFromString()
798 
802  private void createSchema()
803  {
804  // First, check if the schema has already been created
805  if (m_data.schema != null)
806  {
807  // nothing to do
808  return;
809  }
810 
811  // Check if the schema string exists, if so, create the schema from that
812  if (m_data.schemaString != null)
813  {
814  try
815  {
816  m_data.schema = RecordSchema.Parse(m_data.schemaString);
817  return;
818  }
819  catch (Exception ex)
820  {
821  throw new KineticaException(ex.ToString());
822  }
823  } // done creating the schema from the schema string
824 
825  // Since the shortcuts didn't apply, create a JSON object from the columns
826  // and then create the schema and the schema string off it
827  // --------------------------------------------------------------------------
828  // Create the json string for the type
829  string schema_string = "";
830  // Create the json string opening with empty fields (with a generic 'type_name' (because the
831  // server always replaces the name with this string anyway) )
832  string schema_opening = "{'type':'record','name':'type_name','fields':[";
833  // Create the json string closing
834  string schema_closing = "]}";
835 
836  schema_string += schema_opening;
837 
838  // Create the json substrings for the columns
839  foreach (var column in m_data.columns)
840  {
841  // Add the name
842  string field_name = ("'name':'" + column.getName() + "'");
843 
844  // Add the type
845  string field_type = "";
846  if (column.isNullable())
847  { // the column is nullable, so we need a union
848  field_type = ("['" + column.getTypeString() + "','null']");
849  }
850  else // regular type, no union needed
851  {
852  field_type = ( "'" + column.getTypeString() + "'" );
853  }
854  field_type = ("'type':" + field_type);
855 
856  // Put the field together
857  string field = ("{" + field_name + "," + field_type + "},");
858  schema_string += field;
859  } // end looping over the fields
860 
861  // Trim the trailing comma from the fields
862  char[] comma = { ',' };
863  schema_string = schema_string.TrimEnd(comma);
864  // Add the ending of the json string
865  schema_string += schema_closing;
866 
867  // Create the RecordSchema from the JSON string
868  try
869  {
870  m_data.schema = RecordSchema.Parse(schema_string);
871  }
872  catch (Exception ex)
873  {
874  throw new KineticaException(ex.ToString());
875  }
876 
877  // Save the schema string
878  m_data.schemaString = m_data.schema.ToString();
879  return;
880  } // end createSchema()
881  } // end class KineticaType
882 } // 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 /create/type.
Definition: CreateType.cs:269
API to talk to Kinetica Database
Definition: Kinetica.cs:40