Using wso2, DSS version 3.01, I am trying to have an input parameter that could be an optional parameter. A user can say, give me all the info for this specific code, or if a user does not specify any code, I want to give all the rows of data. Can you help?
Instead of creating a query for each optional parameter, you can also do the following:
<query id="selectEmployees" useConfig="default">
<sql>select * from Employees where (:employeeNumber is null or employeeNumber = :employeeNumber)</sql>
<result element="employees" rowName="employee">
<element column="lastName" name="last-name" xsdType="string"/>
<element column="firstName" name="first-name" xsdType="string"/>
<element column="email" name="email" xsdType="string"/>
<element column="salary" name="salary" xsdType="double"/>
</result>
<param defaultValue="#{NULL}" name="employeeNumber" ordinal="1" paramType="SCALAR" sqlType="INTEGER" type="IN"/>
</query>
<operation name="getEmployees">
<call-query href="selectEmployees">
<with-param name="employeeNumber" query-param="employeeNumber"/>
</call-query>
</operation>
Now you can call 'getEmployees' with 'employeeNumber' and get specific employee,
or you can call 'getEmployees' without 'employeeNumber' and get all employees.
(Calling without 'employeeNumber' is by omitting the 'employeeNumber' tag, or using 'xsi:nil="true"'.)
Obviously, you cannot query for the value 'null' this way.
ok soo for example
<query id="employeesByNumberSQL" useConfig="default">
<sql>select * from Employees where employeeNumber = ?</sql>
<result element="employees" rowName="employee">
<element column="lastName" name="last-name" xsdType="string"/>
<element column="firstName" name="first-name" xsdType="string"/>
<element column="email" name="email" xsdType="string"/>
<element column="salary" name="salary" xsdType="double"/>
</result>
<param name="employeeNumber" ordinal="1" paramType="SCALAR" sqlType="INTEGER" type="IN"/>
select * from Employees
You have two queries employeesByNumberSQL, employeesByNumberSQL1 these two are mapped togetemployeesByNumber and getemployeesByNumber2
Well you can make input parameters optional by giving default values to the input parameters. For example
<query id="MyQ" useConfig="myDS">
<sql>select cust_id,name from customer where cust_id = ?</sql>
<result element="Entries" rowName="Entry">
<element column="cust_id" name="cust_id" xsdType="string"/>
<element column="name" name="name" xsdType="string"/>
</result>
<param defaultValue="1" name="cust_id" sqlType="INTEGER"/>
</query>
Here if you do not mention the input parameters it will take the input parameter as one. Or else you need to create two queries and handle them programmatically
Related
I don't know how to create a validator for 2 variables:
Q1. An user code that needs to be checked if exists prior to running the SQL query. I have an endpoint to check if the user code exists or not, how do I make it into a validator?
Q2. An array of dates, the best I could do was to use a pattern validator. I know there's also the possibility to set a parameter with paramType="array" and sqlType="date", but how can I configure this in the query parameters of the resource?
Please check the Data Service definition below:
<data name="APIDataService" serviceNamespace="" serviceGroup="" transports="http https local">
<description />
<config id="postgresDataService">
<property name="carbon_datasource_name">APIPostgres</property>
</config>
<!-- TODO: Q1. Here is the resource I want to use to validate the user code -->
<query id="validateUserCode" useConfig="postgresDataService">
<sql>
SELECT ( EXISTS ( SELECT 1
FROM user
WHERE code ILIKE :user_code ) )::INT AS does_user_exist
</sql>
<param name="user_code" sqlType="string" />
<result element="result">
<element column="does_user_exist" name="doesUserExist" xsdType="integer" />
</result>
</query>
<resource method="GET" path="validateUserCode">
<call-query href="validateUserCode">
<with-param name="user_code" query-param="user_code" />
</call-query>
</resource>
<query id="apiReportUserTotalEventsByDay" useConfig="postgresDataService">
<sql>
SELECT
calendar_date,
record_date,
user_code,
event_type_id,
event_count
FROM user_event
WHERE 1=1
AND calendar_date BETWEEN :calendar_date_start AND :calendar_date_end
AND record_date = ANY( ('{'||:record_date_array||'}')::DATE[] )
AND user_code = :user_code
</sql>
<!-- TODO: Q1. Here is the user code I want to validate -->
<param name="user_code" paramType="scalar" sqlType="string" />
<param name="calendar_date_start" paramType="scalar" sqlType="date" />
<param name="calendar_date_end" paramType="scalar" sqlType="date" />
<!-- TODO: Q2. Here is the array of date that I want to know
how I could convert into an paramType="array" sqlType="date" -->
<param name="record_date_array" paramType="scalar" sqlType="string" >
<validatePattern pattern="\s*\d{4}-\d{2}-\d{2}\s*(,\s*\d{4}-\d{2}-\d{2}\s*)*" />
</param>
<result element="result">
<element column="calendar_date" name="calendar_date" xsdType="string" />
<element column="record_date" name="record_date" xsdType="string" />
<element column="user_code" name="user_code" xsdType="string" />
<element column="event_type_id" name="event_type_id" xsdType="integer" />
<element column="event_count" name="event_count" xsdType="integer" />
</result>
</query>
<resource method="GET" path="apiReportUserTotalEventsByDay">
<call-query href="apiReportUserTotalEventsByDay">
<with-param name="user_code" query-param="user_code" />
<with-param name="calendar_date_start" query-param="calendar_date_start" />
<with-param name="calendar_date_end" query-param="calendar_date_end" />
<with-param name="record_date_array" query-param="record_date_array" />
</call-query>
</resource>
</data>
I followed following sample with one different i used MS SQL database.
http://wso2.com/library/tutorials/2013/11/scheduled-database-polling-with-wso2-data-services-server/
I am observing that polling is working as expected but timestamp (datetime column in sql is not getting updated)
Here is my DSS XML
<data enableBatchRequests="true" name="PollingService" serviceNamespace="http://ws.wso2.org/dataservice/samples/eventing_sample" transports="http https local">
<config enableOData="false" id="Default">
<property name="driverClassName">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
<property name="url">jdbc:sqlserver://geoshieldsp3\sqlexpress;databaseName=RahulTest</property>
<property name="username">sa</property>
<property name="password">CSSL#2014</property>
</config>
<query id="pollingQuery" output-event-trigger="pollingTrigger" useConfig="Default">
<sql>select x.[Call Number], x.Priority, x.Call_Type, x.DispatchDate,y.total from CADFeeds as x left join
(select *,count([Call Number]) over() as total from CADFeeds ) as y on x.[Call Number]=y.[Call Number]
where x.DispatchDate > (select TIMESTAMP from Timestamp where id=1)</sql>
<result element="Calls" rowName="call">
<element column="Call Number" name="CallNumber" xsdType="string"/>
<element column="Priority" name="Priority" xsdType="float"/>
<element column="Call_Type" name="Call_Type" xsdType="string"/>
<element column="DispatchDate" name="DispatchDate" xsdType="string"/>
<element column="total" name="count" xsdType="integer"/>
</result>
</query>
<query id="UpdateTimeStamp" useConfig="Default">
<sql>update dbo.Timestamp set timestamp = GETDATE() where ID=1</sql>
<param name="timestamp" ordinal="2" sqlType="STRING"/>
</query>
<event-trigger id="pollingTrigger">
<expression>//*[local-name()='count' and namespace-uri()='http://ws.wso2.org/dataservice/samples/eventing_sample']>0</expression>
<target-topic>polling_Topic</target-topic>
<subscriptions>
<subscription>http://localhost:8280/services/PollingProxy</subscription>
</subscriptions>
</event-trigger>
<operation name="PollingOperation">
<call-query href="pollingQuery"/>
</operation>
<operation name="UpdateTimeStamp">
<call-query href="UpdateTimeStamp">
<with-param name="timestamp" query-param="timestamp"/>
</call-query>
</operation>
</data>
Here is the DB schema for timestamp table
CREATE TABLE [dbo].[Timestamp](
[ID] [int] NULL,
[timestamp] [datetime] NULL
) ON [PRIMARY]
I do not see anything in the log or command prompt related to timestamp update.
Any help is greatly appreciated.
Thanks,
Rahul
There seems to be a mismatch between the operation and the query.
For the below SQL, query param is not needed as there are no arguments supplied.
Please try the following.
<operation name="UpdateTimeStamp">
<call-query href="UpdateTimeStamp">
</call-query>
</operation>
<query id="UpdateTimeStamp" useConfig="Default">
<sql>update dbo.Timestamp set timestamp = GETDATE() where ID=1</sql>
</query>
I have created a simple Data Service using wso2 dss as follows.
Query : SELECT id, key, value, description FROM dbo.configs where key like '%:filter%'
Final XML :
<query id="select_all_configs_like_query" useConfig="default">
<sql>SELECT id, key, value, description FROM dbo.configs where key like '%:filter%' </sql>
<result element="configsCollection" rowName="configs">
<element column="id" name="id" xsdType="xs:integer"/>
<element column="key" name="key" xsdType="xs:string"/>
<element column="value" name="value" xsdType="xs:string"/>
<element column="description" name="description" xsdType="xs:string"/>
</result>
<param name="filter" sqlType="QUERY_STRING"/>
</query>
<operation name="select_all_configs_like_operation">
<call-query href="select_all_configs_like_query">
<with-param name="filter" query-param="filter"/>
</call-query>
</operation>
When I invoke the service it responds with an empty response. No Error on the console. Once I checked the database history, query is recorded as below
SELECT id, key, value, description FROM dbo.configs where key like '%:filter%'
Looks like parameter is not assigned to the actual query. Any Help?
You can use the Concat function within the SQL statement so for example CONCAT('%',:filter,'%')
I have a wso2esb4.8.1 with features for wso2DSS. i have generate web service inthis url:
http://ec2-54-221-93-14.compute-1.amazonaws.com:9764/services/wsuaecd?tryit#
this is the xml for the web service
<data name="wsuaecd" serviceNamespace="Wsuaecd">
<config id="default">
<property name="carbon_datasource_name">UAECD</property>
</config>
<query id="select_with_key_bd_direccion_uaecd_query" useConfig="default">
<sql>SELECT id_direccion, tipo_identificacion, identificacion, nombre_propietario, primer_apellido, segundo_apellido, direccion_real, cod_barrio, nombre_barrio, cod_localidad, nombre_localidad, cod_upz, nombre_upz, cod_estrato, chip FROM public.bd_direccion_uaecd WHERE id_direccion=?</sql>
<sql dialect="postgresql">SELECT id_direccion, tipo_identificacion, identificacion, nombre_propietario, primer_apellido, segundo_apellido, direccion_real, cod_barrio, nombre_barrio, cod_localidad, nombre_localidad, cod_upz, nombre_upz, cod_estrato, chip FROM public.bd_direccion_uaecd WHERE id_direccion=?</sql>
<result element="bd_direccion_uaecdCollection" rowName="bd_direccion_uaecd">
<element column="id_direccion" name="id_direccion" xsdType="xs:long"/>
<element column="tipo_identificacion" name="tipo_identificacion" xsdType="xs:string"/>
<element column="identificacion" name="identificacion" xsdType="xs:string"/>
<element column="nombre_propietario" name="nombre_propietario" xsdType="xs:string"/>
<element column="primer_apellido" name="primer_apellido" xsdType="xs:string"/>
<element column="segundo_apellido" name="segundo_apellido" xsdType="xs:string"/>
<element column="direccion_real" name="direccion_real" xsdType="xs:string"/>
<element column="cod_barrio" name="cod_barrio" xsdType="xs:string"/>
<element column="nombre_barrio" name="nombre_barrio" xsdType="xs:string"/>
<element column="cod_localidad" name="cod_localidad" xsdType="xs:long"/>
<element column="nombre_localidad" name="nombre_localidad" xsdType="xs:string"/>
<element column="cod_upz" name="cod_upz" xsdType="xs:string"/>
<element column="nombre_upz" name="nombre_upz" xsdType="xs:string"/>
<element column="cod_estrato" name="cod_estrato" xsdType="xs:long"/>
<element column="chip" name="chip" xsdType="xs:string"/>
</result>
<param name="id_direccion" ordinal="1" sqlType="BIGINT"/>
</query>
<query id="select_all_bd_direccion_uaecd_query" useConfig="default">
<sql>SELECT id_direccion, tipo_identificacion, identificacion, nombre_propietario, primer_apellido, segundo_apellido, direccion_real, cod_barrio, nombre_barrio, cod_localidad, nombre_localidad, cod_upz, nombre_upz, cod_estrato, chip FROM public.bd_direccion_uaecd</sql>
<properties>
<property name="forceJDBCBatchRequests">false</property>
<property name="maxRows">100</property>
</properties>
<sql dialect="postgresql">SELECT id_direccion, tipo_identificacion, identificacion, nombre_propietario, primer_apellido, segundo_apellido, direccion_real, cod_barrio, nombre_barrio, cod_localidad, nombre_localidad, cod_upz, nombre_upz, cod_estrato, chip FROM public.bd_direccion_uaecd</sql>
<result element="bd_direccion_uaecdCollection" rowName="bd_direccion_uaecd">
<element column="id_direccion" name="id_direccion" xsdType="xs:long"/>
<element column="tipo_identificacion" name="tipo_identificacion" xsdType="xs:string"/>
<element column="identificacion" name="identificacion" xsdType="xs:string"/>
<element column="nombre_propietario" name="nombre_propietario" xsdType="xs:string"/>
<element column="primer_apellido" name="primer_apellido" xsdType="xs:string"/>
<element column="segundo_apellido" name="segundo_apellido" xsdType="xs:string"/>
<element column="direccion_real" name="direccion_real" xsdType="xs:string"/>
<element column="cod_barrio" name="cod_barrio" xsdType="xs:string"/>
<element column="nombre_barrio" name="nombre_barrio" xsdType="xs:string"/>
<element column="cod_localidad" name="cod_localidad" xsdType="xs:long"/>
<element column="nombre_localidad" name="nombre_localidad" xsdType="xs:string"/>
<element column="cod_upz" name="cod_upz" xsdType="xs:string"/>
<element column="nombre_upz" name="nombre_upz" xsdType="xs:string"/>
<element column="cod_estrato" name="cod_estrato" xsdType="xs:long"/>
<element column="chip" name="chip" xsdType="xs:string"/>
</result>
</query>
<operation name="select_with_key_bd_direccion_uaecd_operation">
<call-query href="select_with_key_bd_direccion_uaecd_query">
<with-param name="id_direccion" query-param="id_direccion"/>
</call-query>
</operation>
<operation name="select_all_bd_direccion_uaecd_operation">
<call-query href="select_all_bd_direccion_uaecd_query"/>
</operation>
</data>
The response for the queries with parameters is:
<axis2ns104:DataServiceFault xmlns:axis2ns104="http://ws.wso2.org/dataservice">DS Fault Message: Error in 'CallQuery.extractParams', cannot find parameter with type:query-param name:id_direccion
</axis2ns104:DataServiceFault>
does anyone has thesame issue? ithink is related with the configuration, but im pretty new in wso2 .
thanks in advanced.
Your question feels similiar to my question.
Data Service fails when deployed with ESB
If our questions are the same then you will be able to solve your problem by simply using DSS and not ESB together.
Create an instance with DSS only and verify this resolves your issue.
i'm using wso2esb4.7.0 and wso2dss 3.1.0.My proxy service in esb allows to retrieve the perticular no of records from database.For that i have to use limit and offset in the query which is written in wso2dss.The query is as follows :
<sql>SELECT firstname, lastname FROM public.testlogin limit 5 offset ?</sql>
As per above query i have set the limit in query but offset is provded by client in request.My requirement is i have to retrieve the 5 records from offset of client requestNoq question is..How should i retrieve the offset which is in the client request.client request is as follows :
LogMediator To: /services/GetTaskDetails, MessageID: urn:uuid:caeaaebb-2239-4639-b1a2-094c22650de0, Direction: request, StartRecord = 6 Envelope: . . . .
here StartRecord is the offset in above request and i wanted to set it as offset in wso2 dss query please suggest something..
The query should work with the query and operation defined as follows:
`
<query id="SELECT" useConfig="MyDataSource">
<sql> SELECT firstname, lastname FROM public.testlogin limit 5 offset ? ;</sql>
<result element="patients" rowName="patient">
<element column="firstname" name="firstname" xsdType="string"/>
<element column="lastname" name="lastname" xsdType="string"/>
</result>
<param name="offset" optional="false" sqlType="INTEGER"/>
</query>
<operation name="getPatients">
<call-query href="SELECT">
<with-param name="offset" query-param="offset"/>
</call-query>
</operation>
`
You can modify the 'query' section in your dbs to set a input param. See the below example. It has a param name as employeeNumber. Which means, data services server will pickup the employeeNumber parameter from the SOAP request. You can modify appropriately. If there are more than one variable (ie. '?' symbols), then the ordering of the param is important.
The complete dbs sample can be found here in RDBMSSample.dbs.
<query id="employeesByNumberSQL" useConfig="default">
<sql>select * from Employees where employeeNumber = ?</sql>
<result element="employees" rowName="employee">
<element column="lastName" name="last-name" xsdType="string"/>
<element column="firstName" name="first-name" xsdType="string"/>
<element column="email" name="email" xsdType="string"/>
<element column="salary" name="salary" xsdType="double"/>
</result>
<param name="employeeNumber" ordinal="1" paramType="SCALAR" sqlType="INTEGER" type="IN"/>
</query>