### Safe OCCI createStatelessConnectionPool usage

I've been working a bit with Oracle's OCCI (the C++ API for Oracle Database), and stateless connection pools in particular.

I've noticed a particular behaviour that's important to be aware of when creating the connection pool (using the oracle::occi::Environment method "createStatelessConnectionPool"). The problem is that this call will fail if you have some kind of conenction or TNS error, leaving you with an unusable and invalid pool.

To give a concrete example, if you create a connection pool like this:

scPool = env->createStatelessConnectionPool(...

what I find is that if the database is down (for example), this call with throw a TNS error like ORA-12541: TNS:no listener, and the scPool object is invalid (but not a null reference).

if you attempt to use the pool thereafter, e.g.:
if (scPool) cout << "MaxConn=" << scPool->getMaxConnections() << endl;

then firstly "if (scPool) .." wont protect you (because its not null), and the getMaxConnections method call will throw an uncatchable segmentation fault (this is Linux x86 I'm using)

The workaround of course is to null your scPool if you catch the TNS error, and then if you want a robust application that must keep running even if the connection pool is not created, everytime you try and get a connection from the pool you should also first check to see if you have a pool object to use (and if not, try and create it again).

Tortuous to say the least!

I would have expected that the desired behaviour should be for createStatelessConnectionPool to return a valid connection pool even if connections are not possible at that point in time, and that for the TNS errors to be only thrown if and when you try and get a connection from the pool.

Anyone have a view? ... bug, ER or expected?

12-Feb, an update: I've since discovered that this behaviour is true only if you set a "minumum connections" >0 for the pool. If you set "minumum connections"==0, then the behaviour is as I would expect - the pool is created without error, but you may hit an error when attempting to get a connection from the pool.

### Handling range parameters in Bash

I've come across a few occasions where I wanted to specify a "range parameter" for Bash scripts. Like "1..4" meaning do for 1,2,3 and 4.

Here's a simple trick that uses the (relatively obscure) variable expansion and substring replacement capabilities of the shell.

#!/bin/bashv_range="1..3"         # or you could have taken it as a script parameterv_start=${v_range%%.*} # chomp everything from the left-most matching "."v_end=${v_range##*.}   # chomp everything up to the right-most matching "."

The repeated %% and ## basically mean you will get a "greedy" match, so you can say "1..4" or "1....5"; it doesn't matter how many repeats you have of the range delimiter. Of course, you can choose other delimiters such as a hyphen, as in "5-10", if you wish.

Now that you have extracted the start and end indices, you can then loop or whatever to your hearts content:
for ((a=v_start; a <= v_end ; a++))do   echo "Looping with a=$a"done For more information on variable expansion, see 9.3 in the Advanced Bash Scripting Guide. Postscript 5-Feb-2008: We live and learn! Hat tip to buford for alerting me to the seq utility, which simplifies the iteration over a range, as in: for a in seq 1 10do echo "Looping with a=$a"done

You still need to determine the start and end values of the range, which is the whole point of the variable expansions approach posted here.

### Generating a temp filename in Bash

Here's a function that simplifies the process of generating temporary filenames in shell scripts (I use bash). This function will generate a temporary filename given optional path and filename prefix parameters. If the file happens to already exist (a small chance), it recurses to try a new filename.

It doesn't cleanup temp files or anything fancy like that, but it does have the behaviour that if you never write to the temp file, it is not created. If you don't like that idea, touch the file before returning the name.

This procedure demonstrates the use of variable expansion modifiers to parse the parameters, and the $RANDOM builtin variable. function gettmpfile(){ local tmppath=${1:-/tmp}  local tmpfile=$2${2:+-}  tmpfile=$tmppath/$tmpfile$RANDOM$RANDOM.tmp  if [ -e $tmpfile ] then # if file already exists, recurse and try again tmpfile=$(gettmpfile $1$2)  fi  echo $tmpfile} By default (with no parameters specified), this function will return a random filename in the /tmp directory: [prompt]$ echo $(gettmpfile) /tmp/324003570.tmp If you specify a path and filename prefix, these are used to generate the name: [prompt]$ echo \$(gettmpfile /my_tmp_path app-tmpfile)
/my_tmp_path/app-tmpfile-276051579.tmp