/** * @param array $args this should have entries for * "config" and "operations" + other WSService constrctor arguments */ public function __construct($args) { // validating the user args if (!array_key_exists(DS_CONFIG, $args)) { DSUtils::error_log(__FILE__, __LINE__, "Configs are missing in the DataService constructor"); } if (!array_key_exists(DS_OPERATIONS, $args)) { DSUtils::error_log(__FILE__, __LINE__, "Operations are missing in the DataService constructor"); } // deriving operations for WSService constructor $wsservice_operatoins = array(); // build the operation array for the WSService constructor $args_ops = $args[DS_OPERATIONS]; foreach ($args_ops as $key => $value) { $wsservice_operations[$key] = $key; } // building the WSService construtor arguments $wsservice_args = array(DS_CLASSES => array(DS_PROCESSOR_HANDLER => array(DS_OPERATIONS => $wsservice_operations, DS_ARGS => array($args)))); /* put all the arguments except the operations and config as arguments for the WSConstructor */ foreach ($args as $args_key => $args_value) { if ($args_key != DS_OPERATIONS && $args_key != DS_CONFIG) { $wsservice_args[$args_key] = $args_value; } } $args_config = $args[DS_CONFIG]; $wsservice_args[DS_ANNOTATIONS] = $this->generate_annotations($args_ops, $args_config); // call the parent constructor parent::__construct($wsservice_args); }
/** * @param string $op_name, service opertion name * @param array $op_args, request message * @param returns the response */ public function __call($op_name, $op_args) { // extracting out the request message $req_msg = NULL; if (array_key_exists(0, $op_args)) { $req_msg = $op_args[0]; } if ($req_msg == NULL) { DSUtils::error_log(__FILE__, __LINE__, "Configs are missing in the DataService constructor"); throw new WSFault("Sender", "Failed in reading the request message"); } $req_msg_str = $req_msg->str; // extracting out the config and operation from theuser args $config = $this->args[DS_CONFIG]; $operations = $this->args[DS_OPERATIONS]; // extracting out the query information on current operation if (array_key_exists($op_name, $operations)) { $operation_query = $operations[$op_name]; } else { DSUtils::error_log(__FILE__, __LINE__, "current operation {$op_name} not in the user provided operations array"); throw new WSFault("Sender", "Operation {$op_name} not found"); } // create the database executor $dbe = new DSDBExecutor($config); // process the incomming message and operation query $ds_proc = new DSQueryProcessor($dbe, $operation_query); /* call the DSQueryProccessor with the configrations + incomming message*/ $response = $ds_proc->process_inmessage($req_msg_str, $operation_query, $dbe); return $response; }
/** * Handles the direct quires which doesn't requries prepared statments * * @param PDO object $dbh * @return array of response information */ private function handle_query($dbh, $sql_query) { //simple execute the query if ($stmt = $dbh->query($sql_query)) { $results = $stmt->fetchAll(); } else { DSUtils::error_log(__FILE__, __LINE__, "Error occured while setting the prepared statment: {$sql_query}"); throw new WSFault("Sender", "Failed in accessing database"); } return $results; }
/** * generate the output element * @param string $op_name operation name * @param array $query configurations to the operation * @param array $complex_types reference to where keeps the complex types * @param DSDBExecutor $dbe database executor * @return array corrosponding to the response element schema */ public function generate_output_element($op_name, $query, &$complex_types, $dbe) { $output_format = NULL; $input_format = NULL; $sql = NULL; if (array_key_exists(DS_OUTPUT_FORMAT, $query)) { $output_format = $query[DS_OUTPUT_FORMAT]; } else { DSUtils::error_log(__FILE__, __LINE__, "Required configuration output param is not found in" . print_r($query, TRUE) . " for {$op_name}"); echo "Error generating the wsdl"; exit(0); } if (array_key_exists(DS_SQL, $query)) { $sql = $query[DS_SQL]; } else { DSUtils::error_log(__FILE__, __LINE__, "Required configuration sql is not found in" . print_r($query, TRUE) . " for {$op_name}"); echo "Error generating the wsdl"; exit(0); } if (array_key_exists(DS_INPUT_FORMAT, $query)) { $input_format = $query[DS_INPUT_FORMAT]; } $result_element_name = NULL; $row_element_name = NULL; $use_nil = TRUE; $namespace = NULL; $column_default_behaviour = NULL; $elements = array(); $attributes = array(); $texts = array(); $queries = array(); $elements_order = NULL; if (array_key_exists(DS_RESULT_ELEMENT, $output_format)) { $result_element_name = $output_format[DS_RESULT_ELEMENT]; } else { $result_element_name = DS_DEFAULT_RESULT_ELEMENT; } if (array_key_exists(DS_ROW_ELEMENT, $output_format)) { $row_element_name = $output_format[DS_ROW_ELEMENT]; } else { $row_element_name = DS_DEFAULT_ROW_ELEMENT; } if (array_key_exists(DS_USE_NIL, $output_format)) { $use_nil = $output_format[DS_USE_NIL]; } if (array_key_exists(DS_DEFAULT_NAMESPACE, $output_format)) { $namespace = $output_format[DS_DEFAULT_NAMESPACE]; } else { $namespace = DS_RESPONSE_NS_DEFAULT_URI; } if (array_key_exists(DS_COLUMN_DEFAULT, $output_format)) { $column_default_behaviour = $output_format[DS_COLUMN_DEFAULT]; } else { $column_default_behaviour = DS_DEFAULT_COLUMN_DEFAULT; } if (array_key_exists(DS_ELEMENTS, $output_format)) { $elements = $output_format[DS_ELEMENTS]; } if (array_key_exists(DS_ATTRIBUTES, $output_format)) { $attributes = $output_format[DS_ATTRIBUTES]; } if (array_key_exists(DS_TEXTS, $output_format)) { $texts = $output_format[DS_TEXTS]; } if (array_key_exists(DS_QUERIES, $output_format)) { $queries = $output_format[DS_QUERIES]; } if (array_key_exists(DS_ELEMENTS_ORDER, $output_format)) { $elements_order = $output_format[DS_ELEMENTS_ORDER]; } // now we create the row element $row_element_type_name = $row_element_name . DS_WSDL_TYPE_POSTFIX; if ($use_nil) { $nillable = DS_WSDL_TRUE; } else { $nillable = DS_WSDL_FALSE; } // prepare the column to xsd map $column_to_xsd_map = array(); // first create the dummy params $dummy_params = $this->generate_dummy_params($input_format); // then fetch the column menta info $result_meta_info = $dbe->get_result_meta_info($sql, $dummy_params); // and fill the column to xsd foreach ($result_meta_info as $column_name => $php_type) { if (array_key_exists($php_type, $this->php_to_xsd_map)) { $column_to_xsd_map[$column_name] = $this->php_to_xsd_map[$php_type]; } else { $column_to_xsd_map[$column_name] = DS_XSD_ANY; } } // prepare the elements arr with all the elements $elements_arr = array(); // name to element map $name_to_element_map = array(); foreach ($elements as $element_name => $column_info) { $element_type = NULL; $xsd_type = NULL; if (is_array($column_info) && array_key_exists(DS_COLUMN_TYPE, $column_info)) { // first priority to the xsd_type $xsd_type = $column_info[DS_COLUMN_TYPE]; } else { if (!is_array($column_info) || array_key_exists(DS_COLUMN_NAME, $column_info)) { // second priority to the column name $column_name = NULL; if (is_array($column_info)) { $column_name = $column_info[DS_COLUMN_NAME]; } else { $column_name = $column_info; } if (array_key_exists($column_name, $column_to_xsd_map)) { $xsd_type = $column_to_xsd_map[$column_name]; } else { $xsd_type = DS_XSD_ANY; } } else { if (is_array($column_info) && array_key_exists(DS_COLUMN_PARAM, $column_info)) { // third check the RARAM column $param_name = $column_info[DS_COLUMN_PARAM]; if (array_key_exists($param_name, $input_format)) { $sql_type = $input_format[$param_name]; if (array_key_exists($sql_type, $this->sql_to_xsd_map)) { $xsd_type = $this->sql_to_xsd_map[$sql_type]; } else { $xsd_type = DS_XSD_ANY; } } else { $xsd_type = DS_XSD_ANY; } } else { $xsd_type = DS_XSD_ANY; } } } $current_element = array(DS_WSDL_NAME => $element_name, DS_WSDL_NAMESPACE => $namespace, DS_WSDL_TYPE => $xsd_type); $elements_arr[] = $current_element; $element_to_name_map[$element_name] = $current_element; } // derive the schema for queries foreach ($queries as $query_name => $nested_query) { $current_element = $this->generate_output_element($op_name, $nested_query, $complex_types, $dbe); $elements_arr[] = $current_element; $element_to_name_map[$query_name] = $current_element; } if ($elements_order) { $ordered_elements = array(); foreach ($elements_order as $element_name) { if (array_key_exists($element_name, $element_to_name_map)) { $ordered_elements[] = $element_to_name_map[$element_name]; } } } else { $ordered_elements = $elements_arr; } // now prepare the attributes // prepare the attributes arr with all the attributes $attributes_arr = array(); foreach ($attributes as $attribute_name => $column_info) { $attribute_type = NULL; $xsd_type = NULL; if (is_array($column_info) && array_key_exists(DS_COLUMN_TYPE, $column_info)) { // first priority to the xsd_type $xsd_type = $column_info[DS_COLUMN_TYPE]; } else { if (!is_array($column_info) || array_key_exists(DS_COLUMN_NAME, $column_info)) { // second priority to the column name $column_name = NULL; if (is_array($column_info)) { $column_name = $column_info[DS_COLUMN_NAME]; } else { $column_name = $column_info; } if (array_key_exists($column_name, $column_to_xsd_map)) { $xsd_type = $column_to_xsd_map[$column_name]; } else { $xsd_type = DS_XSD_ANY; } } else { if (is_array($column_info) && array_key_exists(DS_COLUMN_PARAM, $column_info)) { // third check the RARAM column $param_name = $column_info[DS_COLUMN_PARAM]; if (array_key_exists($param_name, $input_format)) { $sql_type = $input_format[$param_name]; if (array_key_exists($sql_type, $this->sql_to_xsd_map)) { $xsd_type = $this->sql_to_xsd_map[$sql_type]; } else { $xsd_type = DS_XSD_ANY; } } else { $xsd_type = DS_XSD_ANY; } } else { $xsd_type = DS_XSD_ANY; } } } $current_attribute = array(DS_WSDL_NAME => $attribute_name, DS_WSDL_NAMESPACE => $namespace, DS_WSDL_TYPE => $xsd_type); $attributes_arr[] = $current_attribute; } // prepare the row element $row_element = array(DS_WSDL_NAME => $row_element_name, DS_WSDL_NAMESPACE => $namespace, DS_WSDL_NILLABLE => $nillable, DS_WSDL_MIN_OCCURS => 0, DS_WSDL_MAX_OCCURS => DS_WSDL_UNBOUNDED, DS_WSDL_TYPE => $row_element_type_name); $row_element_type = array(DS_WSDL_NAME => $row_element_type_name, DS_WSDL_SEQUENCE => $ordered_elements, DS_WSDL_ATTRIBUTES => $attributes_arr, DS_WSDL_NAMESPACE => $namespace); // at the end create the wrapper element $result_element_type_name = $result_element_name . DS_WSDL_TYPE_POSTFIX; $result_element = array(DS_WSDL_NAME => $result_element_name, DS_WSDL_NAMESPACE => $namespace, DS_WSDL_TYPE => $result_element_type_name); $result_element_type = array(DS_WSDL_NAME => $result_element_type_name, DS_WSDL_SEQUENCE => array($row_element), DS_WSDL_NAMESPACE => $namespace); $this->add_complex_type($complex_types, $result_element_type); $this->add_complex_type($complex_types, $row_element_type); return $result_element; }
/** * build the reponse from the result set * * @param array $result_table array of the result set from DB Execution * @param array $output_format format of the output * @param array $input_param input param of the query context * @param DSDBExecutor object $dbe used for recursive query processing * @param DOMDocument $doc reponse document * @return DOMNode $parent the parent of the current response dom structure */ private function build_response($result_table, $output_format, $input_params, $dbe, $doc) { // extract the respones format in to variables $result_element_name = NULL; $row_element_name = NULL; $use_nil = TRUE; $namespace = NULL; $column_default_behaviour = NULL; $elements = array(); $attributes = array(); $texts = array(); $queries = array(); $elements_order = NULL; if (array_key_exists(DS_RESULT_ELEMENT, $output_format)) { $result_element_name = $output_format[DS_RESULT_ELEMENT]; } else { $result_element_name = DS_DEFAULT_RESULT_ELEMENT; } if (array_key_exists(DS_ROW_ELEMENT, $output_format)) { $row_element_name = $output_format[DS_ROW_ELEMENT]; } else { $row_element_name = DS_DEFAULT_ROW_ELEMENT; } if (array_key_exists(DS_USE_NIL, $output_format)) { $use_nil = $output_format[DS_USE_NIL]; } if (array_key_exists(DS_DEFAULT_NAMESPACE, $output_format)) { $namespace = $output_format[DS_DEFAULT_NAMESPACE]; } else { $namespace = DS_RESPONSE_NS_DEFAULT_URI; } if (array_key_exists(DS_COLUMN_DEFAULT, $output_format)) { $column_default_behaviour = $output_format[DS_COLUMN_DEFAULT]; } else { $column_default_behaviour = DS_DEFAULT_COLUMN_DEFAULT; } if (array_key_exists(DS_ELEMENTS, $output_format)) { $elements = $output_format[DS_ELEMENTS]; } if (array_key_exists(DS_ATTRIBUTES, $output_format)) { $attributes = $output_format[DS_ATTRIBUTES]; } if (array_key_exists(DS_TEXTS, $output_format)) { $texts = $output_format[DS_TEXTS]; } if (array_key_exists(DS_QUERIES, $output_format)) { $queries = $output_format[DS_QUERIES]; } if (array_key_exists(DS_ELEMENTS_ORDER, $output_format)) { $elements_order = $output_format[DS_ELEMENTS_ORDER]; } $result_element = $doc->createElementNS($namespace, $result_element_name); // iterate throught all the rows of the result table foreach ($result_table as $result_row) { $row_element = $doc->createElementNS($namespace, $row_element_name); $result_element->appendChild($row_element); // we first save all the column elements in an array $column_results_arr = array(); // first iterate all the elements foreach ($elements as $element_name => $column_info) { $column_value = $this->infer_column_value($column_info, $result_row, $input_params); if ($column_value === NULL && !$use_nil) { DSUtils::error_log(__FILE__, __LINE__, "{$element_name} is NULL" . "It should not be null"); throw new WSFault("Sender", "Non nillable {$element_name} element is NULL"); } // create an element and save it $column_element = $doc->createElementNS($namespace, $element_name); $text_node = new DOMText($column_value); $column_element->appendChild($text_node); $column_results_arr[$element_name] = $column_element; } // second iterate all the attributes foreach ($attributes as $attribute_name => $column_info) { $column_value = $this->infer_column_value($column_info, $result_row, $input_params); if ($column_value === NULL && !$use_nil) { DSUtils::error_log(__FILE__, __LINE__, "{$column_name} is NULL" . "It should not be null"); throw new WSFault("Sender", "Non nillable result attribute is NULL"); } // create an attribute and save it $column_attribute = new DOMAttr($attribute_name, $column_value); $column_results_arr[$attribute_name] = $column_attribute; } // third iterate through all the texts foreach ($texts as $text_id => $column_info) { $column_value = $this->infer_column_value($column_info, $result_row, $input_params); if ($column_value === NULL && !$use_nil) { DSUtils::error_log(__FILE__, __LINE__, "{$column_name} is NULL" . "It should not be null"); throw new WSFault("Sender", "Non nillable result text is NULL"); } // create an text and save it $column_text = $doc->createTextNode($column_value); $column_results_arr[$text_id] = $column_text; } // build the new merged input params $merged_input_params = array_merge($input_params, $result_row); // forth iterate through quiries foreach ($queries as $query_id => $query_info) { $query_result_element = $this->process_query($merged_input_params, $query_info, $dbe, $doc); $column_results_arr[$query_id] = $query_result_element; } // now check whether the order is provided if ($elements_order && is_array($elements_order)) { //if provided render it in the order provided by that, foreach ($elements_order as $next_name) { if (array_key_exists($next_name, $column_results_arr)) { $next_element = $column_results_arr[$next_name]; $row_element->appendChild($next_element); } else { DSUtils::error_log(__FILE__, __LINE__, "{$next_name} in elementsOrder " . "is non identified"); throw new WSFault("Sender", "Failed loading configurations"); } } } else { //if not just render it in the order it is placed foreach ($column_results_arr as $result_id => $column_element) { $row_element->appendChild($column_element); } } } return $result_element; }