|
|
Home » U++ Library support » U++ SQL » Prefix to prevent name clash in SQL: SqlId, variables, tables, ...
Prefix to prevent name clash in SQL: SqlId, variables, tables, ... [message #14170] |
Sun, 17 February 2008 13:40 |
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"), .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 458 times)
-
Attachment: sch_model.h
(Size: 3.76KB, Downloaded 500 times)
-
Attachment: sch_source.h
(Size: 3.62KB, Downloaded 723 times)
-
Attachment: Sql.cpp
(Size: 15.26KB, Downloaded 575 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 #28361 is a reply to message #17171] |
Mon, 30 August 2010 15:45 |
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
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.
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.
|
|
|
Goto Forum:
Current Time: Fri Sep 20 19:14:52 CEST 2024
Total time taken to generate the page: 0.04249 seconds
|
|
|