The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,860 other subscribers

Archive for June, 2021

Fritz!Box as DMZ behind an Experiabox version 10A

Posted by jpluimers on 2021/06/17

First of all: incoming Fritz!Box VPN behind an Experiabox version 10A fails, because the DMZ implementation of the Experiabox is faulty.

This worked just fine with the Fritz!Box as DMZ host behind a Ziggo Connectbox ([WayBack] Connectbox | Klantenservice | Ziggo).

First a few things to get regular TCP stuff to work: having your Fritz!Box as the DMZ host of an Experiabox.

I had a hart time figuring out some of them, so further below are also quite a few links just in case you bump into simular things.

  1. On the back of the Experiabox version 10A you find the SSDI and WiFi password on what appears to be a sticker, but is in fact a small piece of cardboard paper.

  2. Behind that cardboard paper is a sticker with the initial administrator password: shove out the piece of cardboard to reveal the sticker.
  3. After login (you cannot change the username, which is ADMIN or KPN) you have to choose a new password, which has these undocumented restrictions:
    • It cannot be the old password
    • The password must contain at least 1 special character (!@#$%^&*()_+|~- =\`{}[]:";'<>?,./).
    • The password must contain at least 1 number character.
    • The password must contain at least 1 uppercase letter.
    • Other restrictions I have not bumped into
  4. The default address of the Experiabox V10a is 192.168.2.254. Do NEVER change it, as KPN totally does not support that scenario and will force you to reset it before starting to help you out with anything. Logon as Administrator to the Experiabox at 192.168.2.254.
  5. Setting fixed DHCP leases was hard to find (I was looking for fixed DHCP, not DHCP reservation): Network -> LAN -> LAN DHCP (dropdown next to LAN) -> DHCP Reservation (up to 10 computers).

  6. The DMZ setting was not where I expected it: Network -> Firewall -> DMZ (dropdown next to Firewall)

 

External port checker: [WayBack] Open Port Checker & Scanner | Test Port Forwarding | Internet Protocol Tools

Related:

–jeroen

Posted in Network-and-equipment, Power User, VPN | Leave a Comment »

Beyond Compare 4 for Windows and Mac binary dfm conversion problems. – Scooter Forums

Posted by jpluimers on 2021/06/17

If you bump into binary DFM conversion issues, then on Windows you can use  batch file, but on Mac I have not found a workaround yet.

[WayBack] Beyond Compare 4 for Windows and Mac binary dfm conversion problems. – Scooter Forums

Read the rest of this entry »

Posted in Beyond Compare, Development, Power User, Software Development | Leave a Comment »

Too bad the Delphi IDE does not find the formatter settings when searching for “Margin” or “Right”, despite the setting is named “Right margin”

Posted by jpluimers on 2021/06/17

IDEs drive me nuts, including the Delphi IDE. Searching for Margin or Setting only reveals the margin and gutter setting, not the formatter settings.

So you have to remember this is in the “Formatter”, especially the “Line Breaks” node:

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

GitHub – jjjake/internetarchive: A Python and Command-Line Interface to Archive.org

Posted by jpluimers on 2021/06/16

On my list of things to play with: [WayBack] GitHub – jjjake/internetarchive: A Python and Command-Line Interface to Archive.org.

Via:

Related:

  • [WayBack] The Internet Archive Python Library — Internet Archive item APIs 1.8.5 documentation
  • [WayBack] Command-Line Interface — Internet Archive item APIs 1.8.5 documentation
  • [WayBack] Quickstart — Internet Archive item APIs 1.8.5 documentation, including:

    Configuring

    Certain functionality of the internetarchive Python library requires your archive.org credentials. Your IA-S3 keys are required for uploading, searching, and modifying metadata, and your archive.org logged-in cookies are required for downloading access-restricted content and viewing your task history. To automatically create a config file with your archive.org credentials, you can use the ia command-line tool:

    $ ia configure
    Enter your archive.org credentials below to configure 'ia'.
    
    Email address: user@example.com
    Password:
    
    Config saved to: /home/user/.config/ia.ini
    

    Your config file will be saved to $HOME/.config/ia.ini, or $HOME/.ia if you do not have a .configdirectory in $HOME. Alternatively, you can specify your own path to save the config to via ia --config-file '~/.ia-custom-config' configure.

    If you have a netc file with your archive.org credentials in it, you can simply run ia configure --netrc. Note that Python’s netrc library does not currently support passphrases, or passwords with spaces in them, and therefore not currently suported here.

–jeroen

Read the rest of this entry »

Posted in Development, Internet, InternetArchive, Power User, Python, Scripting, Software Development, WayBack machine | Leave a Comment »

ODAC: calling SYS.DBMS_SESSION.SET_NLS failing with ORA-06550/PLS-00103

Posted by jpluimers on 2021/06/16

Do not call SYS.DBMS_SESSION.SET_NLS with an instance of the [Archive.is] TOraStoredProc Class, as under the hood, it will translate the call to this:

Class:Ora.TOraStoredProc;Component:sprSetNls;Flag:tfQPrepare,Text:Prepare: begin
  SYS.DBMS_SESSION.SET_NLS(:PARAM, :VALUE);
end;
:PARAM(VARCHAR[22],IN)='NLS_NUMERIC_CHARACTERS' 
:VALUE(VARCHAR[4],IN)=''.,''

The above is a translation of the bold portions in this call (note it contains the an instantiation of an [Archive.is] TOraSession Class as you need one; examples further down assume this session instance to exist):

var
  MainOraSession: TOraSession;
  DbmsSessionSetNlsOraStoredProc: TOraStoredProc;
begin
  MainOraSession := TOraSession.Create(Self);
  try
    MainOraSession.Name := 'MainOraSession';
    MainOraSession.Username := 'FOO';
    MainOraSession.Server := 'BAR';
    MainOraSession.LoginPrompt := False;
    MainOraSession.Options.UseOCI7 := True;
    MainOraSession.Open();
    DbmsSessionSetNlsOraStoredProc := TOraStoredProc.Create(Self);
    try
      DbmsSessionSetNlsOraStoredProc.Name := 'DbmsSessionSetNlsOraStoredProc';
      DbmsSessionSetNlsOraStoredProc.StoredProcName := 'SYS.DBMS_SESSION.SET_NLS';
      DbmsSessionSetNlsOraStoredProc.Session := MainOraSession;
      DbmsSessionSetNlsOraStoredProc.Debug := True;
      with DbmsSessionSetNlsOraStoredProc.ParamData.Add do 
      begin
        DataType := ftString;
        Name := 'PARAM';
        ParamType := ptInput;
        Value := nil;
      end;
      with DbmsSessionSetNlsOraStoredProc.ParamData.Add do
      begin
        DataType := ftString;
        Name := 'VALUE';
        ParamType := ptInput;
        Value := nil;
      end;
      DbmsSessionSetNlsOraStoredProc.ParamByName('PARAM').AsString := sParam;
      DbmsSessionSetNlsOraStoredProc.ParamByName('VALUE').AsString := sValue;
      DbmsSessionSetNlsOraStoredProc.Prepare();
      DbmsSessionSetNlsOraStoredProc.ExecProc();
    finally
      DbmsSessionSetNlsOraStoredProc.Free();
    end;
  finally
    MainOraSession();
  end;
end;

It will result in an Oracle error during the Prepare of the statement:

ORA-06550: line 2, column 36:
PLS-00103: Encountered the symbol ":" when expecting one of the following:

   ( - + case mod new not null 
   
   continue avg count current exists max min prior sql stddev
   sum variance execute forall merge time timestamp interval
   date  pipe
   

In stead, take your TOraPackage object and make a call like this:

var
  DbmsSessionOraPackage: TOraPackage;
begin
  DbmsSessionOraPackage := TOraPackage.Create(Self);
  try
    DbmsSessionOraPackage.Name := 'DbmsSessionOraPackage';
    DbmsSessionOraPackage.Debug := True;
    DbmsSessionOraPackage.Session := dbSession;
    DbmsSessionOraPackage.PackageName := 'SYS.DBMS_SESSION';

    DbmsSessionOraPackage.ExecProcEx('SET_NLS', ['PARAM', 'NLS_NUMERIC_CHARACTERS', 'VALUE', '''.,''']);
  finally
    DbmsSessionOraPackage.Free();
  end;
end;

This then results in this in the SQL monitoring (note quoting quotes is different in SQL than Delphi):

Class:Ora.TOraSQL;Component:;Flag:tfQExecute,Text:begin
  SYS.DBMS_SESSION.SET_NLS(:PARAM, :VALUE);
end;
:PARAM(VARCHAR[22],IN)='NLS_NUMERIC_CHARACTERS' 
:VALUE(VARCHAR[4],IN)=''.,''

instead of this:

Class:Ora.TOraStoredProc;Component:sprSetNls;Flag:tfQPrepare,Text:Prepare: begin
  SYS.DBMS_SESSION.SET_NLS(:PARAM, :VALUE);
end;
:PARAM(VARCHAR[22],IN)='NLS_NUMERIC_CHARACTERS' 
:VALUE(VARCHAR[4],IN)=''.,''

I am still a sort of baffled why this is a problem. But using the TOraPackage works.

One thing to remember is that an TOraSession instance does not allow you to get to the underlying TOCIConnection instance, which does allow setting NLS information directly; see for instance the old code at [WayBack] OraClasses.pas in xinhaining-dianjianyiqi-tongxunchengxu | source code search engine.

This is because the underlying connection can be both OCI and Direct depending on the TOraSession.Options.Direct value: [WayBack] About Connection.Ping method when Direct Mode – Devart Forums.

Other calls on SYS.DBMS_SESSION succeed

The odd thing is that single-parameter calls on SYS.DBMS_SESSION.SET_ROLE (which can be tricky, see [WayBack] Introducing Database Security for Application Developers) work fine, so no alternative (like a plain [WayBack] SET ROLE) is needed:

var
  DbmsSessionSetRoleOraStoredProc: TOraStoredProc;
begin
  DbmsSessionSetRoleOraStoredProc := TOraStoredProc.Create(Self);
  try
    DbmsSessionSetRoleOraStoredProc.Name := 'DbmsSessionSetRoleOraStoredProc';
    DbmsSessionSetRoleOraStoredProc.StoredProcName := 'SYS.DBMS_SESSION.SET_ROLE';
    DbmsSessionSetRoleOraStoredProc.Session := dbSession;
    with DbmsSessionSetRoleOraStoredProc.ParamData.Add do begin 
      DataType := ftString;
      Name := 'ROLE_CMD';
      ParamType := ptInput;
      Value := 'EXAMPLE';
    end;
    DbmsSessionSetRoleOraStoredProc.ParamByName('ROLE_CMD').AsString := 'EXAMPLEROLE';
    DbmsSessionSetRoleOraStoredProc.Prepare;
    DbmsSessionSetRoleOraStoredProc.ExecProc;
  finally
    DbmsSessionSetRoleOraStoredProc.Free();
  end;
end;

results in this log:

Class:Ora.TOraStoredProc;Component:StrdPSetRole;Flag:tfQExecute,Text:begin
  SYS.DBMS_SESSION.SET_ROLE(:ROLE_CMD);
end;
:ROLE_CMD(VARCHAR[10],IN)='EXAMPLEROLE'

Similar for SYS.DBMS_APPLICATION_INFO

Calling anything on DBMS_APPLICATION_INFO gives you an exception.

On the .NET side of DevArt, you can use

–jeroen

Posted in Database Development, Delphi, Development, OracleDB, Software Development | Leave a Comment »

ODAC undocumented exception ‘Need Oracle 8 Call Interface’

Posted by jpluimers on 2021/06/16

I got this when taking over maintenance of some legacy code that called a stored procedure in a :

---------------------------
Debugger Exception Notification
---------------------------
Project LegacyProject.exe raised exception class Exception with message 'Need Oracle 8 Call Interface'.
---------------------------
Break   Continue   Help   
---------------------------

The problem with finding more information about this, is that there are virtual no hits on Oracle 8 Call Interface, OCI 8 or Oracle Call Interface 8.

A good document is [WayBack] OCI: Introduction and Upgrading (found via [Archive.is] “OCI 7” – Google Search), but it never mentions 8, only these terms occur:

  • release 7.x OCI
  • OCI release 7
  • OCI version 7
  • Oracle release 7 OCI
  • Release 8.0 of the OCI
  • 7.x OCI
  • Later OCI
  • Post-release 7.x OCI

The error happens on the first instance of at least an [Archive.is] TOraStoredProc Class or [Archive.is] TOraPackage Class that prepares or executes a stored procedure.

One problem is that this is an instance of a plain [WayBack] Exception Class , not a [WayBack] EDatabaseError Class or [Archive.is] EDAError Class.

What it means is that the UseOCI7 sub-property was set to True in your TOraSession property Options:

var
  MainOraSession: TOraSession;
begin
  MainOraSession := TOraSession.Create(Self);

  MainOraSession.Name := 'MainOraSession';
  MainOraSession.Username := 'ExammpleUser';
  MainOraSession.Server := 'ExampleTnsName';
  MainOraSession.LoginPrompt := False;
  MainOraSession.Options.UseOCI7 := True;

One thing to remember is that an TOraSession instance does not allow you to get to the underlying TOCIConnection instance, which does allow setting NLS information directly; see for instance the error at [WayBack] Not connected to oracle error – Devart Forums and old code at [WayBack] OraClasses.pas … | source code search engine and [WayBack] Ora.pas in … | source code search engine; UniDac is relatively similar [WayBack] UniDAC v3.7 …:OraClassesUni.pas (another explanation is in [WayBack] Setting the Client Info for the TOraAlerter extra session – Devart Forums).

This is because the underlying connection can be both OCI and Direct depending on the TOraSession.Options.Direct value: [WayBack] About Connection.Ping method when Direct Mode – Devart Forums.

After the first occurrence, you will not get this error again, you get way more spurious errors, especially on stored procedures in packages, where the stored procedure has 2 or more parameters. There you get errors like this one for TOraStoredProc:

ORA-06550: line 2, column 36:
PLS-00103: Encountered the symbol ":" when expecting one of the following:

   ( - + case mod new not null <an identifier>
   <a double-quoted delimited-identifier> <a bind variable>
   continue avg count current exists max min prior sql stddev
   sum variance execute forall merge time timestamp interval
   date <a string literal with character set specification>
   <a number> <a single-quoted SQL string> pipe
   <an alternatively-quoted string literal with character set speci.

When logging using a [Archive.is] TOraSQLMonitor Class instance (use the [Archive.is] TCustomDASQLMonitor.OnSQL Event with the [Archive.is] TOnSQLEvent Procedure Reference signature) you can get the underlying information of the TOraStoredProc (see the example code below that raises this):

Class:Ora.TOraStoredProc;Component:sprSetNls;Flag:tfQPrepare,Text:Prepare: begin
  SYS.DBMS_SESSION.SET_NLS(:PARAM, :VALUE);
end;
:PARAM(VARCHAR[22],IN)='NLS_NUMERIC_CHARACTERS' 
:VALUE(VARCHAR[4],IN)=''.,''

It fails equally when doing any DBMS_APPLICATION_INFO calls, for which the .NET version of ODAC has a special [WayBack] SetDbmsApplicationInfo Method in the [WayBack] OracleConnection Class. Too bad the Delphi version omits that.

When using TOraPackage, you can get different errors, like for instance this EDatabaseError:

Exception class EDatabaseError with message 'Parameter 'VALUE' not found'.

It basically means that through OCI, the parameter list could not be obtained, so the error is caught on the Delphi side instead of the Oracle side.

Using a TOraPackage is easier at design time, as it allows you to select the [Archive.is] TOraPackage.PackageName Property property using the underlying TOraSession. Somehow a TOraStoredProc does not allow you to select the [Archive.is] TOraStoredProc.StoredProcName Property at design time.

Related:

–jeroen

Read the rest of this entry »

Posted in Database Development, Delphi, Development, OracleDB, Software Development | Leave a Comment »

PlasticSCM: delete a changeset

Posted by jpluimers on 2021/06/15

Every now and then you really goof up the final changeset in a series of changesets that are in a branch.

I have yet to figure out how to delete that changeset, other than keeping the branch stale and merge from the last good changeset to a new branch.

This seems hard to do given these from [Archive.is] plasticscm delete changeset – Google Search:

Deleting the branch fails because there is still a changeset on it:

Deleting the changeset fails because the option is greyed out:

It does not happen that often, though there are now about a few % of the branches stale because of this.

–jeroen

Posted in Development, PlasticSCM, Source Code Management | Leave a Comment »

Needle fear / prikangst

Posted by jpluimers on 2021/06/15

An interesting Dutch thread on fear of needles and how to cope with it is at [Archive.is] Jerry Vermanen on Twitter: “Even iets heel anders. Mijn vaccinatieafspraak komt dichterbij. Maar ik ben doodsbang voor naalden. Hoe hebben andere mensen met dezelfde angst dit aangepakt?”

The question came because of COVID-19 vaccinations.

Since I have needle fear and I am autistic, I posted a sub-thread ([Archive.is] Jeroen Wiert Pluimers on Twitter: “Ik heb mijn “maar je ziet er helemaal niet autistisch uit” T-Shirt aangetrokken (dank @biancatoeps !) … “) with how it works best in my case, which I have translated below just in case it can help other people.

Having gotten my second AstraZeneca shot on Sunday 2021-06-14, and had drawn blood for cardiologist check-up on Monday 2021-06-15 I know these work for me:

I put on my “but you don’t look autistic at all” T-Shirt (thanks [Archive.is] @biancatoeps !)

In addition, I report it in advance and briefly discuss how it works best for me.

They are very happy with that, by the way.

because many have that fear, but don’t say it (just assume that 1 in 3 people has a fear of injection, I’ll look for a link about that in a moment).

In addition to [Archive.is] Eveline Meijer on Twitter: “Nog niet gevaccineerd, maar vaak genoeg geprikt en ik ben er ook bang voor. Ik meld dit vaak bij degene die de prik zet en dat ik de naald vooral niet wil zien. Dus andere kant op kijken en proberen rustig te ademen. Dan komt het bij mij meestal wel goed.… “

first what works for me, and what I do:

  1. give a brief explanation of what they are going to do and how
  2. indicate my preferred arm
  3. tell them they should stop talking to me a few seconds before putting the needle in
  4. look away from where they sting, focus on something else so that I focus on breathing
  5. say “yes” if they can start

You’re certainly not alone, and it’s great that you’re talking about it before now. Hopefully these tips will help making it easier for you in the future.

This states that more than 35% has fear plus some tips: [Wayback] Bang voor naalden? Deze app helpt bij prikangst | RTL Nieuws (which mentions the app [Wayback] AINAR – Artificial Intelligence for Needle Anxiety Reduction)

Good luck for when you get vaccinated. I will get the 2nd shot this afternoon and it will be fine (:

Later: Got shot 2 of AstraZeneca. A little light-headed because the anxiety subsides. Waiting for half an hour now as I’m allergic to NSAIDs: just to be on the safe side.

Notes:

Some interesting bits from the Dutch thread at [Wayback] Thread by @JerryVermanen: Even iets heel anders. Mijn vaccinatieafspraak komt dichterbij. Maar ik ben doodsbang voor naalden. Hoe hebben andere mensen met dezelfde angst dit aangepakt?:

  • [Wayback] AINAR – Artificial Intelligence for Needle Anxiety Reduction

    Welcome to AINAR!

    The AINAR game application makes it possible to learn controlling your needle fear. The AINAR app is making use of state of the art technology in Artificial Intelligence and biofeedback.

    THIS SITE DOES NOT CONTAIN IMAGES OF NEEDLES!

  • Tell them, and when getting the shot, look the other way and focus on breathing.
  • Seek distraction: make some small talk, play on your phone.
  • Look forward to the treat you give yourself afterwards: ice cream, LEGO, whatever.
  • Compartmentalise the event slots (before shot, during shot, after shot) and try to put your fears only in the middle slot.
  • Get the single shot Janssen vaccin (only having fear once instead of twice).
  • If the pain triggers your fear, try lidocaine skin cream (consult with your doctor first as it is a anesthetic that causes loss of feeling in the skin and surrounding tissues that prevents pain).
  • Take a support person or support animal with you (first ask if that is allowed).
  • Fear can enhance the pain sense, so if you can lessen the fear, the pain likely lessens too.

Dutch sub-thread: [Wayback] Thread by @jpluimers: @JerryVermanen Ik heb mijn “maar je ziet er helemaal niet autistisch uit” T-Shirt aangetrokken (dank @biancatoeps !)…

–jeroen

Read the rest of this entry »

Posted in LifeHacker, Power User | Leave a Comment »

Delphi Basics : FindCmdLineSwitch command07

Posted by jpluimers on 2021/06/15

Since I keep forgetting about this, and there is the Embarcadero documentation for it has had no examples added in Delphi 2007 or later: [WayBack] Delphi Basics : FindCmdLineSwitch command

Example code : Saerch the program parameters for 3 switches
begin
// Before running this code, use the Run/parameters menu option
// to set the following command line parameters : /def abc /ghi
ShowMessage(CmdLine);     // Show the execution command + parameters

// How many parameters were passed?
ShowMessage(‘There are ‘+IntToStr(ParamCount)+’ parameters’);

// Scan for parm1, parm2 and parm3 parameters
if FindCmdLineSwitch(‘abc’)
then ShowMessage(‘abc found’)
else ShowMessage(‘abc NOT found’);

if FindCmdLineSwitch(‘def’)
then ShowMessage(‘def found’)
else ShowMessage(‘def NOT found’);

if FindCmdLineSwitch(‘ghi’)
then ShowMessage(‘ghi found’)
else ShowMessage(‘ghi NOT found’);
end;
Show full unit code
   “C:\Program files\Borland\Delphi7\Projects\Project1.exe” /def abc /ghi
There are 3 parameters
abc NOT found
def found
ghi found

Related: [WayBack] delphi – How to read value of ParamStr with different deliminators? – Stack Overflow

Unchanged Embarcadero Delphi 2007 documentation:

For comparison, the Delphi 10.2 Rio documentation:

The really odd thing? The really versatile TCommandParser class got ditched after Delphi XE6: On the Delphi TCommandParser class for parsing command-lines and arguments (via: Suggestions for how to define command line parameters – Stack Overflow).

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

Awesome Cookie Manager: popup URI

Posted by jpluimers on 2021/06/14

I blogged about [WayBack] Awesome Cookie Manager before. The Awesome Cookie Manager lets the user manage cookies in Google Chrome. It is great.

It is even greater that the pop-up dialog has a URI:

chrome-extension://hcpidejphgpcgfnpiehkcckkkemgneif/popup.html

Get it at [Archive.is] Awesome Cookie Manager – Chrome Web Store:

Displays a list of all Google Chrome cookies. Allows searching, viewing, editing, saving, restoring, and deleting cookies.

It helped me solve the below cases, where I had too many cookies, to the Web Archive bailed out; Awesome Cookie Manager helped me to clear the right cookies:

Edit 20231230: Awesome Cookie Manager source repository at [Wayback/Archive] Phatsuo/awesome-cookie-manager: Awesome Cookie Manager.

--jeroen

Posted in Chrome, Google, Power User | Leave a Comment »