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
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
Posted in Beyond Compare, Development, Power User, Software Development | Leave a Comment »
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 »
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:
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
iacommand-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.iniYour config file will be saved to
$HOME/.config/ia.ini, or$HOME/.iaif you do not have a.configdirectory in$HOME. Alternatively, you can specify your own path to save the config to viaia --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
Posted in Development, Internet, InternetArchive, Power User, Python, Scripting, Software Development, WayBack machine | Leave a Comment »
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
TOraSessioninstance does not allow you to get to the underlyingTOCIConnectioninstance, 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
OCIandDirectdepending on theTOraSession.Options.Directvalue: [WayBack] About Connection.Ping method when Direct Mode – Devart Forums.
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'
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 »
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:
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:
- [Archive.is] TOraSession Class
- [Archive.is] TOraSession.Options Property
- [Archive.is] TOraSessionOptions.UseOCI7 Property
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
TOraSessioninstance does not allow you to get to the underlyingTOCIConnectioninstance, 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
OCIandDirectdepending on theTOraSession.Options.Directvalue: [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
Posted in Database Development, Delphi, Development, OracleDB, Software Development | Leave a Comment »
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:
Delete empty branches only
Branches can only be deleted when they are empty. This means that if you want to delete a branch, you have to delete its changesets first. A changeset can only be deleted if it doesn’t have any descendants (children or linked by merges).
Consider the following scenario: If you want to delete
main/t124, you’ll need to delete its two changesets first. But, to delete changesetD, you’ll need to first removeA,BandC, to get rid of all its descendants.Yes, Plastic branches are admittedly hard to kill.
But, in our opinion, the question is: why would you want to delete a branch?
The answer is obvious for users coming from Git: deleting branches is a pretty common technique, you need to clean out old branches to keep the repo usable. But, that’s not the case in Plastic. If you want to learn more about why we don’t delete branches, please check “We don’t delete task branches”.
Changesets can be moved to a different branch
Changesets belong to a branch, but they can be moved under certain circumstances.
A common example is that you mistakenly checkin changes to
maininstead of the right task branch because you forgot to create the branch and switch to it.It is possible to fix the issue and move the changesets to the new branch:
Find the details about how to move changesets here.
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 »
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:
FindCmdLineSwitch determines whether a string represents a command-line switch, based on the first character of the string.
Switchis a command-line parameter to search for.Charsis the set of characters that distinguish switches from other parameters. IfSwitchis omitted, it defaults to ‘-‘ on Unix based systems, and to ‘/’ and ‘-‘ on Windows based systems.IgnoreCasedetermines whether case-insensitive character matching is used. The default is True. This function can also be used to retrieve parameter values in addition to finding command-line switches, for that overload.Valuereturns the value associated with the specified switch.SwitchTypesdetermines how parameter values are parsed:
Constant Value clstValueNextParam -p ValueclstValueAppended -p Valueor -p:ValueThe
clstValueNextParamparameter specifies that values are separated from the switch by a space character. TheclstValueAppendedparameter specifies that the values are appended immediately, following the switch (no space) or after a colon.SwitchTypesis a set type parameter and the default is to allow values of both parameter types to be returned–[clstValueNextParam, clstValueAppended]. Any single switch type may be specified as well. An emptySwitchTypeparameter, [], will result in no values being returned. Pass theSwitchTypesparameter to exclude any of these switch types (Switchmay be 1 or more characters in length.)
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 »
Posted by jpluimers on 2021/06/14
Details at [WayBack] Keyboard Shortcuts, Markdown, and Autocomplete – Atlassian Documentation; summary:
To view all Confluence keyboard shortcuts, do any of the following:
- Choose the help icon from the universal sidebar, then choose Keyboard Shortcuts.
- When viewing a page, press shift+?
- While editing a page, choose the question mark icon from the editor toolbar.
a list of some of the most common shortcuts:
…
Markdown
Use markdown shortcuts to format text from the comfort of your keyboard.
…
Use autocomplete for links
- Either:
- Type [ and then the first few characters of the page title, user’s name, image name or file name.
- Type the first few characters of the page title, user’s name, image name, or file name (or select relevant text) and then press ctrl+shift+k.
- Click the relevant link from the list of suggestions.
If the item you need is not in the list, either choose Search for ‘xxx’ to continue looking for the page within Confluence, or Insert Web Link to link to an external page.
…
When a Windows shortcut has Ctrl in it, the MacOS shortcut uses Command.
–jeroen
Posted in Development, Keyboards and Keyboard Shortcuts, Lightweight markup language, MarkDown, Power User, Software Development | Leave a Comment »
Posted by jpluimers on 2021/06/10
One of the situations where setlocal enabledelayedexpansion comes on handy to replace \ with / which some unix based tools like better: [WayBack] string – Change backslash to forward slash in windows batch file – Stack Overflow
echo off setlocal enabledelayedexpansion for %%f IN ("C:\tools\workspace\*") DO ( set old=%%f echo !old! set new=!old:\=/! echo !new! echo. )
Related, as it explains when the source and target replacements are in variables themselves: [WayBack] command line – String replacement in batch file – Stack Overflow, thanks Joey and Tom Warfield!
You can use the following little trick:
set word=table set str="jump over the chair" call set str=%%str:chair=%word%%% echo %str%The
callthere causes another layer of variable expansion, making it necessary to quote the original%signs but it all works out in the end.…
Upvoting this answer because it works both ways, with the environment variable in either position, or in both the “before” and “after” positions:
set word=table
set str="jump over the chair"
call set str=%%str:chair=%word%%%
echo %str%
set word1=chair
set word2=desk
set str="jump over the chair"
call set str=%%str:%word1%=%word2%%%
echo %str%'
–jeroen
Posted in Batch-Files, Development, Scripting, Software Development | Leave a Comment »
Posted by jpluimers on 2021/06/10
I have been bitten by this a few times too much, so time to write it down:
When porting old Delphi code from the Delphi 7 and older era, the options were stored .dof (options) and .cfg (configuration) files.
More modern Delphi versions try to translate these files when generating the .dproj file, in a similar way as they try to upgrade older .dproj files to newer formats.
Many things can go wrong, including these ones I have bumped into multiple times:
DCC_DebugInformation having a 0 or false value, but not handling these values correctly (I remember problems around the Delphi XE5 era with this: When the Delphi XE5 commandline compiler fails with error F1026: File not found: ‘False.dpr’)DCC_OutputDependencies not being adhered to (no .d file is being emitted by the compiler), though for the .drc files, DCC_OutputDRCFile works fine)DCC_DebugInformation having a 1 value (Limited Debug information) instead of being absent (Debug information)DCC_SymbolReferenceInfo having a 1 value (Definitions Only) instead of being absent (Reference info)–jeroen
Posted in Delphi, Development, Software Development | 1 Comment »