C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Ugly C looking code

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Jim Langston
Guest





PostPosted: Sat Aug 26, 2006 4:17 am    Post subject: Ugly C looking code Reply with quote



I've been working on a project to map a MySQL database to a C++ class.
Well, I actually got it to work, but some if it I just feel is exceptionally
ugly. For example, in my operator<< override:

template<typename T>
CMySQLTable& operator<<(const T& ClassTable)
{
/**/
}

I have a switch statement and code that looks like this:

switch ( ThisField.FieldType() )
{
case SQL_FieldType_Unknown:
std::cerr << " SQL_FieldType_Unknown: Error!" << std::endl;
assert(false);
break;

case SQL_FieldType_VarChar:
ThisField = *reinterpret_cast<const std::string*>( reinterpret_cast<const
char*>( &ClassTable ) + ThisOffset.Offset );
break;

case SQL_FieldType_Int:
ThisField = *reinterpret_cast<const int*>( reinterpret_cast<const
char*>( &ClassTable ) + ThisOffset.Offset );
break;

case SQL_FieldType_UnsignedInt:
ThisField = *reinterpret_cast<const unsigned int*>(
reinterpret_cast<const char*>( &ClassTable ) + ThisOffset.Offset );
break;

case SQL_FieldType_Bool:
ThisField = *reinterpret_cast<const bool*>( reinterpret_cast<const
char*>( &ClassTable ) + ThisOffset.Offset );
break;

/**/
}

It's the complicated casts that I find ugly. And in the operator>> override
it's just as bad, if not worst.

template<typename T>
CMySQLTable& operator>>(T& ClassTable)
{
/**/
}

switch ( ThisField.FieldType() )
{
case SQL_FieldType_Unknown:
std::cerr << " SQL_FieldType_Unknown: Error!" << std::endl;
assert( false );
break;

case SQL_FieldType_VarChar:
*reinterpret_cast<std::string*>( reinterpret_cast<char*>( &ClassTable ) +
ThisOffset.Offset ) = ThisField.Value();
break;

case SQL_FieldType_Int:
*reinterpret_cast<int*>( reinterpret_cast<char*>( &ClassTable ) +
ThisOffset.Offset ) = StrmConvert<int>( ThisField.Value() );
break;

case SQL_FieldType_UnsignedInt:
*reinterpret_cast<unsigned int*>( reinterpret_cast<char*>( &ClassTable )
+ ThisOffset.Offset ) = StrmConvert<unsigned int>( ThisField.Value() );
break;

case SQL_FieldType_Bool:
*reinterpret_cast<bool*>( reinterpret_cast<char*>( &ClassTable ) +
ThisOffset.Offset ) = ThisField.Value() == "0" ? false : true;
break;
/**/
}

Can you think of a cleaner way to do this, or is this the way I'm stuck with
just because of what I'm doing (working with pointers and offsets).

What I'm doing, and it works in test, is I have a class include a subclass
in which I map the variables I want to pull from the database.

void CCharFieldMap::SetMap( CCharacter* Base )
{
SetBase( Base );
SetOffset( "Version", Base->Version );
SetOffset( "Name", Base->Name );
SetOffset( "Password", Base->Password );
SetOffset( "Avatar", Base->Avatar );
SetOffset( "Race", *reinterpret_cast<unsigned int*>( &Base->Race ) );
SetOffset( "Sex", *reinterpret_cast<unsigned int*>( &Base->Sex ) );
SetOffset( "GM", Base->GM );
/**/
}

My overrides for << and >> look at this instance that contains information
about the variables (Type of variable, offset into class) and transfer data
back and forth using the base address of the passed reference and the
offsets.

It's the only way I could find to do it, and right now it seems it will be
extremely easy to use for the user (me) for new classes. No longer do I
have to go through SQL schenanigans to pull data to/from databases, I can
simply do code like:

if ( ! PlayerTable.init( "192.168.1.100", "serpardum", "somepassword",
"abyssal", "players", 3307 ) )
{
std::cerr << "Initialization failed" << std::endl;
std::string wait;
std::getline( std::cin, wait );

return 1;
}

if ( ! PlayerTable.LoadTable( "Name", "Serpardum" ) )
{
std::cout << "Serpardum not found" << std::endl;
return 1;
}

PlayerTable >> Player;

which would open my MySQL database, load the record where the Name ==
Serpardum, and load it into my class.

I like it, but as I said, I find some of it ugly. Any suggestions?
Back to top
Ian Collins
Guest





PostPosted: Sat Aug 26, 2006 5:13 am    Post subject: Re: Ugly C looking code Reply with quote



Jim Langston wrote:
Quote:
I've been working on a project to map a MySQL database to a C++ class.
Well, I actually got it to work, but some if it I just feel is exceptionally
ugly. For example, in my operator<< override:

Why don't you just save all the fields as strings and convert them as

required?


--
Ian Collins.
Back to top
Phlip
Guest





PostPosted: Sat Aug 26, 2006 5:33 am    Post subject: Re: Ugly C looking code Reply with quote



Ian Collins wrote:

Quote:
Jim Langston wrote:

I've been working on a project to map a MySQL database to a C++ class.
Well, I actually got it to work, but some if it I just feel is
exceptionally
ugly. For example, in my operator<< override:

Why don't you just save all the fields as strings and convert them as
required?

Why not store a table of pointers into the MySQL result itself, and fetch
them out on demand, typesafely?

--
Phlip
http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
Back to top
Guest






PostPosted: Sat Aug 26, 2006 7:26 am    Post subject: Re: Ugly C looking code Reply with quote

Ian Collins wrote:
Quote:
Jim Langston wrote:
I've been working on a project to map a MySQL database to a C++ class.
Well, I actually got it to work, but some if it I just feel is exceptionally
ugly. For example, in my operator<< override:

Why don't you just save all the fields as strings and convert them as
required?

I don't quite understand what you mean. All the fields are strings in
the CField class. The operator>> and operator<< overrides are doing
the conversion. So what did you mean beyond this?
Back to top
Guest






PostPosted: Sat Aug 26, 2006 7:31 am    Post subject: Re: Ugly C looking code Reply with quote

Phlip wrote:
Quote:
Ian Collins wrote:

Jim Langston wrote:

I've been working on a project to map a MySQL database to a C++ class.
Well, I actually got it to work, but some if it I just feel is
exceptionally
ugly. For example, in my operator<< override:

Why don't you just save all the fields as strings and convert them as
required?

Why not store a table of pointers into the MySQL result itself, and fetch
them out on demand, typesafely?

Please explain? Currently when I read the table it goes into a CField
map which contains the string that MySQL returns and the data type. So
in my CMySQLTable class I have a map of <std::string, CField> with the
std::string being the field name, and CField being the value (as a
string) and data type as stored in MySQL.

Oh, I think I see what you are saying, and I even thought about this.
Instead of storing them as std::string in the CField, store them as the
data type itself. I couldnt' figure out a good way to do this in a
map. A union wouldn't work as the data would be different sizes. And
even if I used a union of pointers (pointing to std::string, int,
unsigned int, etc...) I would still wind up having to use a switch
based on type.

Even if I came up with a way to store the data as it's type
transparently, the only thing this would save me is not having to run
StrmConvert</* type */>( ) on the strings. I don't see how it could
save me on the casting into the class they're being loaded into.
Back to top
Ian Collins
Guest





PostPosted: Sat Aug 26, 2006 7:45 am    Post subject: Re: Ugly C looking code Reply with quote

Serpardum (AT) gmail (DOT) com wrote:
Quote:
Ian Collins wrote:

Jim Langston wrote:

I've been working on a project to map a MySQL database to a C++ class.
Well, I actually got it to work, but some if it I just feel is exceptionally
ugly. For example, in my operator<< override:


Why don't you just save all the fields as strings and convert them as
required?


I don't quite understand what you mean. All the fields are strings in
the CField class. The operator>> and operator<< overrides are doing
the conversion. So what did you mean beyond this?

I might have misunderstood your code, I though you were converting each

field value in a result as it was copied.

Looking at my own MySQL wrappers, I do pretty much what Phlip said and
store the query result and use the subscript operator to index rows and
again within the row to access fields. The field access converts the
value to std::string on read and from the base type on write.

--
Ian Collins.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.