How to conditionally compile in case of an existing table? - openedge

I'm working with Progress-4GL, release 11.6, appBuilder and procedure editor.
I have just created a table, called "table_X", and I'm using it inside the code, something like:
FIND table_X ...
However, my program is general, but the table is custom-based (some customers have this table, but some don't).
So, I'd like to add a "preprocessor", something like:
&IFDEF table_X
&THEN FIND table_X ...
&END
Where the &IFDEF means: "Only compile this piece of code if that table exists in DB".
Is this possible in Progress-4GL, release 11.6?

If you are using static queries you will need to add a define in an environment include used when compiling. In your standard directory:
// env.i
// nothing (yet)
And in your customer directory:
// env.i
&global define table_x
Which you can then use at compile time with your propath, if your propath starts with the customer directory then the definition is picked up, otherwise env.i is taken from your standard directory and table_x is not defined:
{ env.i }
&if defined( table_x ) &then
find table_x no-lock.
&endif
If you can replace static use of this table with dynamic use, then you do not need the definitions and you can:
def var hb as handle no-undo.
create buffer hb for table "table_x" no-error.
if valid-handle( hb ) then do:
hb:find-unique( no-lock ).
end.
While this could be attractive, it does mean that you are burdening all your customers with potentially irrelevant run-time checks.

Related

Is it possible to ignore the column when generating migrations

My project working on Symfony 4.4 and doctrine migrations bundle 3.2.1.
I used the columnDefinition to write a special column:
columnDefinition="VARCHAR(50) GENERATED ALWAYS AS (IF(ISNULL(`cabinet_id`), 'null', `cabinet_id`)) VIRTUAL"
It works perfect, but now, every time when I call doctrine:migrations:diff, migration is trying to change the column for the same:
ALTER TABLE MonitoringReportUpdate CHANGE virtual_null `virtual_null` VARCHAR(50) GENERATED ALWAYS AS (IF(ISNULL(`cabinet_id`), \'null\', `cabinet_id`)) VIRTUAL
And even if I run this alter, and call doctrine:migrations:diff again, I'll see the same query to execute:
ALTER TABLE MonitoringReportUpdate CHANGE virtual_null `virtual_null` VARCHAR(50) GENERATED ALWAYS AS (IF(ISNULL(`cabinet_id`), \'null\', `cabinet_id`)) VIRTUAL
Did I use columnDefinition wrong or maybe it's just a bug? Or is it possible to ignore this column when I call generate migration?
This is something Doctrine is not able to analyze properly so he is not able to consider it "already done", so he is considering it missing each time you generate a diff.
I already had to try such "complex" doctrine column def and i did not found a good workaround.
My best answer would be : There is something bad in your code that generate that kind of needed behavior in your database : avoid it and adapt your code.

Error during compiling: `identifier not found` (code C3861)

I have a field in my acore_characters table named 'rank' with a tinyint which ranges from 0 to 3 inclusive, based on player's progression. I need to read that value at both login and at certain specific circumstances.
I wrote the following PreparedStatement: "SELECT rank FROM acore_characters WHERE guid = ?" and then the code which is supposed to read that value:
uint16 GetCharactersRank(uint64 guid) {
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(mystatement);
stmt->setUInt32(0, GetGUID());
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (result) {
[...truncated]
and then fetching the result and so on, but then I get a code C8361 when compiling because 'GetGUID':identifier not found in Player.cpp file...what goes wrong? The other GetGUID calls throughout the file dont give this result. I'm not very fond of c++, any help is very appreciated.
It's not recommended to directly patch the core to add customisations to it. Instead, use modules.
An example can be found here: Is it possible to turn a core patch into a module for AzerothCore?
You can have a look and copy the skeleton-module and start modifying it to create your own.
In your case, you probably want to use the OnLogin player hook.

File Exists and Exception Handling in U-Sql

Two questions
How to check file exists or not before EXTRACT?
we have scenario where new inputs file is generated every day for catalog data. we need to merge new input with d-1 file. before merge we what to make sure that new input file exists at source location
does u-sql supports try...catch block?
Regarding checking if a file exists. We recently released a compile-time IF statement that indeed can check for partition existence (and other objects such as files and tables are on the roadmap).
Once that feature is released (still one or two refreshs out at the time of this answer) it may look something like (syntax subject to change):
IF FILE.EXISTS("/mydir/myfile.csv") THEN
#data = EXTRACT ... FROM "/mydir/myfile.csv" USING ...;
...
#jobstate = SELECT * FROM (VALUES("job completed")) AS T(status);
ELSE
#jobstate = SELECT * FROM (VALUES("file not ready. Job not executed.")) AS T(status);
END;
OUTPUT #jobstate TO "/jobs/myjobstate.csv" USING Outputters.Csv();
You will be able to provide the name as a parameter as well. Please let me know if that will work for your scenario.
An other alternative is to use the file set syntax, especially if you want to use a dynamic value to determine the process. That would simply create an empty rowset:
#data = EXTRACT ..., date DateTime
FROM "/mydir/{date:yyyy}/{date:MM}/{date:dd}/data.csv"
USING ...;
#data = SELECT * FROM #data WHERE date == DateTime.Now.AddDays(-1);
... // continue processing #data that is empty if yesterday's file is not yet there
Having said that, you may want to check of your job orchestration framework (such as ADF) may be a better place to check for existence before submitting the job in the first place.
As to the try catch block: U-SQL itself is a script-level optimizable, declarative language where the plan gets generated and optimized at runtime over the whole script. Thus providing a dynamic TRY-CATCH is currently not available, since it would severely impact the ability to optimize the script (e.g., you cannot move predicates or column pruning outside of a try-catch block). Also TRY/CATCH can lead to some very hard to understand and debug code, especially if it is used to mimic procedural workflows in an otherwise declarative environment.
However, you can use try/catch inside your C# functions without problems if you need to catch C# runtime errors.
FILE.EXISTS() always returns True when executed locally. However, it works when executing against Azure Data Lake.
Tried MSDN example and the following returns True, True
DECLARE #filepath_good = "/Samples/Data/SearchLog.tsv";
DECLARE #filepath_bad = "/Samples/Data/zzz.tsv";
#result =
SELECT FILE.EXISTS(#filepath_good) AS exists_good,
FILE.EXISTS(#filepath_bad) AS exists_bad
FROM (VALUES (1)) AS T(dummy);
OUTPUT #result
TO "/Output/FileExists.txt"
USING Outputters.Csv();
I have Microsoft Azure Data Lake Tools for Visual Studio version 2.2.5000.0

premake5 adding new complex fields

I am trying to add a new premake5 field in my premake5 script but am having trouble understanding how to specify the field.kind .
I want to add a field that contains a list of (path, string ) pairs but can't work out how to specify the kind spec .
The documentation and examples are not particularly clear.
This is how I have registered my new field
premake.api.register( {
name = "mypathmappings",
scope = "config",
kind = "list:path:string", or "list:keyed:path:string"
}
)
and inside of a config scope I declare the field item like so
project myproject
mypathmappings { ["path/to/file1"] = "stringvalue1", ["path/to/file2"] = "stringvalue2"}
However when it comes to processing time I don't get what I'm expecting in the field:
function processpathmappings(cfg)
local pathmappings = cfg.mypathmappings
for path, value in pairs(pathmappings) do
--do something with the path and value but
--value is not a string as expected
end
end
Can someone explain how the complex kinds can be built up correctly from the field kinds registered in api.lua?
I get that "list:integer" specifies a list of integers but don't know how the "keyed" element works for example.
Right now, it is not possible to control the "kind" of the keys in a keyed value. The best you will be able to get with the current system is kind="keyed:string", which should give you the values (the strings) that you want, but the paths will not be processed by Premake (made absolute, etc.)
If it is feasible, you might want to flip it around to kind="keyed:path" and set the values like this:
mypathmappings { ["stringvalue1"] = "path/to/file1" }
But that relies on your string values being unique within a map.
In theory, Premake's field API could be extended to support kinds of keys; feel free to open a ticket or submit a pull request.

Can the Path assigned a SQLite DB be an arbitrary value?

In this blog post, some prerequisite code for getting started using SQLite in Windows Store Apps is given, for adding to the OnLaunched method of App.xaml.cs:
// Get a reference to the SQLite database
this.DBPath = Path.Combine(
Windows.Storage.ApplicationData.Current.LocalFolder.Path, "customers.sqlite");
My question is: Can I use any arbitrary value to replace the "customers.sqlite" part, or does it have to match something else in my code, such as the name of my table definition class (in my case "PhotraxCoreData.cs" which, according to Mr. Green's suggestion, I added below a newly-created "Models" folder)?
My understanding is that, once I've got those classes defined (I do), and the code above in App.xaml.cs, along with this there (adapted for my SQLite classes):
using (var db = new SQLite.SQLiteConnection(this.DBPath))
{
// Create the tables if they don't exist
db.CreateTable<PhotraxBaseData>();
db.CreateTable<PhotraxNames>();
db.CreateTable<PhotraxQueries>();
}
...SQLite tables based on those classes I specified will be created, and have the name "customers.sqlite" (provided I don't change it).
So, can I use:
this.DBPath = Path.Combine(
Windows.Storage.ApplicationData.Current.LocalFolder.Path, "platypus.sqlite");
...or must it be something like:
this.DBPath = Path.Combine(
Windows.Storage.ApplicationData.Current.LocalFolder.Path, "PhotraxCoreData.sqlite");
That database name is just a file name.
The directory must be accessible by your app, but the file name can be anything.
AS CL says, the file name can be anything the app has direct access to. Windows Store apps have limited access to the file system, so the sqlite database must be in either the apps install location (read only) or it's app data folder (read write). A common pattern is to ship a seed database in the app package and then copy it from the install location to app data on first use so it can be written to.

Resources