Updating Oracle BLOBs with image files - oracle10g

This is what I am trying to do:
Read an image from the oracle BLOB
Resize it
Write the resized image back to the table(update the blob itself).
My table looks like this:
TECHID NOT NULL NUMBER(12)
MEDIADATA NOT NULL BLOB()
INSERTEDDATE NOT NULL DATE
MODIFIEDDATE NOT NULL DATE
Steps 1 and 2 work perfectly. The code for step 3 is as follows (this is a PoC type spike solution - not final production):
File resized = get the resized image
FileInputStream fis = new FileInputStream(resized)
PreparedStatement p = db.connection.prepareStatement("update mymediadata set mediadata = ? where TECHID=142")
if (fis != null)
{
println("Available: ${fis.available()}"); // this works - shows 117K bytes available.
}
p.setBinaryStream (1, fis, resized?.length()?.intValue())
try
{
p.executeUpdate()
}
catch (Exception e)
{
e.printStackTrace()
}
finally
{
p.close()
fis.close()
}
When I get to step 3, I get the following error:
SQLException: ORA-01407: cannot update ("OWNER"."MEDIADATA"."MEDIADATA") to NULL
I explicitly checked (in debugger) that the FileInputStream (fis) is not null. I also checked that the resized?.length()?.intValue() value is also > 0. So I am struggling to see what I might be doing wrong.
Technology stack:
Groovy GDK 1.7
Java 1.5
Oracle 10g
Running on 32 bit Windows XP.

OK, I finally managed to resolve this. It turns out it was a dodgy JDBC oracle driver (apparently an earlier version) which was causing the errors.
As soon as I switched to the proper version, the error vanished!

Related

HAPI v2 after terser: get entire changed message

I have an HL7 message whose content I'm manipulating slightly with the terser.set() method. Once I've done that, I see in the debugger that it's been changed just how I want it, but I can't seem to get the whole message back intact. I've tried (for example):
HapiContext context = new DefaultHapiContext();
Parser parser = context.getGenericParser();
Message message = parser.parse( MESSAGE );
Terser terser = new Terser( message );
terser.set( "/PID-2", "XXX XX XXXX" );
String fixedMessage = message.encode();
...which gets me close, however, lines (segment lines) that ended in just vertical bars (pipes) with no values in their fields come back trimmed (the vertical bars are simply dropped). I want the message to remain identical to what I put in (if also modified where I did it on purpose).
I think you need to use addForcedEncode in the ParserConfiguration.
Like
#Test
public void testSetManualRepetitions() {
try {
String m = "MSH|^~\\&|hl7Integration|hl7Integration|||||ADT^A01|||2.3|\r" +
"EVN|A01|20130617154644\r" +
"PID|1|465 306 5961||407623|Wood^Patrick^^^MR||19700101|1||||||||||\r" +
"PV1|1||Location||||||||||||||||261938_6_201306171546|||||||||||||||||||||||||20130617134644|||||||||";
HapiContext hc = new DefaultHapiContext();
ExecutorService es = hc.getExecutorService(); // to avoid npe when closing context should be fixed https://sourceforge.net/p/hl7api/bugs/223/
ParserConfiguration pc = hc.getParserConfiguration();
PipeParser pipeParser = hc.getPipeParser();
Message message = pipeParser.parse(m);
Terser terser = new Terser(message);
//Add first Address
terser.set("/.PID-11(0)-1", "13 Oxford Road");
terser.set("/.PID-11(0)-3", "Oxford");
//Add second Address
terser.set("/.PID-11(1)-1", "16 London Road");
terser.set("/.PID-11(1)-3", "London");
pc.addForcedEncode("PID-26-1"); // make sure PID has 26 fields
System.out.println(message.encode().replaceAll("\r", "\r\n"));
hc.close();
} catch (HL7Exception e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
yields:
/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/bin/java -ea -Didea.launcher.port=7540 "-Didea.launcher.bin.path=/Applications/IntelliJ IDEA CE.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar:/Applications/IntelliJ IDEA CE.app/Contents/plugins/junit/lib/junit-rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/lib/tools.jar:/Users/thomas/git/Hapi-HL7-Terser/target/test-classes:/Users/thomas/.m2/repository/junit/junit/4.4/junit-4.4.jar:/Users/thomas/.m2/repository/ca/uhn/hapi/hapi-base/2.2/hapi-base-2.2.jar:/Users/thomas/.m2/repository/ca/uhn/hapi/hapi-structures-v21/2.2/hapi-structures-v21-2.2.jar:/Users/thomas/.m2/repository/ca/uhn/hapi/hapi-structures-v23/2.2/hapi-structures-v23-2.2.jar:/Users/thomas/.m2/repository/ca/uhn/hapi/hapi-structures-v24/2.2/hapi-structures-v24-2.2.jar:/Users/thomas/.m2/repository/ca/uhn/hapi/hapi-structures-v25/2.2/hapi-structures-v25-2.2.jar:/Users/thomas/.m2/repository/org/slf4j/slf4j-simple/1.6.0/slf4j-simple-1.6.0.jar:/Users/thomas/.m2/repository/org/slf4j/slf4j-api/1.6.0/slf4j-api-1.6.0.jar:/Users/thomas/.m2/repository/org/slf4j/log4j-over-slf4j/1.6.2/log4j-over-slf4j-1.6.2.jar" com.intellij.rt.execution.application.AppMain com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 com.hl7integration.hapi.tests.SetRepetitionsTerserTest,testSetManualRepetitions
68 [main] INFO ca.uhn.hl7v2.util.Home - hapi.home is set to /Users/thomas/git/Hapi-HL7-Terser/.
170 [main] INFO ca.uhn.hl7v2.VersionLogger - HAPI version is: 2.2
197 [main] INFO ca.uhn.hl7v2.VersionLogger - Default Structure libraries found for HL7 versions 2.1, 2.3, 2.4, 2.5,
MSH|^~\&|hl7Integration|hl7Integration|||||ADT^A01|||2.3
EVN|A01|20130617154644
PID|1|465 306 5961||407623|Wood^Patrick^^^MR||19700101|1|||13 Oxford Road^^Oxford~16 London Road^^London|||||||||||||||
PV1|1||Location||||||||||||||||261938_6_201306171546|||||||||||||||||||||||||20130617134644
Technically you are not changing the message, you parse it to a Java object and encode it back to string. So that your output message looks like your input message. There could still be subtle differences afterwards (e.g. if your input message is dynamic).
From the docs (http://hl7api.sourceforge.net/configuring_hapi.html):
Forced Encoding
By default, when encoding a message HAPI will not encode any segments or fields that have no content and therefore have no semantic meaning in the message.
This can cause problems if you need to transmit a message to a system that expects certain empty content to be present in order to get "hints" about where in the message it is.
The addForcedEncode method may be used to add Terser paths which should be forced to be encoded:
parser.getParserConfiguration().addForcedEncode("PATIENT_RESULT/ORDER_OBSERVATION/ORC-4");
// ORC-4 will still exist (but be empty) even if ORC has no content
String encoded = parser.encode(message);
See the JavaDoc for examples.

Error reading from an IP-Camera

I capture the image from an IP-Camera and I work with the frames. My programm reads when there is a movement, and then, it makes a photo and save it on the computer.
It works perfectly at first, but when it is running like 2-3 hours, it usually get an error, and I do not find a explanation for this. Because, if it is an error on getting the image or the processing, it should happens since first, shouldn't it?
The error I get is the next:
Exception in thread "main" java.lang.NullPointerException
at com.googlecode.javacv.IPCameraFrameGrabber.grab(IPCameraFrameGrabber.java:105)
at Llamada.main(Llamada.java:34)
I have looked for the error nÂș105 but I have not found anything.
The program is the next:
public class Llamada {
public static void main(String[] args) throws Exception {
IPCameraFrameGrabber grabber = new IPCameraFrameGrabber("http://192.168.2.102:80/mjpg/video.mjpg");
//OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
grabber.start();
IplImage frame = grabber.grab();
IplImage image = null;
IplImage prevImage = null;
IplImage diff = null;
Date data = new Date();
String output = "";
int i=0, j=0;
CanvasFrame canvasFrame = new CanvasFrame("IP Camera");
canvasFrame.setCanvasSize(frame.width(), frame.height());
CvMemStorage storage = CvMemStorage.create();
while (canvasFrame.isVisible() && (frame = grabber.grab()) != null) {
cvSmooth(frame, frame, CV_GAUSSIAN, 9, 9, 2, 2);
if (image == null) {
image = IplImage.create(frame.width(), frame.height(), IPL_DEPTH_8U, 1);
cvCvtColor(frame, image, CV_RGB2GRAY);
} else {
prevImage = IplImage.create(frame.width(), frame.height(), IPL_DEPTH_8U, 1);
prevImage = image;
image = IplImage.create(frame.width(), frame.height(), IPL_DEPTH_8U, 1);
cvCvtColor(frame, image, CV_RGB2GRAY);
}
if (diff == null) {
diff = IplImage.create(frame.width(), frame.height(), IPL_DEPTH_8U, 1);
}
if (prevImage != null) {
// perform ABS difference
cvAbsDiff(image, prevImage, diff);
// do some threshold for wipe away useless details
cvThreshold(diff, diff, 64, 255, CV_THRESH_BINARY);
canvasFrame.showImage(diff);
// recognize contours
CvSeq contour = new CvSeq(null);
cvFindContours(diff, storage, contour, Loader.sizeof(CvContour.class), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
while (contour != null && !contour.isNull()) {
if (contour.elem_size() > 0) {
output = data.toString();
if (data != null)
output = output.substring(0,10);
if(i%300 == 0)
cvSaveImage((j++)+" "+ output +"-capture.jpg", frame);
CvBox2D box = cvMinAreaRect2(contour, storage);
// test intersection
if (box != null) {
CvPoint2D32f center = box.center();
CvSize2D32f size = box.size();
}
i++;
}
contour = contour.h_next();
}
}
}
grabber.stop();
canvasFrame.dispose();
}
}
Thank you for everything!
Have you tried using a debugger and setting a break point? I understand that waiting around for 2-3 hours isn't fun, but maybe it'd help you get a handle on what's going on.
That seems to be in your while loop's second conditional part. Something inside the method grab on the grabber object is throwing a NullPointerException.
Probably the way you've initialized the grabber has led it to do this.
And it would be useful to know which version of the IPCameraFrameGrabber class you're using and what the author of that class really expected. Namely it's initialized to respond to a particular camera's url. In reading the class, it would appear this makes no claim to work with all IP cameras' MJPEG streams.
Let's look at one example comment in there:
foscam url http://host/videostream.cgi?user=username&pwd=password
http://192.168.0.59:60/videostream.cgi?user=admin&pwd=password
android ipcam http://192.168.0.57:8080/videofeed
And compare that to your url:
http://192.168.2.102:80/mjpg/video.mjpg
I gather it is not a foscam videostream.cgi url nor an android ipcam videofeed url, which would appear to be the only tested urls. It reminds me of an Axis camera url. More on that later.
In a recent version of that class (also in the older one actually), there seems to be some hackish attempt at reading only to the end of a subheader that is always delimited by crlfcrlf which could have been done just as well with a buffered input reader reading lines until it gets an empty line. What I do see here that seems likely to cause an npe is:
When your url's http server's response does not contain the content-length header, which is quite possible, the returned readImage() byte[] is null.
Since javax.imageio.ImageIO specifies that it will throw an IllegalArgumentException when it gets a null input, I'm guessing it's the ByteArrayInputStream constructor in the grabBufferedImage method that's throwing this, the IplImage.createFrom(null) in the old version, or the b.length in the newer version that is.
None of the line numbers of these versions line up with the error message you've shown that you're getting, so maybe your version of the library is yet again different, and broken differently. Try using the debugger, edit and patch the source of the IPCameraFrameGrabber to better support your mjpeg over http "device" based on what you find out is really in the input stream of the http response.
Since the url format reminds me of an Axis camera, I tried this with one running firmware v5.50 with the boa server built in:
$ curl -I http://user:pass#10.10.10.10:8080/mjpg/video.mjpg
HTTP/1.0 200 OK
Cache-Control: no-cache
Pragma: no-cache
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Connection: close
Content-Type: multipart/x-mixed-replace; boundary=myboundary
So you can see the content length is missing there. However, you do say you're getting frames initially for hours, then then, so I'm kind of at a loss with that part. I mean it sounds as though EITHER the input stream is getting closed, or the java implementation wrapping the stream, implemented in the http protocol handler, runs out of some kind of total space or open connection timer for some reason. I know this seems vague.
Another thing that seems odd is that from what I read in the two example classes of IPCameraFrameGrabber linked, every call to grab reads the input stream looking for headers first, which doesn't make sense to me right now, and I feel as though I must be misreading that.

db.changeVersion doesn't work as expected

I'm trying to upgrade a DB in an app for Ubuntu Touch. I use QtQuick.LocalStorage 2.0.
When I call db.changeVersion it works, but db.version doesn't change until app restarts.
db.changeVersion(db.version, "2", function(tx){...}); // Update database to version 2
console.log(db.version); //Should return "2", instead returns previous version of database
How can have the new db.version without restart the app?
This has been recently fixed in Qt. The changeVersion function will now return a new db object which has the version field updated.
https://bugreports.qt.io/browse/QTBUG-71838
Previous Qt versions required the user to reopen the database to see the updated version, as evidenced by the test code:
http://code.qt.io/cgit/qt/qtdeclarative.git/tree/tests/auto/qml/qqmlsqldatabase/data/changeversion.js
This bug has been fixed, see Andrzej's answer
ORIGINAL ANSWER
I resolved my problem writing this function, that permits to upgrade from any version of the DB to the last version without problems.
/* We need this function because db.version is in the .ini file, that is update only by Javascript Garbage Collection.
* So, we have to upgrade from actual version to the last version using only once db.changeVersion.
* To avoid to have a lot of switch and spaghetti-code, this function allow to add new db version without modify old sql
*
* IMPORTANT: NUMBER OF VERSION HAVE TO BE INT (e.g. 0.1, not 0.1.1)
*/
function upgradeDB() {
// This is the array with all the sql code, insert your update at the last
var sqlcode = [
'CREATE TABLE IF NOT EXISTS Calculations(id INTEGER PRIMARY KEY, calc TEXT)',
'ALTER TABLE Calculations ADD insertDate INTEGER NOT NULL DEFAULT 0'
]
// This is the last version of the DB, remember to update when you insert a new version
var lastVersion = "0.2";
// Hack for change old numeration with new one
if (db.version == "0.1.1") {
db.changeVersion("0.1.1", "0.2");
console.log("Fixed DB!");
}
// So, let's start the version change...
db.changeVersion(db.version, lastVersion,
function(tx) {
if (db.version < 0.1) {
tx.executeSql(sqlcode[0]);
console.log('Database upgraded to 0.1');
}
if (db.version < 0.2) {
tx.executeSql(sqlcode[1]);
console.log('Database upgraded to 0.2');
}
/* This is the structure of the update:
* n is the number of version that sql update to
* m is the number of the sql element in the array. Remember that the number of the first element of array is 0 ;)
if (db.version < n) {
tx.executeSql(sqlcode[m]);
console.log('Database upgraded to n');
}
*/
}); // Finish db.changeVersion
}

App hangs when executing the query in prepared statement

I am trying to select rows which are older than 7 days from current date. Database used is DB2 version 9.
Can you please tell me how exactly can I use the datetime in the query? The date table field is of type timestamp.
I am able to manually run the query without issues. However, when I am using in the prepared statement,
The app hangs when executing the query result = pselect.executeQuery(); as a result of which we need to restart db2 instance in order to clear it.
Can you please help what might be the issue? I do not see any exceptions at all. Other parts of the code works fine if I remove the select_query part.
try{
String select_query = "SELECT URL_ID ,URLVAL FROM URL_TAB WHERE " +
"UPDATED_DATE < TIMESTAMP(CURRENT_DATE - 7 DAYS, '00.00.00')";
System.out.println("select_query=" + select_query);
conn = JDBCDataObjectFactoryManager
.getConnection("JDBCConnectionFactory-SDE");
pselect = conn.prepareStatement(select_query);
System.out.println("pselect=" + pselect);
try{
System.out.println("inside try");
result = pselect.executeQuery();
System.out.println("result=" + result);
}catch(Exception e){
System.out.println("inside catch");
System.out.println("error message==============>"+e.getMessage());
}
if ((result != null) && (result.next())) {
System.out.println("3 >>>>>>>>>>>>>>>>>>>>>>>>>");
url_id = result.getInt(1);
url = result.getString(2);
}//end if
There are two possibilities: either the query is in a lock wait, or it runs for so long that it appears to be hung.
Check what is the value of LOCKWAIT database configuration parameter --by default it is -1, which means infinity, and you normally want to set it to a more reasonable value, typically 30 or 60 seconds. If it is the lock wait that causes your application to "hang", you would get an exception instead, which will help you to debug further.
If the issue is caused by the poor query performance, you'll need to work with your DBAs to figure out the root cause and resolve it.

Problem reading Serial Port C#.net 2.0 to get Weighing machine output

I'm trying to read weight from Sartorius Weighing Scale model No BS2202S using the following code in C#.net 2.0 on a Windows XP machine:
public string readWeight()
{
string lastError = "";
string weightData = "";
SerialPort port = new SerialPort();
port.PortName = "COM1";
port.BaudRate = 9600;
port.Parity = Parity.Even;
port.DataBits = 7;
port.StopBits = StopBits.One;
port.Handshake = Handshake.RequestToSend;
try {
port.Open();
weightData = port.ReadExisting();
if(weightData == null || weightData.Length == 0) {
lastError = "Unable to read weight. The data returned form weighing machine is empty or null.";
return lastError;
}
}
catch(TimeoutException) {
lastError = "Operation timed out while reading weight";
return lastError;
}
catch(Exception ex) {
lastError = "The following exception occurred while reading data." + Environment.NewLine + ex.Message;
return lastError;
}
finally {
if(port.IsOpen == true) {
port.Close();
port.Dispose();
}
}
return weightData;
}
I'm able to read the weight using Hyperterminal application (supplied with Windows XP) with the same serial port parameters given above for opening the port. But from the above code snippet, I can open the port and each time it is returning empty data.
I tried opening port using the code given this Stack Overflow thread, still it returns empty data.
Kindly assist me.
I know this is probably old now ... but for future reference ...
Look at the handshaking. There is both hardware handshaking and software handshaking. Your problem could be either - so you need to try both.
For hardware handshaking you can try:
mySerialPort.DtrEnable = True
mySerialPort.RtsEnable = True
Note that
mySerialPort.Handshake = Handshake.RequestToSend
I do not think sets the DTR line which some serial devices might require
Software handshaking is also known as XON/XOFF and can be set with
mySerialPort.Handshake = Handshake.XOnXOff
OR
mySerialPort.Handshake = Handshake.RequestToSendXOnXOff
You may still need to enable DTR
When all else fails - dont forget to check all of these combinations of handshaking.
Since someone else will probably have trouble with this in the future, hand shaking is a selectable option.
In most of the balances you will see the options for Software, Hardware 2 char, Hardware 1 char. The default setting for the Sartorius balances is Hardware 2 Char. I usually recommend changing to Software.
Also if it stops working all together it can often be fixed by defaulting the unit using the 9 1 1 parameter. And then resetting the communication settings.
An example of how to change the settings can be found on the manual on this page:
http://www.dataweigh.com/products/sartorius/cpa-analytical-balances/