C++ Builder XE3, IntraWeb, Display SQL Server database query results - c++

Our company is beginning development on an IntraWeb application which requires access to our SQL Server database(s). I am attempting to creating a very basic application to get one column of data from our database and display it... in any way possible. I have attempted many times to do this but have only seen failure. From what I see I can not even get query results. I am using C++ Builder XE3. This is what I am doing...
Create IntraWeb Application Wizard (Standalone)
Add #include "UserSessionUnit.h" to Unit1.cpp
Set IWServerController->ComInitialization to ciMultiThreaded
Drag TADOConnection to UserSessionUnit
Set ADOConnection1->ConnectionString using builder (Microsoft OLE DB Provider for SQL Server)
Drag TADOQuery to UserSessionUnit
Set ADOQuery1->Connection to ADOConnection1
Set ADOQuery1->SQL to "SELECT Column1 FROM Table1"
Drag TDataSource to UserSessionUnit
Set DataSource1->DataSet to ADOQuery1
Drag TIWDBGrid to Unit1
Set IWDBGrid1->DataSource to IWUserSession.DataSource1
Run the query when IWForm1 is created...
void __fastcall TIWForm1::IWAppFormCreate(TObject *Sender)
{
UserSession()->ADOQuery1->Open();
}
I imagine this should work. The application builds and runs with no errors, but displays only an empty grid...
I replicated this scenario in a C++ Builder VCL Forms Application and it worked no problems (used TDBGrid instead of TIWDBGrid, of course).
I have tried this with several "TIWDB" components to no avail.

Related

View creation works in Firebird 3.0 but not in version 4.0

I created a music database application a few years ago in C++ (Code::Blocks + wxWidgets + SQLAPI++) and Firebird as the database server (running as a service in classic mode) on the Windows platform (v10). It creates a SQL database with tables, views, triggers, generators.
So far, it has been running perfectly up to Firebird 3 (Latest version). Now Firebird 4.0 is out, I thought I try it out.
In order to narrow down on the problem, I created a new app that only creates the database, tables, triggers, generators,and only 2 views which are focused around the problem area.
The code for vew_AlbumDetails I use in my test app is:
CREATE VIEW vew_AlbumDetails (Album_Name, Album_NrSeconds)
AS
SELECT b.Album_Name, SUM(a.NumberOfSamples/NULLIF(b.SampleRate,-1))
FROM tbl_Tracks a
INNER JOIN tbl_AlbumNames b ON a.AlbumName_ID = b.ID
GROUP BY b.Album_Name
ORDER BY b.Album_Name;
The code for vew_ReportDetails I use in my test app is:
CREATE VIEW vew_ReportDetails (Album_Name, Album_NrSeconds)
AS
SELECT b.Album_Name, a.NumberOfSamples/NULLIF(b.SampleRate,-1)
FROM tbl_Tracks a
INNER JOIN tbl_AlbumNames b ON a.AlbumName_ID = b.ID
ORDER BY b.Album_Name;
When I create the database with Firebird 3 running as a service, and open it in FlameRobin, everything is OK. In VIEW vew_AlbumDetails, Album_NrSeconds type is BIGINT. (see image below)
When I create the database with Firebird 4 running as a service, and open it in FlameRobin, everything is NOT OK. In VIEW vew_AlbumDetails, Album_NrSeconds type is (16). (see image below)
In VIEW vew_ReportDetails, Album_NrSeconds type is BIGINT. This is OK (see image below)
In FlameRobin, I also manually added a new view (vew_Manual_Added_View) with the same code as for vew_AlbumDetails (except for the name). The code is shown in above image.
Strange is that the type for Album_NrSeconds is now DOUBLE PRECISION instead of (16) under Firebird 4 service or BIGINT under Firebird 3 service.
My problem is the following when running Firebird 4 as a service:
My Music app creates the database without errors, but with vew_AlbumDetails, Album_NrSeconds type as (16). It crashes without any error message when the vew_AlbumDetails is being used to show an overview of the stored albums. Album_NrSecondse being of type (16) is causing this.
There are 2 things I do not understand when using Firebird 4 as a service.
Why is Album_NrSecondse of type (16) when creating vew_AlbumDetails with my app?
Why is Album_NrSecondse of type (Double Precision) when the exactly same code is used for adding a view manually?
Is there a bug in Firebird 4.0 that causes this strange behaviour?, or do I need to adapt my code somehow?
I hope somebody can help me understand what causes the different behavior between Firebird 3.0 and 4.0, and sends me on the way to a solution.
I have added 'DataTypeCompatibility = 3.0' to both databases.conf and firebird.conf.
The datatype for Album_NrSeconds is now NUMERIC.
My application runs flawlessly under Firebird 4.0 as a service after these 2 edits.
Thank you Mark Rotteveel for your suggestion. Its much appreciated.

Creating Custom WMI classes for SCCM queries

I am working to create a custom WMI class for use with SCCM's device collection membership query rules to expose some organization specific information to SCCM for collection creation. I have managed to add a new class in with the MOF file below, and it shows up in the GUI as expected with the desired display name.
The only issue I believe I have left to solve is how to make the generated query work as expected. I know by default joins are not supported in WQL. However Microsoft seems to be using them regularly in these queries, and I have verified they work as expected outside of the application. Is there some sort of joining class I need to create to make this work? Is there some attribute to designate a property as a forigen key??
I have searched through the System Center Configuration Manager SDK documentation, and the WMI reference on the Windows Dev Center site for a few hours without much luck and would really appreciate any helpful input.
MOF File:
#pragma namespace ("\\\\.\\root\\sms\\site_lab")
[DisplayName("CMDB CI Computer")]
class SMS_G_System_MTS_cmdb_ci_computer : SMS_G_System
{
[key] uint32 ResourceID;
string asset_tag;
string dv_company;
string dv_cost_center;
string dv_location;
};
SCCM Generated Query:
select * from SMS_R_System inner join SMS_G_System_MTS_cmdb_ci_computer on SMS_G_System_MTS_cmdb_ci_computer.ResourceID = SMS_R_System.ResourceId
I am testing these commands with the Get-CimInstance command in powershell with the below results
Powershell:
This command returns the joined objects as expected.
Get-CimInstance -Namespace 'root\sms\site_lab' -Query 'select SMS_G_System_PROCESSOR.Architecture from SMS_R_System inner join SMS_G_System_PROCESSOR on SMS_G_System_PROCESSOR.ResourceId = SMS_R_System.ResourceId'
This command throws an "Invalid Query" Error.
Get-CimInstance -Namespace 'root\sms\site_lab' -Query 'select asset_tag from SMS_R_System inner join SMS_G_System_MTS_cmdb_ci_computer on SMS_G_System_MTS_cmdb_ci_computer.ResourceID = SMS_R_System.ResourceId'

wbemtest doesn't show certain data after executing a query

I have BitLocker enabled on my machine and I want to use the wbemtest.exe utility to view properties about the Bitlocker data.
According to the properties section at MSDN, some of the data that I want to retrieve are DeviceID, DriveLetter, PersistentVolumeID, and ProtectionStatus.
However, when I execute the query
SELECT * from Win32_EncryptableVolume
using wbemtest.exe, only one object gets returned, and that is BitLocker DeviceID. I also want this query to return the DriveLetter and the other properties. What do I do to retrieve these? The data should be there, because my C# app using System.Management is able to get data on the other properties without any trouble (by assigning the return value of a ManagementClass GetInstances() method to a a ManagementObjectCollection.)
It turns out that I am able to view the data I need quite simply by using the WMI Code Creator utility.
I found this information on windows-noob

SQLite database update in C++

I have an application where I show data from a database. In fact we can say it's a database editor.
Now I want to perform update/delete command on this opened database. Using the following commands, the database opens successfully.
int nRet = sqlite3_open(szFile, &mpDB);
From C# (.net api) I am able to update data from database
dbCmd5 = New SQLiteCommand(
"update Tbl_Tmp_Cal_Res Load_Time=5 WHERE Part_Index= 5", g_dbFlow);
dbCmd5.ExecuteNonQuery()
But from C++ I am getting error 5 (database is locked)
C++ code
int nRet = sqlite3_open(szFile, &mpDB);//database opened successfully.
sqlite3_exec(mpDB, "UPDATE query", 0, 0, &szError);//Error for this statement
Multithreading is not used in application.
Is the database used from another location in the code? Since something else clearly seems to have the database locked, I would guess that you're using the database from another location in the code and have forgotten to call sqlite3_finalize on a select statement or something similar.
maybe you have forgotten authentication step (username/password & etc)

Using MbUnit3's [Rollback] for unit testing NHibernate interactions with SQLite

Background:
My team is dedicated to ensuring that straight from checkout, our code compiles and unit tests run successfully. To facilitate this and test some of our NHibernate mappings, we've added a SQLite DB to our repository which is a mirror of our production SQL Server 2005 database. We're using the latest versions of: MbUnit3 (part of Gallio), System.Data.SQLite and NHibernate.
Problem:
I've discovered that the following unit test does not work with SQLite, despite executing without trouble against SQL Server 2005.
[Test]
[Rollback]
public void CompleteCanPersistNode()
{
// returns a Configuration for either SQLite or SQL Server 2005 depending on how the project is configured.
Configuration config = GetDbConfig();
ISessionFactory sessionFactory = config.BuildSessionFactory();
ISession session = sessionFactory.OpenSession();
Node node = new Node();
node.Name = "Test Node";
node.PhysicalNodeType = session.Get<NodeType>(1);
// SQLite fails with the exception below after the next line called.
node.NodeLocation = session.Get<NodeLocation>(2);
session.Save(node);
session.Flush();
Assert.AreNotEqual(-1, node.NodeID);
Assert.IsNotNull(session.Get<Node>(node.NodeID));
}
The exception I'm getting (ONLY when working with SQLite) follows:
NHibernate.ADOException: cannot open connection --->
System.Data.SQLite.SQLiteException:
The database file is locked database is locked
at System.Data.SQLite.SQLite3.Step(SQLiteStatement stmt)
at System.Data.SQLite.SQLiteDataReader.NextResult()
at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave)
at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.SQLite.SQLiteCommand.ExecuteNonQuery()
at System.Data.SQLite.SQLiteTransaction..ctor(SQLiteConnection connection, Boolean deferredLock)
at System.Data.SQLite.SQLiteConnection.BeginDbTransaction(IsolationLevel isolationLevel)
at System.Data.SQLite.SQLiteConnection.BeginTransaction()
at System.Data.SQLite.SQLiteEnlistment..ctor(SQLiteConnection cnn, Transaction scope)
at System.Data.SQLite.SQLiteConnection.EnlistTransaction(Transaction transaction)
at System.Data.SQLite.SQLiteConnection.Open()
at NHibernate.Connection.DriverConnectionProvider.GetConnection()
at NHibernate.Impl.SessionFactoryImpl.OpenConnection()
--- End of inner exception stack trace ---
at NHibernate.Impl.SessionFactoryImpl.OpenConnection()
at NHibernate.AdoNet.ConnectionManager.GetConnection()
at NHibernate.AdoNet.AbstractBatcher.Prepare(IDbCommand cmd)
at NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand cmd)
at NHibernate.Loader.Loader.GetResultSet(IDbCommand st, Boolean autoDiscoverTypes, Boolean callable, RowSelection selection, ISessionImplementor session)
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies)
at NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session, Object id, IType identifierType, Object optionalObject, String optionalEntityName, Object optionalIdentifier, IEntityPersister persister)
at NHibernate.Loader.Entity.AbstractEntityLoader.Load(ISessionImplementor session, Object id, Object optionalObject, Object optionalId)
at NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id, Object optionalObject, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.Load(Object id, Object optionalObject, LockMode lockMode, ISessionImplementor session)
at NHibernate.Event.Default.DefaultLoadEventListener.LoadFromDatasource(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.DoLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.ProxyOrLoad(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent event, LoadType loadType)
at NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType loadType)
at NHibernate.Impl.SessionImpl.Get(String entityName, Object id)
at NHibernate.Impl.SessionImpl.Get(Type entityClass, Object id)
at NHibernate.Impl.SessionImpl.Get[T](Object id)
D:\dev\598\Code\test\unit\DataAccess.Test\NHibernatePersistenceTests.cs
When SQLite is used and the [Rollback] attribute is NOT specified, the test also completes successfully.
Question:
Is this an issue with System.Data.SQLite's implementation of TransactionScope which MbUnit3 uses for [Rollback] or a limitation of the SQLite engine?
Is there some way to write this unit test, working against SQLite, that will rollback so as to avoid affecting the database each time the test is run?
This is not a real answer to you question, but probably a solution to solve the problem.
I use an in-memory implementation of sql lite for my integration tests. I build up the schema and fill the database before each test. The schema creation and initial data filling happens really fast (less then 0.01 seconds per test) because it's an in-memory database.
Why do you use a physical database?
Edit: response to answer about question above:
1.) Because I migrated my schema and data directly from SQL Server 2005 and I want it to persist in source control.
I recommend to store a file with the database schema in and a file or script that creates the sample data in source control. You can generate the file using sql server studion management express, you can generate it from your NHibernate mappings or you can use a tool like sql compare and you can probably find other solutions for this when you need it. Plain text files are stored easier in version control systems then complete binary database files.
2.) Does something about the in-memory SQLite engine differ such that it would resolve this difficulty?
It might solve your problems because you can recreate your database before each test. Your database under test will be in a the state you expect it to be before each test is executed. A benefit of that is there is no need to roll back your transactions, but I have run similar test with in memory sqllite and it worked as aspected.
Check if you're not missing connection.release_mode=on_close in your SQLite NHibernate configuration. (reference docs)
BTW: always dispose your ISession and ISessionFactory.
Ditch [Rollback] and use NDbUnit. I use this myself for this exact scenario and it has been working great.