I am using eclipse.persistence.logging to log SQL queries. I want to bind the parameters into the query on the right place where they belong, so I could just copy+paste from log file into database development environment and run that query. For example I want "SELECT * FROM table WHERE id = 5" instead of "SELECT * FROM table WHERE id = ? bind => [5]" to be logged.
In the persistance.xml I have these properties already:
<property name="eclipselink.logging.level.sql" value="FINE"/>
<property name="eclipselink.logging.parameters" value="true"/>
<property name="eclipselink.logging.logger" value=my cutom logger class/>
And I made a custom logger class to override method public void log(SessionLogEntry logEntry), where I am replacing the '?' with parameters from the 'bind => [...]' part of the message using regex and string functions.
It all works fine but I have one problem, which I don't know how to solve.
Parameters in the '[...]' are separated by comma, so when I split the '[...]' part by commas to get an array of parameters, the string/varchar parameters containing commas mess up the whole thing and are splitted into multiple parts by those commas. The parameters are not quoted to mark the start and the end of the string/varchar parameter, so I don't see any solution to prevent the splitting.
At first I thought the parameters for the message would be accesible by getParameters() method of SessionLogEntry class and easier to handle, but this method returns null and the parameters are only in the message, therefore I used the regex and string functions.
Can anyone help me with this? Is there any other way to achieve the result?
Related
I am trying to get specific data between two strings which are a opening and closing tag. Normally I would just parse it using XmlParse but the problem is it has a lot of other junk in the dataset.
Here is an example of the large string:
test of data need to parse:<?xml version="1.0" encoding="UTF-8"?><alert xmlns="urn:oasis:names:tc::cap:1.2"><identifier>_2020-12-16T17:32:5620201116173256</identifier><sender>683</sender><sent>2020-12-16T17:32:56-05:00</sent><status>Test</status><msgType>Alert</msgType><source>test of data need to parse</source><scope>Public</scope><addresses/><code>Test1.0</code><note>WENS IPAWS</note><info><language>en-US</language></info>
<capsig:Signature xmlns:capsig="http://www.w3.org/2000/09/xmldsig">
<capsig:Info>
<capsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n"/>
<capsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-morersa-sha256"/>
<capsig:Referrer URI="">
<capsig:Trans>
<capsig:Trans Algorithm="http://www.w3.org/2000/09/xmldsigenveloped-signature"/>
</capsig:Trans>
<capsig:DMethod Algorithm="http://www.w3.org/2001/04/xmlencsha256"/>
<capsig:DigestValue>wjL4tqltJY7m/4=</capsig:DigestValue>
</capsig:Referrer>
</capsig:Info>
test of data need to parse:<?xml version="1.0" encoding="UTF-8"?><alert xmlns="urn:oasis:names:tc::cap:1.2"><identifier>_2020-12-16T17:32:5620201116173256</identifier><sender>683</sender><sent>2020-12-16T17:32:56-05:00</sent><status>Test</status><msgType>Alert</msgType><source>test of data need to parse</source><scope>Public</scope><addresses/><code>Test1.0</code><note>WENS IPAWS</note><info><language>en-US</language></info>
So what I need to do is just extract the following:
<capsig:Info>
<capsig:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n"/>
<capsig:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-morersa-sha256"/>
<capsig:Referrer URL="">
<capsig:Trans>
<capsig:Trans Algorithm="http://www.w3.org/2000/09/xmldsigenveloped-signature"/>
</capsig:Trans>
<capsig:DMethod Algorithm="http://www.w3.org/2001/04/xmlencsha256"/>
<capsig:DigestValue>wjL4tqltJY7m/4=</capsig:DigestValue>
</capsig:Referrer>
</capsig:Info>
I have searched everywhere and I have found where things can be done with characters and counts but none of them really worked. Tried doing it with SQL but because the constant change in the string it causes issues. So my plan was get everything after "capsig:Info" and before "</capsig:Info>" then insert it into a table.
Is there a way to do this with Coldfusion?
Any suggestions would be appreciated.
Thanks!
Yes, you can use a regular expression match to extract the substring containing the text between the <capsig:Info> ... </capsig:Info> tags by using the ColdFusion function reMatch() which will return an array of all substrings that match the specified pattern. This can be done using the line of code below.
<!--- Use reMatch to extract all pattern matches into an array --->
<cfset parsedXml = reMatch("<capsig:Info>(.*?)</capsig:Info>", xmlToParse)>
<!--- parsedXml is an array of strings. The result will be found in the first array element as such --->
<cfdump var="#parsedXml[1]#" label="parsedXml">
You can see this using the demo here.
https://trycf.com/gist/00be732d93ef49b2427768e18e371527/lucee5?theme=monokai
I have run into an issue using attempting to add values from two different columns together in a query, namely that some of them contain numbers. This means that the built in Concat does not work as it requires strings or chars.
Considering how one can cast variables as other datatypes in SQL I don't see why I wouldn't be able to do that in Django.
cast(name as varchar(100))
I would assume that one would do it as follows in Django using the Concat function in combination with Cast.
queryset.annotate(new_col=Concat('existing_text_col', Cast('existing_integer_col', TextField())).get())
The above obviously does not work, so does anyone know how to actually do this?
The use case if anyone wonders are sending jenkins urls saved as fragments as a whole. So one url would be:
base_url: www.something.com/
url_fragment: name/
url_number: 123456
I ended up writing a serializer that inherits from the base serializer that contains the urls fragments and a lot of other things. In it I made a MethodField for my complete url and defined a getter function that loaded in the different fragments and added them together. I also redeclared the fragmented fields to None.
The code inside the new serializer is:
complete = serpy.MethodField("get_copmlete")
serverUrl = serpy.Field(attr=None, call=False, required=False)
jobName = serpy.Field(attr=None, call=False, required=False)
buildNumber = serpy.Field(attr=None, call=False, required=False)
def get_complete(self, obj):
return obj.server_url + obj.job_name + '/' + str(obj.build_number)
So, I have this select query below, which joins two tables and retrieves a String:
<select id =“getAppVerByConfId” parameterType=“java.lang.String” resultType=“java.lang.String”>
SELECT t.app_ver
FROM
application a
JOIN transaction t on t.txn_id = a.txn_id
WHERE
a.confirmation_id = #{0}
</select>
and then I used that as a template to write a 2nd query, which is nearly identical, but just retrieves a different parameter from the table.
<select id =“getStepNameByConfId” parameterType=“java.lang.String” resultType=“java.lang.String”>
SELECT t.step_name
FROM
application a
JOIN transaction t on t.txn_id = a.txn_id
WHERE
a.confirmation_id = #{0}
Both of these work fine on their own, and they're used at the same point in the program. But there's got to be a better way than this surely? I should be able to make the query once, and then map the results to what I want, correct? Should I make a resultset, and then be able to pull them out? Maybe as a HashMap and I can retrieve the values by keys? Is this a situation where I can USE the AS operator? i.e. "SELECT t.app_ver AS appVersion"? My thinking is that's for passing variables into the query, though, and not for getting them out?
If there's any thoughts on this I would love to hear them. I'm basically trying to combine these into one query, and I need to be able to retrieve the right value and not assign app_ver to step_name or vice versa.
Cheers
As you say it's not a bad idea use alias (t.app_ver as appVersion) in your select but it is just the name of the column which will be mapped. So in the case you use alias as next t.app_ver as appVersion, t.step_name as stepName your column names will be appVersion and stepName.
Then, to map your result you have multiple choices the idea to map it in a map structure is not a bad idea and it's easy, you just need to put your result type as hashmap, it will be something like that (and it's not need any Resultmap):
Hashmap
(Example in offical page)
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
The column will be the key and the row values the value in the map.
keyed by column names mapped to row values
So to get your values you will need to use the column name as key in the map:
String appVersionValue = map.get("appVersion");
Resultmap
Other way it to create a class with the properties you need to map and then create your resultmap.
A resultmap is defined as next:
resultMap – The most complicated and powerful element that describes
how to load your objects from the database result sets.
Your class would be like:
public class Application{
private String appVersion;
private String stepName;
//.... getters and setters
}
And your result map would map the column name with the class properties specifying the type with the class created for this (In this case is Application):
<resultMap id="applicationResultMap" type="Application">
<result property="appVersion" column="appVersion"/>
<result property="stepName" column="stepName"/>
</resultMap>
(Be careful, because in this example the columns and properties are called equal, there are cases where the column is called app_version and the property appVersion for example so there would be <result property="appVersion" column="app_version"/>
Finally in your select you specify to use this resultmap:
<select id="selectMethodName" resultMap="applicationResultMap">
select t.app_ver as appVersion, t.step_name as stepName
from your_table
</select>
I have JDBC where I'm calling the stored Procedure, It is returning the response as below, But I'm pretty not sure how to extract the value of result set
Please find the response from DB
{updateCount1=4,resultSet1=[{XML_F5RYI-11YTR=<Customers><Customer1>John<Customer1><Customer2>Ganesh<Customer2><Customers>}],resultSet2[{SequenceNumber=94}],updateCount2=1, updateCount3=4}
I have used the this expression #[message.payload.get(0)], It has return the ResultSet as below, But not exactly value required. I need to take the xml value of XML_F5RYI-11YTR.
{XML_F5RYI-11YTR=<Customers><Customer1>John<Customer1><Customer2>Ganesh<Customer2><Customers>}
Also tried like below
#[message.payload.get(0).XML_F5RYI-11YTR] but getting error , not able to extract the xml.
Could you please suggest how can I extract the xml from the ResultSet1
In most cases, the way you did it should work. I think what is happening here is that the hyphen in the column name is interpreted by the MEL parser as a subtraction. So you could change yours to this syntax, and it should work:
#[message.payload.get(0)['XML_F5RYI-11YTR']]
Also you can omit "message", as payload is resolvable directly:
#[payload.get(0)['XML_F5RYI-11YTR']]
You could use array bracket syntax to access the first row in the result set, instead of the get method:
#[payload[0]['XML_F5RYI-11YTR']]
Finally, you might want to do something for each row returned from the database. If you use a collection-splitter or a for-each, your payload will be the map that represents the row, instead of a list of maps representing the whole result set:
<collection-splitter />
<logger message="#[payload['XML_F5RYI-11YTR']]" />
EDIT
To access the result set in the payload shown in the question, you would need to access it like so:
#[payload.resultSet1[0]['XML_F5RYI-11YTR']]
The database connector gives you a list of maps. The map keys will be the name of the columns. Therefore if you want to get updateCount1, you can use something like this:
#[payload.get('updateCount1')]"
Thump rule - you database connector gives you list of map, not sure what format does it is carry, if you want XML_F5RYI.. value then do the below
[message.payload.get(0)] convert it to json or map from which #[message.payload.get("XML_F5RYI-11YTR")]
I am trying to setup a data-driven subscription and it works fine except when 2 of the parameters are set to take dynamic values instead of static ones.
The strucutre is basically
Param1 -> read from database
Param2 -> read from database
Param3s -> read from database
Param3 -> split Param3s (multivalued parameter, allowed values depend on Params 1 and 2)
Note that Param3 is a multi-value parameter and therefore it's value is populated by proxy from a string parameter (param3s) that is split.
The above does not work and gives the following error when saving the subscription
This report requires a default or user-defined value for the report parameter 'Param3'. To run or subscribe to this report, you must provide a parameter value. (rsReportParameterValueNotSet)
However, when setting Param1 and Param2 to static values it works.
There is nothing useful in the ReportServer logs to help in identifying what is going on.
Anyone have any clue??
Apparently all parameters need to have a default value set to them, otherwise it won't work.
I had parameters 1 and 2 set without the default values in the report so it didn't work.