Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ SQL » SqlArray Join
SqlArray Join [message #4061] Wed, 19 July 2006 02:47 Go to next message
rbmatt is currently offline  rbmatt
Messages: 90
Registered: July 2006
Location: Tennesse, USA
Member

I just found U++ yesterday, so this is all new to me.

The program I am working on has a SqLite3 backend with two tables. One table references the other (like a foreign key). I was working on implementing this when I found the Join() functions. I could not, however, make these work as I expected. Are there any examples? It would be great to see the Address book example written with a SqLite backend.

Also, I'm not sure I even understand what SqlDetails does, much less how to use it. Can anyone shed some light on this?

Thanks.
Re: SqlArray Join [message #4062 is a reply to message #4061] Wed, 19 July 2006 07:27 Go to previous messageGo to next message
rbmatt is currently offline  rbmatt
Messages: 90
Registered: July 2006
Location: Tennesse, USA
Member

Ok, so after playing with it some more I figured it out somewhat.
My SqlArray's are now properly Join'ed and working as they should. Now how do I set the SqlArray to allow inserts, deletes, and modifications? I think for modifications I can do something like
EditString editDesc;
AddColumn("DESCRIPTION","Description").Edit(editDesc);

which seems to work ok.

I also have SqlDetail setup to populate some EditStrings with the values. Now how can I make it so edits to these are saved back to the database?

[Updated on: Wed, 19 July 2006 07:28]

Report message to a moderator

Re: SqlArray Join [message #4068 is a reply to message #4062] Wed, 19 July 2006 11:11 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
To insert / remove rows, use

SqlArray arr;
.....
arr.Removing().Appending();


SqlDetails are reserved for quite rare 1:1 relations (means - one table is represented by SqlArray and for each line of this SqlArray there is _single_ record in another joined table, which is edited by SqlDetails Ctrls).

If what you want to do is to edit some columns of record of single table in SqlArray rows and rest in separate Ctrls, just add those Ctrls to SqlArray (ArrayCtrl::AddCtrl).

Important thing to understand here is that not every "index" in ArrayCtrl "row" corresponds to single column in ArrayCtrl (SqlArray is ArrayCtrl derivative). Some indicies can be bound to external Ctrls, some can be completely hidden and respectively, some columns of ArrayCtrl can "merge" more indicies (e.g. you have YEAR, MONTH and DAY columns in your database and you want to display them in single SqlArray column).

Mirek
Re: SqlArray Join [message #4081 is a reply to message #4068] Wed, 19 July 2006 17:07 Go to previous messageGo to next message
rbmatt is currently offline  rbmatt
Messages: 90
Registered: July 2006
Location: Tennesse, USA
Member

luzr wrote on Wed, 19 July 2006 05:11

If what you want to do is to edit some columns of record of single table in SqlArray rows and rest in separate Ctrls, just add those Ctrls to SqlArray (ArrayCtrl::AddCtrl).

Ok, I tried that but there are a few problems. The control I added is not automatically populated with the value from the database- should it be or do I have to do this manually?
This is why I was using SqlDetail, I have a 1-to-1 because I am editing the same row on the same table. Maybe not what it was designed for, but it seems to work here.

I'm sure I'll have some more questions in a little bit.

Let me also add that I had to do some core hacking to even get it to compile (I'm using the Win32 package that includes MinGW). The SqLite3 package referenced the DocTypes package which complained about a missing DocTypes.h. I removed those dependencies. It then had problems with ambiguous calls that I resolved by adding TRUE to them.
Re: SqlArray Join [message #4082 is a reply to message #4081] Wed, 19 July 2006 17:13 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Quote:


Ok, I tried that but there are a few problems. The control I added is not automatically populated with the value from the database- should it be or do I have to do this manually?



It should be. How are you trying that? The right approach is

SqlArray table;
...
table.AddCtrl(COLUMNID, myctrl);


Quote:


This is why I was using SqlDetail, I have a 1-to-1 because I am editing the same row on the same table. Maybe not what it was designed for, but it seems to work here.



Yes, it should. But it is unnecessary complex Wink

Quote:


Let me also add that I had to do some core hacking to even get it to compile (I'm using the Win32 package that includes MinGW). The SqLite3 package referenced the DocTypes package which complained about a missing DocTypes.h. I removed those dependencies. It then had problems with ambiguous calls that I resolved by adding TRUE to them.


Strange, what U++ version?

Mirek
Re: SqlArray Join [message #4086 is a reply to message #4082] Wed, 19 July 2006 18:36 Go to previous messageGo to next message
rbmatt is currently offline  rbmatt
Messages: 90
Registered: July 2006
Location: Tennesse, USA
Member

luzr wrote on Wed, 19 July 2006 11:13

It should be. How are you trying that? The right approach is
SqlArray table;
...
table.AddCtrl(COLUMNID, myctrl);


I have the SqlArray named "CListView" on a TabCtrl named "tab" with a tab named "list". I used the designer to add a StringEdit called "strName1" to the list layout.
list.CListView.AddCtrl("NAME",list.strName1);

I eventually want to move the controls to a different tab, but I have them here for testing.
When I navigate to different rows, it does look like the control might be refreshing, but there is nothing there. It will save data to the database, but not show it.
luzr wrote on Wed, 19 July 2006 11:13

Strange, what U++ version?

The current release, 605, with MinGW bundled.

Thanks for your help.
Re: SqlArray Join [message #4093 is a reply to message #4086] Wed, 19 July 2006 21:17 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
rbmatt wrote on Wed, 19 July 2006 12:36

luzr wrote on Wed, 19 July 2006 11:13

It should be. How are you trying that? The right approach is
SqlArray table;
...
table.AddCtrl(COLUMNID, myctrl);


I have the SqlArray named "CListView" on a TabCtrl named "tab" with a tab named "list". I used the designer to add a StringEdit called "strName1" to the list layout.
list.CListView.AddCtrl("NAME",list.strName1);

I eventually want to move the controls to a different tab, but I have them here for testing.
When I navigate to different rows, it does look like the control might be refreshing, but there is nothing there. It will save data to the database, but not show it.
luzr wrote on Wed, 19 July 2006 11:13

Strange, what U++ version?

The current release, 605, with MinGW bundled.

Thanks for your help.


Hard to say. Can you pack and send the whole package?
Re: SqlArray Join [message #4095 is a reply to message #4093] Wed, 19 July 2006 22:53 Go to previous messageGo to next message
rbmatt is currently offline  rbmatt
Messages: 90
Registered: July 2006
Location: Tennesse, USA
Member

luzr wrote on Wed, 19 July 2006 15:17

Hard to say. Can you pack and send the whole package?

Thanks for looking into it. Make sure you have simple2.db in the same folder you run it from.
  • Attachment: EzellApp4.zip
    (Size: 2.68KB, Downloaded 1778 times)
Re: SqlArray Join [message #4096 is a reply to message #4095] Wed, 19 July 2006 23:48 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
OMG:

#include <SqlCtrl/SqlArray.cpp>
#include <SqlCtrl/SqlDetail.cpp>


Should be

#include <SqlCtrl/SqlCtrl.h>

If I compile it that way (minus menu line commented out...), it works as I would expect.

BTW,

        // Kinda dumb that we have to do this
	// isn't there a better way?
	SqlId JOBID("JOBID");
	SqlId NAME("NAME");
	SqlId CUSTOMER_ID("CUSTOMER_ID");


You #define something like this (actually, in TSql package it is defined, but 'T' packages are somewhat 'less canonical'):

#define SQLID(x) const SqlId x(#x);

Anyway, the best way is to do db schema in U++ and get those defines for free.

Mirek

[Updated on: Wed, 19 July 2006 23:53]

Report message to a moderator

Re: SqlArray Join [message #4098 is a reply to message #4096] Thu, 20 July 2006 00:09 Go to previous messageGo to next message
rbmatt is currently offline  rbmatt
Messages: 90
Registered: July 2006
Location: Tennesse, USA
Member

Must be some Mirek Magic Razz
I made the change to the #include's and commented out my menu line (was testing and I forgot to remove it before I packaged it) but no luck. It still doesn't work here. Just a blank box that has some hidden functionality. Are you using MinGW to compile or MS VC++?
Re: SqlArray Join [message #4108 is a reply to message #4098] Fri, 21 July 2006 06:35 Go to previous messageGo to next message
rbmatt is currently offline  rbmatt
Messages: 90
Registered: July 2006
Location: Tennesse, USA
Member

I just installed MS VC++ Express and the Windows SDK, and I get the same results. The test name box is not populated with the name. Interesing though, if you enter something in the box, it will show that in the box for all subsequent times you view that row. It also saves that to the database.
Re: SqlArray Join [message #4112 is a reply to message #4108] Fri, 21 July 2006 14:33 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
OK, I hope I have found it.

The trouble is that bug exposes only in the start (you double-click on first record). I have tested after clicking to another row - there it was OK.

Anyway, the bug is caused by wrong placement of

	list.CListView.Query();


You are performing the query _before_ you join with detail. Query sets the cursor to the first row, means detail will not get loaded for this row....

Putting it at the end of constructor fixed the problem.

I have taken the oportunity a tried to improve the code a bit:

#include <CtrlLib/CtrlLib.h>
#include <SqlCtrl/SqlCtrl.h>
#include <plugin/Sqlite3/Sqlite3.h>

#define LAYOUTFILE <EzellApp4/EzellApp4.lay>
#include <CtrlCore/lay.h>

class EzellApp4 : public WithEzellApp4Layout<TopWindow> {
	WithListLayout<ParentCtrl> list;
	WithDetailLayout<ParentCtrl> detail;
	// The SQLite session

	// For editing
	EditDate editDate;
	EditString editDesc;
	EditString editCost;
	
public:
	typedef EzellApp4 CLASSNAME;
	void SwitchView();
	void CrossUpdate(int);
	EzellApp4();
};

void EzellApp4::CrossUpdate(int i)
{
	// In progress
	PromptOK("Yea, OK");
	list.CListView.Refresh();
}

EzellApp4::EzellApp4()
{
	// Setup the layouts
	CtrlLayout(*this, "Bean Heat and Air- Customer Files");
	CtrlLayout(list);
	CtrlLayout(detail);
	
	Sizeable();
	Zoomable();
	
	// Tell tab control what slave ctrls to use
	tab.Add(list, "Customers");
	tab.Add(detail, "Details");
	
	// Kinda dumb that we have to do this
	// isn't there a better way?
	SqlId JOBID("JOBID");
	SqlId NAME("NAME");
	SqlId CUSTOMER_ID("CUSTOMER_ID");
	
	// Setup primary customer list
	list.CListView.SetTable("CUSTOMERS");
	list.CListView.AddColumn("ID", "Id");
	list.CListView.HeaderObject().HideTab(0);
	list.CListView.AddColumn("NAME","Name");
	list.CListView.AddColumn("ADDRESS","Address");
	list.CListView.AddColumn("CSZ","City, State Zip");
	list.CListView.AddColumn("PHONE1","Phone 1");

	list.CListView.AddCtrl("NAME",list.strName1);
	list.CListView.AddCtrl("NAME", detail.strName);
	list.CListView.AddCtrl("ADDRESS", detail.strAddress);
	list.CListView.AddCtrl("CSZ", detail.strCSZ);

	list.CListView.SetOrderBy(NAME);
	list.CListView.WhenLeftDouble = THISBACK(SwitchView);
	
	detail.detailList.SetTable("JOBS");
	detail.detailList.AddColumn("JOBID","Id");
	detail.detailList.HeaderObject().HideTab(0);
	detail.detailList.AddColumn("DONEDATE","Date").Edit(editDate);
	detail.detailList.AddColumn("DESCRIPTION","Description").Edit(editDesc);
	detail.detailList.AddColumn("COST","Cost").Edit(editCost);
	detail.detailList.SetOrderBy(JOBID);
	detail.detailList.Join(CUSTOMER_ID, list.CListView);
	detail.detailList.Removing().Appending();

	list.CListView.Query();
}

void EzellApp4::SwitchView()
{
	tab.Set(1);
}

GUI_APP_MAIN
{
	Sqlite3Session session;

	if(!session.Open(ConfigFile("simple2.db"))) {
		Exclamation("Error opening the database file");
		return;
	}

#ifdef _DEBUG
	session.SetTrace();
	session.LogErrors(true);
#endif

	SQL = session;

	EzellApp4().Run();
}


Changes:

SqlDetails are really not necessary.

Most application do not use more than single DB engine, therefore it is a good ideal to define default session - you do not have to se it everywhere ("SQL=session").

Opening session in constructor is really bad thing Smile

BTW, is your database schema fixed in existing .db file, or is it a part of application you are developing? U++ has nice support for schemas... I would be happy to help you with that...

...because, in fact, it would not be a bad idea to finally add some nice SQL example to U++ Smile

Mirek
Re: SqlArray Join [message #4115 is a reply to message #4112] Fri, 21 July 2006 17:16 Go to previous messageGo to next message
rbmatt is currently offline  rbmatt
Messages: 90
Registered: July 2006
Location: Tennesse, USA
Member

luzr wrote on Fri, 21 July 2006 08:33

OK, I hope I have found it.
Thanks so much
luzr

Anyway, the bug is caused by wrong placement of
	list.CListView.Query();

You are performing the query _before_ you join with detail. Query sets the cursor to the first row, means detail will not get loaded for this row....

Putting it at the end of constructor fixed the problem.

Makes sense now Wink
luzr

I have taken the oportunity a tried to improve the code a bit:
Wow, thanks a million.
luzr

Most application do not use more than single DB engine, therefore it is a good ideal to define default session - you do not have to se it everywhere ("SQL=session").

Makes sense, good tip.
luzr

Opening session in constructor is really bad thing Smile

I guess this is also because there will only be one DB session but possibly multiple instances of my app window, also performance.
luzr

BTW, is your database schema fixed in existing .db file, or is it a part of application you are developing? U++ has nice support for schemas... I would be happy to help you with that...

I have lots of data that is currently in a spreadsheet. I will use php or perl to parse it out into a usable CSV or something similar. The actual structure of the DB can still be changed. The reason I did not opt for schemas was because I thought it might add a little extra (code size, memory usage) to the final product. If all the processing is pre-compile, it might be beneficial to add it in here. Advice?
luzr

...because, in fact, it would not be a bad idea to finally add some nice SQL example to U++ Smile

I'll be glad to offer my app as a tutorial and help write it.

Thanks again
Re: SqlArray Join [message #4117 is a reply to message #4115] Sat, 22 July 2006 07:42 Go to previous messageGo to next message
rbmatt is currently offline  rbmatt
Messages: 90
Registered: July 2006
Location: Tennesse, USA
Member

Ok, so I worked through several things today.
I added schema support so while in debug mode it will update my schema based on the .sch file. Then I use sch to automatically define all my SqlId's.
I found out why I was having a problem with data reverting to old states. Got that (mostly) fixed.
I don't think there is a way for me to manually make the changes to the database (short of actually writing the code Wink). What I mean is UpdateRow() is protected so I cannot call it. There are no member functions that say "write this to the db" that I see.
Also inserting does not seem to be working. I traced the code as best I could.
The program does a late insert but somehow it looks like it only wants to do an update. The update code looks like:
update CUSTOMERS set NAME = 'test', ADDRESS = NULL, CSZ = NULL, PHONE1 = NULL, NAME = 'test' where ID is NULL
Well, there is no entry where ID is NULL so nothing happens.
And to get the autonumber we need to set ID = NULL which it does not do.
I've attached my new version.
Thanks.
P.S. What are the lines in the DocEdit? Is there a way to turn that off?
Re: SqlArray Join [message #4122 is a reply to message #4115] Sun, 23 July 2006 19:15 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Quote:


luzr

Opening session in constructor is really bad thing Smile

I guess this is also because there will only be one DB session but possibly multiple instances of my app window, also performance.



The reson why it is bad thing is that if open fails, you will end with semiconstructed object...

Quote:


I have lots of data that is currently in a spreadsheet. I will use php or perl to parse it out into a usable CSV or something similar. The actual structure of the DB can still be changed. The reason I did not opt for schemas was because I thought it might add a little extra (code size, memory usage) to the final product.


Only a little - and it is also possible to exculde that using #ifdef _DEBUG

Mirek
Re: SqlArray Join [message #4124 is a reply to message #4122] Sun, 23 July 2006 19:49 Go to previous messageGo to next message
rbmatt is currently offline  rbmatt
Messages: 90
Registered: July 2006
Location: Tennesse, USA
Member

Hmm.. I thought my addition of schemas was working properly...

EDIT: nevermind, I think I got that sorted

[Updated on: Sun, 23 July 2006 19:55]

Report message to a moderator

Re: SqlArray Join [message #8450 is a reply to message #4117] Sat, 10 March 2007 18:44 Go to previous message
forlano is currently offline  forlano
Messages: 1185
Registered: March 2006
Location: Italy
Senior Contributor
rbmatt wrote on Sat, 22 July 2006 07:42

Ok, so I worked through several things today.
I added schema support so while in debug mode it will update my schema based on the .sch file. Then I use sch to automatically define all my SqlId's.
I found out why I was having a problem with data reverting to old states. Got that (mostly) fixed.
I don't think there is a way for me to manually make the changes to the database (short of actually writing the code Wink). What I mean is UpdateRow() is protected so I cannot call it. There are no member functions that say "write this to the db" that I see.
Also inserting does not seem to be working. I traced the code as best I could.
The program does a late insert but somehow it looks like it only wants to do an update. The update code looks like:
update CUSTOMERS set NAME = 'test', ADDRESS = NULL, CSZ = NULL, PHONE1 = NULL, NAME = 'test' where ID is NULL
Well, there is no entry where ID is NULL so nothing happens.
And to get the autonumber we need to set ID = NULL which it does not do.
I've attached my new version.
Thanks.
P.S. What are the lines in the DocEdit? Is there a way to turn that off?


Hello,

I was unable to compile the package with 2007.1.rc2.
Perhaps something changed during these months. Any hope to fix it? I remind I was able to compile it with old version. Now all the complains come from the .sch file.

Luigi
Previous Topic: ODBC ?
Next Topic: MS SQL Server connection possible?
Goto Forum:
  


Current Time: Mon Apr 29 08:55:00 CEST 2024

Total time taken to generate the page: 0.03303 seconds