Docker – List Container Startup Policies

A quick one-line Bash command to output all containers and the startup policy:

docker container ls -aq | xargs docker container inspect --format '{{ .Name }}: {{.HostConfig.RestartPolicy.Name}}'

For Docker on Windows, the following PowerShell command produces similar results:

$jsonData = docker container ls -aq |%{docker container inspect --format "{{json .}}"$_}
[System.Collections.ArrayList]$arrayContainerConfig = @()
foreach($jsonContainerConfig in $jsonData ){
	$psobjContainerConfig = ConvertFrom-JSON $jsonContainerConfig
	$arrayContainerConfig.add(@{Name=$psobjContainerConfig.Name;Hostname=$psobjContainerConfig.Config.Hostname;CurrentlyRunning=$psobjContainerConfig.State.Running;RestartPolicy=$psobjContainerConfig.HostConfig.RestartPolicy.Name})
}

$arrayContainerConfig | ForEach {[PSCustomObject]$_} | Format-Table -AutoSize

Oracle – Collections and IN or LIKE Queries

I’ve been retrofitting a lot of PHP/SQL queries to use oci_bind_by_name recently. When using “IN” clauses, you can iterate through your array twice, but it’s an inefficient approach.

// Build the query string with a bunch of placeholders
$strQuery = "select Col1, Col2, Col3 from TableName where ColName IN (";
for($i=0; $i < count($array); $i++){
    if($i > 0){
        $strQuery = $strQuery . ", ";
    }
    $strQuery = $strQuery . ":bindvar" . $i;
}
$strQuery = $strQuery . ")";
... 
// Then bind each placeholder to something
for($i=0; $i < count($array); $i++){
    oci_bind_by_name($stmt, ":bindvar".$i, $array[$i]);
}

Building a table from the array data and using an Oracle collection object creates cleaner code and avoids a second iteration of the array:

$strQuery = "SELECT indexID, objName FROM table WHERE objName in (SELECT column_value FROM table(:myIds))";
$stmt = oci_parse($conn, $strQuery);

$coll = oci_new_collection($kpiprd_conn, 'ODCIVARCHAR2LIST','SYS');
foreach ($arrayValues as $strValue) {
     $coll->append($strValue);
}
oci_bind_by_name($stmt, ':myIds', $coll, -1, OCI_B_NTY);
oci_set_prefetch($stmt, 300);
oci_execute($stmt);

A simple like clause is quite straight-forward

$strNameLikeString = "SomeName%";
$strQuery = "SELECT ds_dvrsty_set_nm from ds_dvrsty_set WHERE ds_dvrsty_set_nm LIKE :divsetnm ORDER BY ds_dvrsty_set_nm DESC fetch first 1 row only";

$stmt = oci_parse($connDB, $strQuery);
oci_bind_by_name($stmt, ":divsetnm", $strNameLikeString);
oci_set_prefetch($stmt, 300);
oci_execute($stmt);

But what about an array of inputs essentially reproducing the LIKE ANY predicate in PostgreSQL? There’s not a direct equivalent in Oracle, and iterating through the array twice to build out a query WHERE (Field1 LIKE ‘Thing1%’ OR Field1 LIKE ‘Thing2%’ OR Field1 LIKE ‘Thing3%’) is undesirable. The with EXISTS allows me to create a LIKE ANY type query and only iterate through my array once to bind variables to placeholders using the same collection approach as was used with the IN clause.

$arrayLocs = array('ERIEPAXE%', 'HNCKOHXA%', 'LTRKARXK%');
$strQuery = "SELECT location_id, clli_code FROM network_location WHERE EXISTS (select 1 FROM TABLE(:likelocs) WHERE clli_code LIKE column_value)";
$stmt = oci_parse($connDB, $strQuery);

$coll = oci_new_collection($connDB, 'ODCIVARCHAR2LIST','SYS');
foreach ($arrayLocs as $strLocation) {
    $coll->append($strLocation);
}
oci_bind_by_name($stmt, ':likelocs', $coll, -1, OCI_B_NTY);
oci_execute($stmt);
print "<table>\n";
print "<tr><th>Loc ID</th><th>CLLI</th></tr>\n";
while ($row = oci_fetch_array($stmt, OCI_ASSOC+OCI_RETURN_NULLS)) {
    print "<tr><td>" . $row['LOCATION_ID'] . "</td><td>" . $row['CLLI_CODE'] . "</td></tr>\n";
}
print "</table>\n";

There are many different collection types in Oracle which can be used with oci_new_collection. A full list of the system collection types can be queried from the database.

SELECT * FROM SYS.ALL_TYPES WHERE TYPECODE = 'COLLECTION' and OWNER = 'SYS';

Frog Rescue

Anya rescued a frog today. It had rained overnight, and the frog somehow hopped on top of our chicken tractor. It got stuck in the screen that covers the top of the tractor. Anya managed to pick up the frog, and she carried it back to our pond. It hopped out of her hands when they were close to the pond.

Socialized Medicine

What really gets me is that the US has socialized health care. Your insurance company isn’t logging all of the excess income they make from you to a large medical expense you incur in the future. The whole point of insurance is that the million (or whatever) ‘customers’ all pay in their their, say, thirteen grand a year. Many people get their annual checkup, and that’s it. Insurance company pays out a couple hundred bucks from that thirteen grand. Someone gets heart surgery – the excess all those only-checkup people paid covers it, and the insurance company pays out fifty grand for that stranger’s medical care.

The American insurance system is just socialized in small, less efficient islands. Those islands are making money off of us all. And you get voted off the island when you lose your job.

Oh, and people still go bankrupt from medical expenses. Or resort to airing their sad story on GoFundMe hoping for donations. I guess we all get to feel benevolent when we donate to their fundraiser, and just paying taxes doesn’t get to make you feel like you’re personally helping someone. But do we really need a profit-driven and inefficient solution just so we can feel good about ourselves? Maybe we could switch to a more efficient system where everyone is the customer pool and the insurance company is looking to more or less break even. And you can donate the money you save on heath care to some other charity — homeless people, bail projects, food kitchens, abused animals, etc.

PostgreSQL Sequences

I’m having a problem with a database refusing to change INSERTS to UPDATES on the ON CONFLICT condition — it insists that a ‘duplicate key value violates unique constraint’. A little time with a search engine tells me that sequences can get out of sync, and then you cannot insert items into the table. How do you know your sequence is out of sync?

SELECT NEXTVAL((SELECT PG_GET_SERIAL_SEQUENCE('"table_name"', 'name_of_column_with_sequence'))) as "NextValue", MAX("name_of_column_with_sequence") AS "Max Value" FROM "table_name";

So null seems like it would be a problem!

For future reference, when the next value is smaller than the max value in the table, the solution is to set the series value based on the max value

SELECT SETVAL((SELECT PG_GET_SERIAL_SEQUENCE('"table_name"', 'name_of_column_with_sequence')), (SELECT (MAX("name_of_column_with_sequence") + 1) FROM "table_name"), FALSE);

Android 11 Arrived!

This morning, my phone was very slow. It got progressively worse — finally getting to a point where there was a ten second lag between touching something and a response. I was trying to reboot because closing all of the apps didn’t do anything. The phone locked instead. And, when I woke the screen back up, I had a strange circle arrow icon in the notification bar. It turns out my phone had been downloading an OS update. It was soon ready to install, and I was actually able to use my phone again. Installed the update — that took a long while too — and voila, I’ve got Android 11 on a TCL T770B. Woohoo!

Wood Chips

Some of the Metroparks have a free wood chip pile. I’m sure they bring in a big, industrial tree chipper machine and a dump truck to clear out downed trees throughout the park. The chips are then dumped into a large pile and free for anyone who wants to haul them. We discovered this last year and started making a wonderful path through our woods — a path that did an awesome job of replacing the usual muck road we travel during maple season. We’ve been watching the location for a new pile of wood chips this year, and Anya spotted the pile a few days ago. It’s a bit of rush to collect them — local landscaping companies show up with large trailers and clear the place out.

We got a lot of wood chips the last few days. The first day, I shoveled and Scott ferried. There was a lot of time lost to driving, so he put together a rear hitch mount for one of our carts. We can now tow both carts simultaneously. The second day, I shoveled while he used a pitch fork — a far superior tool for moving wood chips — and then hung out with Anya while he ferried the carts. Today, he pitch-forked and ferried while I consolidated the pile and did a few other tasks (turned compost, disassembled the temporary hop greenhouse). We’re up to 38 cartloads of wood chips! We’ll probably move some more tomorrow, but it’ll all be soggy from the rain tonight.

Decoy Garden

We’ve had a lot of trouble with deer eating our veggies — corn, beans, lettuce. All very good deer munchies. We had a little luck playing talk radio all night long, but I think they get used to it pretty quickly. Then eat all your not-quite-ready-to-pick sweet corn. This year, we put in a decoy garden full of deer’s fav foods. There are brassicas, beets, radishes, oats, and rye grains. Scott tilled up a big area where our garden used to be, I raked it out to level the soil, and then I spread a bunch of seeds. We did it in three sections — the north-east quarter was finished first. The south-east quarter and west strip were done second, and the strip in the middle was done last. The first section is coming in quite vigorously. The second section is just starting to come in, and the final strip is pretty much dirt. We’ve been lucky to have a few heavier rains since the seeds were spread, so everything is watered well. This should be really cool. My next adventure is to replace some of the lawn with a wildflower seed mix so we’ve got plenty of bee chow available.