ADOQuery on C++ Builder 6 and Windows 7 64bit - c++

I am having a weird problem using the TADOQuery component.
I currently work at a place where they are using Borland C++Builder applications that run on a Windows XP VM. So we want to move to Windows 7 and serve it as a terminal so employees can receive new machines with Windows 10 without the need to create Win XP VM on each machine again.
Currently the application uses BDE components and it works great on XP. We created a Win7 64bit VM for testing, and installed the necessary driver etc, but BDE just won't work. When I try to login through the SQL Explorer that comes with Borland, it just hangs. It sends the request but never gets a response. I spent more than a week trying to debug this issue, but didn't get anywhere with it.
Anyways, I gave up on BDE and wanted to try to change to ADO. So I started by simply creating a TDBGrid and fill it with data using ADO components. It worked great on both XP and Win7! So now I am trying to convert the applications' BDE components (TDataBase, TQuery, etc) to ADO components.
I came across an interesting issue when trying to use parameters. Here is a query example:
SELECT t1.SEC_CODE, t1.CODE, t1.CTRL_NUM, t1.CHECK_CODE,
t1.CHECK_NO, t1.CLIENT_ID, t1.AMOUNT, t1.TRANS_NO, decode(t2.prefix,null,t2.name,t2.name||', '||t2.prefix) as fullName,
t1.ENTRY_DATE, t1.DEPOSIT_DATE, t1.ACCT_COMMENT, t2.NAME, t2.PREFIX
FROM ACCOUNTING.ACCT_CHECK_IN t1, OISC.CLIENT t2
WHERE
(:BEN =1 OR (:BEN =0 AND t1.ENTRY_DATE=:DATE)
OR (:BEN =2 AND t1.DEPOSIT_DATE IS NOT NULL)
OR (:BEN =3 AND t1.DEPOSIT_DATE IS NULL)) AND
(:ALEX =1 OR (:ALEX =0 AND t1.ENTRY_DATE>=:DATE1 AND
t1.ENTRY_DATE<=:DATE2) OR (:ALEX =2 AND t1.DEPOSIT_DATE>=:DATE1
AND t1.DEPOSIT_DATE<=:DATE2))
AND T2.CLIENT_ID(+)=T1.CLIENT_ID
ORDER BY t1.SEC_CODE, t1.CHECK_CODE, fullName, t1.check_no
Please don't pay attention to the parameter names, it's a little funny for me but you guys won't be able to connect.
The first issue here is that even though some parameters are the same name, ADO sees them as individual parameters! So, if I do this:
checkload1->Parameters->ParamByName("BEN")->Value=0
ADO will not replace every occurrence of "BEN" with 0, and I end up with a result set of 0 records! Instead, I am using this:
checkload1->Parameters->Items[0]->Value = 0; // BEN param
checkload1->Parameters->Items[1]->Value = 0;
checkload1->Parameters->Items[3]->Value = 0;
checkload1->Parameters->Items[4]->Value = 0;
Basically, replacing every "BEN" parameter with 0 based on the parameter index.
This brings me results, but not right away.
So here is how it works: the application is a tree based user interface. There is a node that says "Today's Checks" and it displays today's checks when it is expanded. Great, now this works fantastic with BDE, and I only assign the parameter value once and it automatically replaces it wherever it sees "BEN", etc.
When using ADO components, I expand the "Today's Checks" node and the code runs though, loading the parameters, activating the query component and I get no results! So the node stays collapsed. If I click on the + sign again to expand the tree, it loads the checks! And it will load them every time after that.
So, in the application there is a date option that defaults to today's date. If I change that to yesterday's date, I still get today's checks... It's like the parameters aren't getting updated. And if I try to start with a different date at the very beginning, I don't get any results! It will bring results with today's date, but after that it won't accept a different date.
I debugged the code and the dates are changing, but for some reason the parameters aren't changing. Here is my code block:
checkload1->Filter="" ;
checkload1->Filtered=false ;
switch(params)
{
case 0: checkload1->Parameters->Items[0]->Value = 1; // BEN param
checkload1->Parameters->Items[1]->Value = 1;
checkload1->Parameters->Items[3]->Value = 1;
checkload1->Parameters->Items[4]->Value = 1;
// ALEX Param
checkload1->Parameters->Items[5]->Value = 0;
checkload1->Parameters->Items[6]->Value = 0;
checkload1->Parameters->Items[9]->Value = 0;
checkload1->SQL->Strings[13] = "AND t1.CHECK_STATUS NOT IN ('Refunded', 'Posted') ";
break ;
case 1: checkload1->Parameters->Items[0]->Value = 0; // BEN param
checkload1->Parameters->Items[1]->Value = 0;
checkload1->Parameters->Items[3]->Value = 0;
checkload1->Parameters->Items[4]->Value = 0;
checkload1->Parameters->ParamByName("DATE")->Value=FormatDateTime("dd-mmm-yyyy", Date()) ;
checkload1->SQL->Strings[13] = " ";
break ;
case 2: checkload1->Parameters->Items[0]->Value = 2; // BEN param
checkload1->Parameters->Items[1]->Value = 2;
checkload1->Parameters->Items[3]->Value = 2;
checkload1->Parameters->Items[4]->Value = 2;
//ALEX param
checkload1->Parameters->Items[5]->Value = 2;
checkload1->Parameters->Items[6]->Value = 2;
checkload1->Parameters->Items[9]->Value = 2;
checkload1->SQL->Strings[13] = "AND t1.CHECK_STATUS IN ('Deposited') ";
break ;
case 3: checkload1->Parameters->Items[0]->Value = 3; // BEN param
checkload1->Parameters->Items[1]->Value = 3;
checkload1->Parameters->Items[3]->Value = 3;
checkload1->Parameters->Items[4]->Value = 3;
//ALEX param
checkload1->Parameters->Items[5]->Value = 0;
checkload1->Parameters->Items[6]->Value = 0;
checkload1->Parameters->Items[9]->Value = 0;
checkload1->SQL->Strings[13] = "AND t1.CHECK_STATUS IN ('Held') ";
break ;
}
if(!mainform->date1->Checked){
checkload1->Parameters->Items[5]->Value = 1;
checkload1->Parameters->Items[6]->Value = 1;
checkload1->Parameters->Items[9]->Value = 1;
}
checkload1->Parameters->Items[7]->Value = FormatDateTime("dd-mmm-yyyy", fromdate);
checkload1->Parameters->Items[10]->Value = FormatDateTime("dd-mmm-yyyy", fromdate);
checkload1->Parameters->Items[8]->Value = FormatDateTime("dd-mmm-yyyy", todate);
checkload1->Parameters->Items[11]->Value = FormatDateTime("dd-mmm-yyyy", todate);
if(filters != "") checkload1->SQL->Strings[12] = filters;
else checkload1->SQL->Strings[12]=" " ;
checkload1->Prepared = true;
checkload1->Active=true ;
Can someone with experience advise me on this?
I know this is ancient stuff, but those programs were written literally 15-20 years ago, and they are moving to a web-based user interface, but that's still being built. Until then, I need to make the required changes/updates as part of my job.

Okay I got this to work!!
For anyone out there who is struggling with BDE to work on Windows 7 64 bit, here is a solution! Remember the database I am dealing with is Oracle 8i and Borland C++ applications built with C++ Builder 6.
Follow the photo and arrows. I tried to put each photo with its own comment but then this site said I can't post more than 2 links... To hell with them so I put all on one picture.
This TQuery for example is looking for bnetdata as the database. Great, in the next picture we add an ADOConnection component
Click on connection string that's highlighted.
Choose use connection string and click on build.
Select the highlighted provider then click next.
Check use data source name then click the arrow to select one. Note that you will later enter the user name and password and check allow for saving password.
Select the same data source that the BDE components are using. Note that this is one of the sources under your system DSN in the ODBC Administrator. If it's not there, then create one.
Here is a shot from the ODBC Administrator. Note that this is still XP environment. You will need to create the same data source (bnetdata in my case) in the windows 7 machine.
Now click on advanced and check readwrite option from the list.
After you click OK on the ADOConnection component, as you see now in the object inspector. Look at the highlighted areas. Now, we need to set connected property to true. When you do that, it will ask you to log in to the database. Enter the user name and password and click OK. The connection property will now become true. After that you need to set the LoginPrompt property to false. Now click save on the project.
So let's say you have BDE database component too, click on it and then clear alias name and driver name and then put your database name under databaseName property (in my case it's bnetdata).
Save the project and compile in XP. Copy the application and paste it in Windows 7 machine and double click it and it will work! I have successfully converted all the applications to work on Windows 7. The hardest part was to get Borland installed and to get Windows 7 to recognize Oracle ODBC Driver under the Drivers tab in the ODBC Administrator.
Again, SQL Explorer that comes with Borland install is not going to work. So, I will still need to develop in my Windows XP VM but users can use the application in Windows 7 VM served as a terminal on a Windows server... Works for me!!
Hope this helps someone!
EDIT:
I also tried Microsoft OLE DB Provider for Oracle in the ADOConnection and it also worked. Didn't see a measurable impact on speed or performance. Both seem to perform the same way. I'm just surprised how adding the ADOConnection component allowed the application to connect to the database and work like it does in XP!
Also just to clear things up, you will not need to change the BDE components in the application. Only need to add the ADOConnection and all other components stay the same (BDE components). I was trying to convert to using ADO components but there is no need anymore.

Related

how to close an order using the api MT4-Manager-API without specifying the closing price?

I am using the MT4-Manager-API Api, and I want to close trades at the current market price, without having to specify it.
So far I have been able to close a previously opened trade but specifying the closing price as follows:
c++ code
TradeTransInfo info = { 0 };
info.type = TT_BR_ORDER_CLOSE;
info.order = 98492174;
info.price = 1.30263; // I don't want to have to specify the price.
info.volume = 1;
ExtManager->TradeTransaction(&info);
I also don't want to switch to pumping mode.
EDIT
The main reason for not wanting to specify the closing price is because I can't find a way to obtain it by making an API call, without switching to pumping mode.
By getting the current price of the symbol, I can then solve my problem and use the code shown.

Sitecore 7 Analytics increase engagement value programatically

I am working on implementing sitecore DMS in 7.2 and I'm having one main issue for which I seem to be having a hard time finding an answer. I have some goals and events set up and I am attempting to set one off through the Analytics API. The event is being logged as being set off in the PageEventId database, but what I am trying to do is add Engagement Value to the current visit/visitor.
I'm looking to update the Value field in the Visits database for the current visit. Here is what I am currently using:
public static void triggerGoal(ID goal)
{
if (Tracker.IsActive && Tracker.CurrentPage != null)
{
Sitecore.Data.Items.Item goalToTrigger = Sitecore.Context.Database.GetItem(goal);
if (goalToTrigger != null)
{
Sitecore.Analytics.Data.Items.PageEventItem reg = new Sitecore.Analytics.Data.Items.PageEventItem(goalToTrigger);
Sitecore.Analytics.Data.DataAccess.DataSets.VisitorDataSet.PageEventsRow eventData =
Tracker.CurrentPage.Register(reg);
eventData.Data = goalToTrigger["Description"];
Tracker.Submit();
}
}
}
This updates the PageEventId database properly, noting that the event has been triggered, but this adds no Engagement Value to the Visits database, regardless of how many engagement points are assigned to the Goad that is being triggered.
I've tried various ways of getting the API to update this field, but nothing has worked for me so far. Here are a bunch of the different things I've tried:
Tracker.CurrentVisit.BeginEdit();
Tracker.CurrentVisit.Value += 3; //look up value here instead of hardcoding. Create new PageEventItem class to get field ID.
Tracker.CurrentVisit.AcceptChanges();
Tracker.CurrentVisit.EndEdit();
Tracker.CurrentVisit.Load();
Tracker.CurrentPage.BeginEdit();
Tracker.CurrentPage.Visit.Value += 3;
Tracker.CurrentPage.AcceptChanges();
Tracker.CurrentPage.EndEdit();
Tracker.Visitor.CurrentVisit.BeginEdit();
Tracker.Visitor.CurrentVisit.Value += 3;
Tracker.Visitor.CurrentVisit.AcceptChanges();
Tracker.Visitor.CurrentVisit.EndEdit();
Tracker.Visitor.CurrentVisit.Load();
Tracker.CurrentVisit.CurrentPage.Visit.BeginEdit();
Tracker.CurrentVisit.CurrentPage.Visit.Value += 3;
Tracker.CurrentVisit.CurrentPage.Visit.AcceptChanges();
Tracker.CurrentVisit.CurrentPage.Visit.EndEdit();
Tracker.CurrentVisit.CurrentPage.Visit.Load();
Tracker.CurrentVisit.CurrentPage.VisitorsRow.BeginEdit();
Tracker.CurrentVisit.CurrentPage.VisitorsRow.Value += 3;
Tracker.CurrentVisit.CurrentPage.VisitorsRow.AcceptChanges();
Tracker.CurrentVisit.CurrentPage.VisitorsRow.EndEdit();
I've used different combinations of using the AcceptChanges() and BeginEdit() EndEdit() and Load() functions, as I'm not completely sure what they each do, but either way, none of them update the Value field.
I am trying to avoid doing a custom SQL query to update this field, I'm trying to figure out how to do it through the built-in Sitecore Analytics API. Can anyone help me figure out how to update this field?
The following works fine for me, are you waiting long enough to see the value written for the visit?
if (Tracker.IsActive)
{
Tracker.CurrentVisit.Value += 3;
}
No need to BeginEdit, AcceptChanges, EndEdit, etc.
What you've done should work so long as you have set up your goal correctly in Sitecore. I like to mirror sitecore's default goals, and create goals of the "Page Event" template. Make sure that you've assigned the goal to your content item Analyze Tab -> Goals -> [select your goal from checkbox list]. If you're going to set the CurrentVisit value, I suggest using the line below to prevent hardcoding the engagement point values.
//This line will add points specified in Content Editor
Tracker.CurrentVisit.Value += int.Parse(reg.Points);
This document explains how to set up your goals the correct way. And if you follow it, your code will work the way you have it, reporting the value specified in the Content Editor without setting CurrentVisit.Value.
Sitecore SDN - Marketing Operations Cookbook

Issue with CQN registration getting dropped implictly

Using custom C++ OCI wrappers, I can successful register a CQN C++ callback-based registration, but it appears that somehow the subscription is dropped right away, behind my back. I get no call back on simple DMLs. If I try to unregister that subscription, for which register() worked just fine, I get ORA-29970: Specified registration id does not exist.
I'm running this test on a Win7 (64-bit) box, running a local 11.2.0.1.0 Oracle Server, and I connect with a C++ client app built against instantclient-11.2.0.2.0 that runs on that same machine.
I tried setting OCI_ATTR_SUBSCR_TIMEOUT explicitly to 0, to no avail.
I checked the job_queue_processes instance param to make sure it's not 0 (it's 1000).
Of course, the user/schema I'm connecting with has been granted CHANGE NOTIFICATION
I'm running out of ideas on this issue, and I would appreciate some insights on what else I could try or check.
I'm starting to wonder if CQN needs to be activated somehow. My DBA skills are close to nonexistent, this is a stock install of 11gR1 on Windows using the installer, with no special configurations or customization done at all.
Thanks, --DD
Update #1
A colleague successfully ran that same test, and he ran it using the server-provided oci.dll. I tried that (I build using instantclient, but forced the PATH at runtime: Path=D:\oracle\product\11.2.0\dbhome_1\BIN;$(Path) in VS Property Page> Debugging> Environment), and indeed the CQN test works! We still haven't figured out whether the slight version difference between client and server, or using instantclient (the Light variant by the way) vs a full client vs a server install is the real culprit.
But it is bad news that a newer instantclient does not support CQN...
Update #2
I've tried all 6 combinations of instantclient Light (65 MB) or Normal (150 MB) in versions 12.2.0.(1|2|3).0 on Win64, and none of them worked. Haven't tested the Full Client yet, nor have we tested on Linux just yet.
Environment_var cqn_env = Environment::create(OCI_EVENTS + OCI_OBJECT);
Connection_var cqn_conn = Connection::logon2(...);
Subscription sub(cqn_conn, "cqn_test", OCI_SUBSCR_NAMESPACE_DBCHANGE);
sub.set<attr::SUBSCR_CALLBACK>( &cqn_callback_func );
sub.set<attr::SUBSCR_CQ_QOSFLAGS>( OCI_SUBSCR_CQ_QOS_QUERY );
try {
sub.register_self();
} catch (const OracleException& ex) {
BOOST_REQUIRE(ex.error_code && *ex.error_code == 29972);
cerr << "\nSKIPPED: test requires CHANGE NOTIFICATION privilege" << endl;
return;
}

How to obtain display devices information regardless of session?

I using EnumDisplayDevices that give me obtain information about the display devices in the current session.
But i need information about the display devices regardless of session. Because i create some windows service application (System process).
Does anybody know some alternative for this code:
vncDesktop::GetNrMonitors()
{
if(OSversion()==3 || OSversion()==5) return 1;
int i;
int j=0;
helper::DynamicFn<pEnumDisplayDevices> pd("USER32","EnumDisplayDevicesA"); // it's EnumDisplayDevices function
if (pd.isValid())
{
DISPLAY_DEVICE dd;
ZeroMemory(&dd, sizeof(dd));
dd.cb = sizeof(dd);
for (i=0; (*pd)(NULL, i, &dd, 0); i++)
{
if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
if (!(dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))j++;
}
}
return j;
}
Thanks in advance!
sources below
Well, the reason why this doesn't work is because session 0 isn't connected to a console. What's more, because many more video settings are per user on Windows 7 it would be bad to assume that anything you get from one user even applies to another user.
You could also try to find the display monitors in the registry.
The display monitors should be stored here:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\DISPLAY
The class GUID for display monitors is {4D36E96E-E325-11CE-BFC1-08002BE10318}. you can try to find the monitors in system using the Setup API (SetupDiGetClassDevs, ...)
If you are coding specifically for Win7 and later, you might want to have a look at QueryDisplayConfig and related functions.
Sources
EnumDisplayDevices function not working for me
http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/4384f8d2-c429-410b-87e4-1e031ddc8167
I found solution for this issue. Only need create process user - System and SessionID - some user. And then all working fine.

SharePoint Web Services. Using UserPofileService.GetUserProfileByName. After SP upgrade... failing

The below web services code has worked properly for me for over a year. We have updated our SharePoint servers, and now the below code throws an exception (at the bottom line of code) "Object reference not set to an instance of an object"
UserProfileWS.UserProfileService userProfileService = new UserProfileWS.UserProfileService();
userProfileService.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
string serviceloc = "/_vti_bin/UserProfileService.asmx";
userProfileService.Url = _webUrl + serviceloc;
UserProfileWS.PropertyData[] info = userProfileService.GetUserProfileByName(null);
EDIT: The service is still there. I browse http:///_vti_bin/UserProfileService.asmx, and the information for the service is still there, including the full description of the GetUserProfileByName call.
EDIT2: This does appear to be due to a change in SharePoint. I loaded a previous version of my software (known to be working), and it exhibits the same erroneous behavior.
try
UserProfileWS.PropertyData[] info = userProfileService.GetUserProfileByName(userName);
as specified http://msdn.microsoft.com/en-us/library/microsoft.office.server.userprofiles.userprofileservice.getuserprofilebyname(v=office.12).aspx
When was the farm updated? Was the WSS updates installed before the MOSS updates? If you believe it to be a problem as a result of infrastructure updates, build a test farm and try the code against pre-updates (go back as far as a year ago to start off).