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 » Prefix to prevent name clash in SQL: SqlId, variables, tables, ...
icon3.gif  Prefix to prevent name clash in SQL: SqlId, variables, tables, ... [message #14170] Sun, 17 February 2008 13:40 Go to next message
mingodad is currently offline  mingodad
Messages: 53
Registered: February 2008
Location: Spain
Member
Today I was converting one application to upp 2008.1 and found that the actual system of parse database schema can generate name clash:

TABLE_(CURRENCIES)
INT_ (CURRENCY)
END_TABLE

The above will generate a name clash:
----------
main.cpp
In file included from d:\upp\uppsrc/Sql/sch_model.h:162,
from d:\upp\uppsrc/plugin/sqlite3/Sqlite3Schema.h:82,
from d:\upp\uppsrc/Sql/sch_header.h:45,
from d:\MyApps\DADBiz\/DADBiz.h:17,
from d:\MyApps\DADBiz\main.cpp:1:
d:\MyApps/DADBiz/dadbiz.sch:33: error: 'Upp::SqlId CURRENCY' redeclared as different kind of symbol
d:\upp\mingw\include/oaidl.h:113: error: previous declaration of 'typedef union CY CURRENCY'
In file included from d:\upp\uppsrc/Sql/sch_model.h:162,
from d:\upp\uppsrc/plugin/sqlite3/Sqlite3Schema.h:82,
from d:\upp\uppsrc/Sql/sch_source.h:6,
from d:\MyApps\DADBiz\/DADBiz.h:18,
from d:\MyApps\DADBiz\main.cpp:1:
d:\MyApps/DADBiz/dadbiz.sch:33: error: 'Upp::SqlId CURRENCY' redeclared as different kind of symbol
d:\upp\mingw\include/oaidl.h:113: error: previous declaration of 'typedef union CY CURRENCY'
----------
[FEATURE REQUEST]
So I studied the source code and end up with some modifications that allow us to specify a prefix to the generated symbols with a definition of one preprocessor macro:

#define SCHEMA_PREFIX_CPP _ANY_PREFIX_YOU_LIKE_

And after that any reference to tables or fields should be done as:

dbList.AddKey(_ANY_PREFIX_YOU_LIKE_CURRENCY);
dbList.SetTable(_ANY_PREFIX_YOU_LIKE_CURRENCIES);
dbList.AddColumn(_ANY_PREFIX_YOU_LIKE_CURRENCY, t_("Id"), Cool.SetFormat("%8>d");
dbList.SetOrderBy(_ANY_PREFIX_YOU_LIKE_CURRENCY).Limit(100);

It doesn't break any application that already works, because without defining SCHEMA_PREFIX_CPP all generated symbols remain as before.

In this process I've found a bug in GCC when joining string in macros, in some cases it adds a space betwen the tokens, that's why the macro ADD_SCHEMA_PREFIX_CPP2 was created.

I've sending attached the files I've modified.

I'll hope it will be usefull to others and probably be included in the official distribution too !

Thanks for all of you that help develop this fantastic tool !

If you need more explanations, ask me !

Ps:
[FEATURE REQUEST]
As well to allow applications made with upp to work with databases, tables generated by other programs that doesn't create table and record fields names in uppercase (commonly lowercase) a patch to sql.cpp to make comparisons after convert field names retrieved fron queries to upper case.

Instead of:
// sql.cpp line 254
Value Sql::operator[](SqlId id) const {
String s = ~id;
for(int i = 0; i < cn->info.GetCount(); i++)
if(cn->info[i].name == s)
return operator[](i);
return Value();
}

Use this :

Value Sql::operator[](SqlId id) const {
String s = ~id;
for(int i = 0; i < cn->info.GetCount(); i++)
{
String sb = ToUpper(cn->info[i].name);
if(sb == s)
return operator[](i);
}
return Value();
}
  • Attachment: sch_header.h
    (Size: 1.66KB, Downloaded 429 times)
  • Attachment: sch_model.h
    (Size: 3.76KB, Downloaded 455 times)
  • Attachment: sch_source.h
    (Size: 3.62KB, Downloaded 705 times)
  • Attachment: Sql.cpp
    (Size: 15.26KB, Downloaded 556 times)

[Updated on: Tue, 19 February 2008 22:10]

Report message to a moderator

Re: Prefix to prevent name clash in SQL: SqlId, variables, tables, ... [message #14201 is a reply to message #14170] Tue, 19 February 2008 23:42 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
OK, why not. Path accepted.

Only I have rather placed ToUpper to Execute -> that way we will avoid ToUpper in each row fetch... (Equality comparison is fast, ToUpper is not...):

bool Sql::Execute() {
	SqlSession &session = GetSession();
	if(session.traceslow < INT_MAX)
		cn->starttime = GetTickCount();
	if(session.usrlog)
		UsrLogT(9, cn->statement);
	Stream *s = session.GetTrace();
	if(s) {
#ifndef NOAPPSQL
		if(this == &AppCursor())
			*s << "SQL* ";
#endif
		*s << cn->statement << '\n';
	}
	session.GetStatus().Statement(cn->statement);
	session.PassStatus(ActivityStatus::EXECUTING);
	bool b = cn->Execute();
	session.GetStatus().Time(GetTickCount() - cn->starttime);
	session.PassStatus(ActivityStatus::END_EXECUTING);
	if(!b) {
		if(s) {
			*s << "## ERROR: " << session.GetLastError() << '\n';
		}
		session.GetStatus()
			.Error(session.GetLastError())
			.ErrorCode(session.GetErrorCode())
			.ErrorCode(session.GetErrorCodeString());
		session.PassStatus(ActivityStatus::EXECUTING_ERROR);
	}
	for(int i = 0; i < cn->info.GetCount(); i++)
		cn->info[i].name = ToUpper(cn->info[i].name);
	return b;
}



(please check)

BTW, was your suggestion based on real problems or do you just want to play safe?

Mirek
Re: Prefix to prevent name clash in SQL: SqlId, variables, tables, ... [message #17135 is a reply to message #14170] Wed, 30 July 2008 17:57 Go to previous messageGo to next message
WebChaot is currently offline  WebChaot
Messages: 53
Registered: September 2006
Location: Austria, Vienna
Member
Hi Mirek!

I found this article in forum related to my current problem:

I need to create grids (arrayctrl) via database tables. But because of these lines

for(int i = 0; i < cn->info.GetCount(); i++)
cn->info[i].name = Toupper(cn->info[i].name);

i allways get the column headers in upper case. Is it possible to put switch to suppress this auto-uppercase functionality?

WebChaot
Re: Prefix to prevent name clash in SQL: SqlId, variables, tables, ... [message #17171 is a reply to message #17135] Fri, 01 August 2008 10:07 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
WebChaot wrote on Wed, 30 July 2008 11:57

Hi Mirek!

I found this article in forum related to my current problem:

I need to create grids (arrayctrl) via database tables. But because of these lines

for(int i = 0; i < cn->info.GetCount(); i++)
cn->info[i].name = Toupper(cn->info[i].name);

i allways get the column headers in upper case. Is it possible to put switch to suppress this auto-uppercase functionality?

WebChaot


Hm, I am afraid it is not the right approach.

Maybe we could add the name in the "original form" to ColumnInfo?

Mirek
Re: Prefix to prevent name clash in SQL: SqlId, variables, tables, ... [message #28361 is a reply to message #17171] Mon, 30 August 2010 15:45 Go to previous message
sevenjay is currently offline  sevenjay
Messages: 30
Registered: October 2008
Location: Taiwan
Member
I have another opinion on this.
When you create tables/columns with lower-case names, set SqlID like
SqlId TITLE("Title");

It will not match the table/column name "Title" because it will be "TITLE" in cn->info[i].name.
That is not convenient to force user to set SqlID all upper case.
SqlId TITLE("TITLE");


I think it could be case insensitive equality comparison.

if(cn->info[i].name == s) 

could be
if( 0 == s.CompareInsensitive(~(cn->info[i].name))) 

The method CompareInsensitive maybe like this
template <class B>
int AString<B>::CompareInsensitive(const tchar *b) const
{
	const tchar *a = B::Begin();
	const tchar *ae = End();
	for(;;) {
		if(a >= ae)
			return *b == 0 ? 0 : -1;
		if(*b == 0)
			return 1;
		int q = cmpval__(*a) - cmpval__(*b);
		if( (cmpval__('a') < cmpval__(*a) && cmpval__(*a) < cmpval__('z')) || 
		    (cmpval__('A') < cmpval__(*a) && cmpval__(*a) < cmpval__('Z')) )
			if(q == cmpval__('a') - cmpval__('A') || q == cmpval__('A') - cmpval__('a'))
				q = 0;
		if(q)
			return q;
		
		*a++;
		*b++;
	}
}

I tried it's OK.
But I am not sure if it is faster than ToUpper.
Previous Topic: transactions and sql
Next Topic: Some questions around SQlite3
Goto Forum:
  


Current Time: Thu Mar 28 12:53:45 CET 2024

Total time taken to generate the page: 0.02308 seconds