Wednesday, May 30, 2012

Coldfusion, SOAP headers and custom namespaces

Some webservices require you to add specific headers to your request (i.e. for authentication). In the CFML reference you can find a function AddSOAPRequestHeader which can do this for you. The problem is that the documentation is not always very clear about HOW you should use this.
My problem was that the header should use some custom namespaces and some default namespaces, here is how you should do this.
My SOAP header should look like this:

<soapenv:header>
<ws:authenticationheader>
<username>[username here]</username>
<password>[password here]</password>
</ws:authenticationheader>
</soapenv:header>

There is a namespace "ws" defined in the soapenv:Envelope pointing to a custom namespace. It is still (as far as I could research) impossible to define this in the soapenv. Second best is to define this in the header itself.

XmlHeader = XmlNew();
XmlHeader.xmlRoot = XmlElemNew(XmlHeader,"http://www.url-to-ns","ws:AuthenticationHeader");
XmlHeader.xmlRoot.XmlChildren[1] = XmlElemNew(XmlHeader,"","username");
XmlHeader.xmlRoot.XmlChildren[2] = XmlElemNew(XmlHeader,"","password");
XmlHeader.xmlRoot.username.XmlText = "[username here];
XmlHeader.xmlRoot. username .XmlAttributes['xsi:type'] = "xsd:string";
XmlHeader.xmlRoot.Password.XmlText = "[password here]";
XmlHeader.xmlRoot.Password.XmlAttributes['xsi:type'] = "xsd:string";
AddSOAPRequestHeader(varnameOfWS," http://www.url-to-ns ","ws:AuthenticationHeader",XmlHeader,false);
result = varnameOfWS.doSomething();

From the CF documentation:
XmlElemNew(xmlObj[, namespace], childName)
The trick is to add the namespace alias to childName parameter using the format "[alias]:childname", the namespace alias then is automatically added.

Here is the soap header using soap_req = getSOAPRequest(varnameOfWS);


<soapenv:Header>
<ws:AuthenticationHeader 
soapenv:actor="" 
soapenv:mustUnderstand="0" 
xmlns:ws="http://www.url-to-ns">
<username xmlns="" xsi:type="xsd:string">[username here]</username>
<password xmlns="" xsi:type="xsd:string">[password here]</password>
</ws:AuthenticationHeader>
</soapenv:Header>


The namespace definition is valid for the web service which was my goal. I would rather see the definition in the soapenv:Envelope so if anyone knows how to do this please let me know! :)

Wednesday, April 4, 2012

A pinout database of any plug

This is a great initiative: http://pinouts.ru/
I have an old computer power supply lying around which I want to repurpose for a DIY electronics project. But which pin is what? I can try my volt meter on every pin, but using this site is much easier!

This site contains a database with more than 1400 descriptions of hardware pinouts, cables, connectors and even some schemes. Everything is nicely categorized and searchable. You can even submit your own pinouts if you think something is missing!

Thursday, May 5, 2011

Install Flash builder 4.5 standalone as an Eclipse plugin

I noticed that there is no download link for the Flash Builder 4.5 Eclipse plugin as it exists with version 4. It seems that a separate plugin installer is no longer necessary.
Here are the steps:
1. Install the standalone version.
2. Go to the program folder of Flash builder 4.5 (program files\Adobe\Adobe Flash Builder 4.5)
3. Then go to the folder "utilities" and execute "Adobe Flash Builder 4.5 Plug-in Utility"
4. Point the installer to your Eclipse folder

Next, next, OK, next, next, done!

Friday, March 18, 2011

ColdFusion queries and SQL comment

Here's one problem I experienced using a query in ColdFusion which was working perfectly in SQL server manager, but refused to work in ColdFusion.
The query was something like:

SELECT * --some comment
FROM users
WHERE user_id = 1

The query would only work if the comment is removed. The source of the problem is that ColdFusion removes all the line breaks in a query before executing. In this case only "SELECT *" would be executed which results (luckily) in a SQL error.
Good to know this before I tried the following query:

DELETE
FROM users --some comment
WHERE user_id = 1

Note: Normally you would use a SQL param and replace it with queryService.addParam(), this would result in an error because the param could not be found.

To work around this problem use /* and */ for SQL comment, or strip all your comments in SQL if you execute it through ColdFusion.

Tuesday, August 31, 2010

Modifying a column in SQL manager, the right way

If you have a column of a table that needs to be changed, don't always go to the modify table page in SQL manager to do your changes. I tried something simple as increasing the column size of a nvarchar field, but the update kept on giving timeouts in the SQL manager. Then I tried the generate SQL script button to see what SQL manager was trying to do. The contents gave me an idea why I was getting timeouts:
-alter the table:
-drop constraints
-drop triggers
-create temporary table with new column sizes/fields
-add defaults from table to temp table
-add constraints from table to temp table
-add index to temp table
-insert all values from original table to temp table
-drop relationships from original table
-drop original table
-rename temp table name to original table name
-add relationships to temp table

Which it needed to do is:
ALTER TABLE sometablename
ALTER COLUMN somecolumnname
nvarchar(100) NULL;

Next time if I modify a table with much data, or a lot of relationships and/or constraints I will stay clear of the SQL manager "modify table" dialog.

Tuesday, August 3, 2010

Query of queries weirdness

I was playing around with the query service object when I found some strange behavour. It looks like there is a differency between the query object and the QueryNew() object.
See the test case below:


//test case for query of queries usings querynew and query object:

//Make query object with queryNew()
qUsers = queryNew("usename,userID","varChar,integer");
queryAddRow(qUsers);
querySetCell(qUsers,"usename","Jorrit");
querySetCell(qUsers,"userID",1);
queryAddRow(qUsers);
querySetCell(qUsers,"usename","Ben");
querySetCell(qUsers,"userID",2);
queryAddRow(qUsers);
querySetCell(qUsers,"usename","Tom");
querySetCell(qUsers,"userID",3);

writeDump(qUsers);

queryService = new Query();
//queryService.setName("qGetUserByID");
queryService.setDBType("query");
queryService.addParam(name="userID", cfsqltype="cf_sql_integer", value="1");
SaveContent variable="queryBody" {
WriteOutput("SELECT userID, usename ");
WriteOutput("FROM qUsers ");
WriteOutput("WHERE userID = :userID ");
}
queryService.setSql(queryBody);
test = queryService.execute();

writeDump(test);

/*
The code above will result in an error
Error Executing Database Query.

Query Of Queries runtime error.
Table named qUsers was not found in memory. The name is misspelled or the table is not defined.
*/

Monday, August 2, 2010

ColdFusion ignores typo in for loop statement

I was making a simple XML iteration in script using a for loop, but it only returned one element in stead of all the elements. In a further inspection I discovered a typo which was not reported by ColdFusion.
Here is the for loop:

for (sCount=1; sCount<+arrayLen(xmlSomething["anotherElement"]); sCount++){

}

The problem is the <+ operator which should be <=
But no error report, just the first element that is returned. I wonder why!