private TransformationModel GetModel() { TransformationModel m = null; bool found = false; // Recupera i metadati. Se non sono presenti, ritorna uno stato di invalido foreach (dynamic prop in ComponentMetaData.CustomPropertyCollection) { if (prop.Name == PROPERTY_KEY_MODEL) { // Trovato! found = true; m = TransformationModel.LoadFromJson((string)prop.Value); break; } } if (!found) { throw new ModelNotFoundException(); } else { return(m); } }
public JsonTransformUI(System.Windows.Forms.IWin32Window parent, TransformationModel model, IServiceProvider sp) { // HOTOLTO VARS! // Salva i riferimenti in locale _parent = parent; _model = model; _sp = sp; // Inizializza la UI InitializeComponent(); // Imposta i vari Enumerativi previsti come tipi di dato. (uiIOGrid.Columns["OutColumnType"] as DataGridViewComboBoxColumn).DataSource = Enum.GetNames(typeof(JsonTypes)); // Registra l'handler per il settaggio dei valori di default uiIOGrid.DefaultValuesNeeded += uiIOGrid_DefaultValuesNeeded; // Carico il model LoadModel(_model); }
/* * Carico il modello all'interno della view */ private void LoadModel(TransformationModel m) { inutColumnCb.Items.Clear(); foreach (var el in m.Inputs) { inutColumnCb.Items.Add(el.Key); } if (!String.IsNullOrEmpty(m.InputColumnName)) { inutColumnCb.SelectedItem = m.InputColumnName; } if (m.JsonObjectRelativePath == null) { uiPathToArray.Text = ""; } else { uiPathToArray.Text = m.JsonObjectRelativePath; } if (m.CustomLocalTempDir == null) { uiTempDir.Text = ""; } else { uiTempDir.Text = m.CustomLocalTempDir; } // Tab IO if (m.IoMap != null) { LoadIO(m.IoMap); } else { uiIOGrid.Rows.Clear(); } }
public override void ProvideComponentProperties() { ComponentMetaData.Name = "JSON filter"; ComponentMetaData.Description = "Given a input, this component will parse and process input text putting data into buffers."; ComponentMetaData.ContactInfo = "Alberto Geniola, [email protected]"; // Pulisco gli input, output e le custom properties base.RemoveAllInputsOutputsAndCustomProperties(); //ComponentMetaData.UsesDispositions = false; // Non supportiamo uscite con errori // Configuro l'input var input = ComponentMetaData.InputCollection.New(); input.Name = "Json Input"; // Configuro gli output (per default nessun output presente) var output = ComponentMetaData.OutputCollection.New(); output.Name = "Parsed Json lines"; output.SynchronousInputID = 0; TransformationModel m = null; try { m = GetModel(); } catch (ModelNotFoundException e) { // Non l'ho trovato. Aggiungi la proprietà, salvando l'oggetto MODEL serializzato // in XML. var model = ComponentMetaData.CustomPropertyCollection.New(); model.Description = "Contains information about the confiuguration of the item."; model.Name = PROPERTY_KEY_MODEL; model.Value = new TransformationModel().ToJsonConfig(); } }
/* * Metodo invocato quando il componente UI viene caricato per la prima volta, generalmente in seguito al doppio click sul componente. */ public void Initialize(IDTSComponentMetaData100 dtsComponentMetadata, IServiceProvider serviceProvider) { // Salva un link ai metadati del runtime editor ed al serviceProvider _sp = serviceProvider; _md = dtsComponentMetadata; // Controlla se l'oggetto contiene il model serializzato nelle proprietà. In caso negativo, creane uno nuovo ed attribuisciglielo. IDTSCustomProperty100 model = _md.CustomPropertyCollection[ComponentConstants.PROPERTY_KEY_MODEL]; if (model.Value == null) { _model = new TransformationModel(); model.Value = _model.ToJsonConfig(); } else { _model = TransformationModel.LoadFromJson(model.Value.ToString()); } if (_md == null) { _md = (IDTSComponentMetaData100)_md.Instantiate(); } }
public static TransformationModel LoadFromJson(string jsonConfig) { TransformationModel res = JsonConvert.DeserializeObject <TransformationModel>(jsonConfig); return(res); }
public override void PreExecute() { bool debugging = false; IDTSVariables100 vars = null; try { VariableDispenser.LockOneForRead(JSON_SOURCE_DEBUG_VAR, ref vars); object o = vars[JSON_SOURCE_DEBUG_VAR].Value; if (o != null) { if ((bool)o) { debugging = true; } } } catch (Exception e) { //Do nothing bool fireAgain = false; ComponentMetaData.FireInformation(0, ComponentMetaData.Name, "wk_debug variable cannot be found. I won't stop to let debug attachment.", null, 0, ref fireAgain); } finally { if (vars != null) { vars.Unlock(); } } if (debugging) { MessageBox.Show("Start Debugger"); } TransformationModel m = GetModel(); _opt = new ParallelOptions(); _opt.MaxDegreeOfParallelism = 4; bool cancel = false; // Carico i dettagli dal model try{ m = GetModel(); }catch (ModelNotFoundException ex) { ComponentMetaData.FireError(RUNTIME_ERROR_MODEL_INVALID, ComponentMetaData.Name, "Invalid Metadata for this component.", null, 0, out cancel); return; } // Salva il mapping in un array locale _iomap = m.IoMap.ToArray <IOMapEntry>(); // Salva una copia locale del percorso cui attingere l'array _pathToArray = m.JsonObjectRelativePath; // Genera un dizionario ad accesso veloce per il nome della colonna per i dati json: mappo nome colonna - Indice della colonna nella riga. // Questo dizionario è usato solo per il JSON, mentre per gli input standard non facciamo il lookup, ma usiamo l'indice del buffer. _startOfJsonColIndex = ComponentMetaData.InputCollection[0].InputColumnCollection.Count; _outColsMaps = new Dictionary <string, int>(); foreach (IOMapEntry e in _iomap) { bool found = false; for (var i = 0; i < _iomap.Count(); i++) { var col = ComponentMetaData.OutputCollection[0].OutputColumnCollection[_startOfJsonColIndex + i]; if (col.Name == e.OutputColName) { found = true; int colIndex = BufferManager.FindColumnByLineageID(ComponentMetaData.OutputCollection[0].Buffer, col.LineageID); _outColsMaps.Add(e.OutputColName, colIndex); break; } } if (!found) { // Una colonna del model non ha trovato il corrispettivo nel componente attuale ComponentMetaData.FireError(RUNTIME_ERROR_MODEL_INVALID, ComponentMetaData.Name, "The component is unable to locate the column named " + e.OutputColName + " inside the component metadata. Please review the component.", null, 0, out cancel); return; } } _inputColIndex = BufferManager.FindColumnByLineageID(ComponentMetaData.InputCollection[0].Buffer, ComponentMetaData.InputCollection[0].InputColumnCollection[GetModel().InputColumnName].LineageID); // Check if ww should take care of date parsing if (!m.ParseDates) { _dateParsePolicy = DateParseHandling.None; } }
/* * public override void OnInputPathDetached(int inputID) * { * base.OnInputPathDetached(inputID); * } */ /** * Questo metodo è invocato diverse volte durante il designtime. Al suo interno verifico che i metadati siano * coerenti e consistenti. In caso di ambiguità o lacune, segnalo al designer le situazioni di inconsistenza, * generando opportunamente Warning o Errors. **/ public override Microsoft.SqlServer.Dts.Pipeline.Wrapper.DTSValidationStatus Validate() { if (ComponentMetaData.AreInputColumnsValid == false) { return(DTSValidationStatus.VS_NEEDSNEWMETADATA); } bool fireAgain = false; // Validazione di base // - Una sola linea di output. // - Nessuna linea di input. if (ComponentMetaData.InputCollection.Count != 1) { ComponentMetaData.FireError(ERROR_NO_INPUT_SUPPORTED, ComponentMetaData.Name, "This component requires at least one output lane.", null, 0, out fireAgain); return(Microsoft.SqlServer.Dts.Pipeline.Wrapper.DTSValidationStatus.VS_ISBROKEN); } if (ComponentMetaData.OutputCollection.Count != 1) { ComponentMetaData.FireError(ERROR_SINGLE_OUTPUT_SUPPORTED, ComponentMetaData.Name, "This component only supports a single output lane.", null, 0, out fireAgain); return(Microsoft.SqlServer.Dts.Pipeline.Wrapper.DTSValidationStatus.VS_ISBROKEN); } /* * foreach (IDTSInputColumn100 input in ComponentMetaData.InputCollection[0].InputColumnCollection) { * bool cancel; * if (input.DataType != DataType.DT_STR && input.DataType != DataType.DT_WSTR && input.DataType != DataType.DT_TEXT && input.DataType != DataType.DT_NTEXT) * { * ComponentMetaData.FireError(0, input.IdentificationString, "The column data type of " + input.Name + " is not a textual one, so it is unsupported.","",0,out cancel); * return DTSValidationStatus.VS_ISBROKEN; * } * }*/ TransformationModel m = null; try { m = GetModel(); } catch (Exception e) { return(Microsoft.SqlServer.Dts.Pipeline.Wrapper.DTSValidationStatus.VS_ISBROKEN); } // Controlla la tabella di IO // Il modello è vuoto? var enumerator = m.IoMap.GetEnumerator(); if (m.IoMap == null || enumerator.MoveNext() == false) { ComponentMetaData.FireError(ERROR_IOMAP_EMPTY, ComponentMetaData.Name, "This component must at least have one output column.", null, 0, out fireAgain); return(Microsoft.SqlServer.Dts.Pipeline.Wrapper.DTSValidationStatus.VS_ISBROKEN); } // Assicurati di avere tutte le informazioni per ogni colonna foreach (IOMapEntry e in m.IoMap) { // FieldName and outputFiledName cannot be null, empty and must be unique. if (string.IsNullOrEmpty(e.InputFieldPath)) { ComponentMetaData.FireError(ERROR_IOMAP_ENTRY_ERROR, ComponentMetaData.Name, "One row of the Input-Output mapping is invalid: null or empty input field name. Please review IO configuration.", null, 0, out fireAgain); return(Microsoft.SqlServer.Dts.Pipeline.Wrapper.DTSValidationStatus.VS_ISBROKEN); } if (string.IsNullOrEmpty(e.OutputColName)) { ComponentMetaData.FireError(ERROR_IOMAP_ENTRY_ERROR, ComponentMetaData.Name, "One row of the Input-Output mapping is invalid: null or empty output field name. Please review IO configuration.", null, 0, out fireAgain); return(Microsoft.SqlServer.Dts.Pipeline.Wrapper.DTSValidationStatus.VS_ISBROKEN); } // Checks for unique cols foreach (IOMapEntry e1 in m.IoMap) { if (!ReferenceEquals(e, e1) && e.InputFieldPath == e1.InputFieldPath) { // Not unique! ComponentMetaData.FireError(ERROR_IOMAP_ENTRY_ERROR, ComponentMetaData.Name, "There are two or more rows with same InputFieldName. This is not allowed.", null, 0, out fireAgain); return(Microsoft.SqlServer.Dts.Pipeline.Wrapper.DTSValidationStatus.VS_ISBROKEN); } if (!ReferenceEquals(e, e1) && e.OutputColName == e1.OutputColName) { // Not unique! ComponentMetaData.FireError(ERROR_IOMAP_ENTRY_ERROR, ComponentMetaData.Name, "There are two or more rows with same OutputColName. This is not allowed.", null, 0, out fireAgain); return(Microsoft.SqlServer.Dts.Pipeline.Wrapper.DTSValidationStatus.VS_ISBROKEN); } } } // Controllo i parametri avanzati if (!string.IsNullOrEmpty(m.CustomLocalTempDir)) { // Give warning only if the user specified a custom value and that one is invalid if (!Directory.Exists(m.CustomLocalTempDir)) { ComponentMetaData.FireWarning(WARNING_CUSTOM_TEMP_DIR_INVALID, ComponentMetaData.Name, "The path to " + m.CustomLocalTempDir + " doesn't exists on this FS. If you're going to deploy the package on another server, make sure the path is correct and the service has write permission on it.", null, 0); return(Microsoft.SqlServer.Dts.Pipeline.Wrapper.DTSValidationStatus.VS_ISBROKEN); } } // Controllo che la colonna di input sia ancora valida bool found = false; if (String.IsNullOrEmpty(m.InputColumnName)) { ComponentMetaData.FireError(ERROR_INPUT_LANE_NOT_FOUND, ComponentMetaData.Name, "Input column has not been selected.", null, 0, out fireAgain); return(Microsoft.SqlServer.Dts.Pipeline.Wrapper.DTSValidationStatus.VS_ISBROKEN); } foreach (IDTSVirtualInputColumn100 vcol in ComponentMetaData.InputCollection[0].GetVirtualInput().VirtualInputColumnCollection) { if (vcol.Name == m.InputColumnName) { found = true; break; } } if (!found) { ComponentMetaData.FireError(ERROR_INPUT_LANE_NOT_FOUND, ComponentMetaData.Name, "Input column " + m.InputColumnName + " is not present among the inputs of this component. Please update the component configuration.", null, 0, out fireAgain); return(Microsoft.SqlServer.Dts.Pipeline.Wrapper.DTSValidationStatus.VS_ISBROKEN); } return(base.Validate()); }