Archived

This topic is now archived and is closed to further replies.

How to create a global class?

This topic is 5802 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello All. i use the following bit of code in a lot of different public functions, in a number of different classes (located in different .cc files).
  
  try {
    Connection con(use_exceptions);
    con.connect(DB_CONN_STRING);
    Query query = con.query();
    (std::ostream&)query << buf;
// buf contains some SQL string...

 ....
 }
  
the code works perfectly, etc etc etc.. but what i was wondering, was everytime i enter that function, i create an instance of the Connection class, and an instance of the Query class. Could i do that ONCE (create the con and query instances) in my Main.cc or in some .h file, and then all my other classes use that single instance? Can extern do this? How? Or is this idea -bad practice(tm)- Thank you in advance to any help -PK-

Share this post


Link to post
Share on other sites
quote:
Original post by Pure Krome
i use the following bit of code in a lot of different public functions, in a number of different classes (located in different .cc files).



In other words, you have a cross-cutting concern. Is there no way you can refactor your design so that the code exists in one place (preferably as a class behaviour)?

quote:

Could i do that ONCE (create the con and query instances) in my Main.cc or in some .h file, and then all my other classes use that single instance? Can extern do this? How?



You could try investigating the Singleton pattern. I''m sure I posted an example sometime in the last couple of weeks. If you can''t find anything, post back and I''ll provide some sample code.

quote:

Or is this idea -bad practice(tm)-


You got it. It''s nearly always bad encapsulation to have global "command" objects. I explained that one somewhere on this forum too. You should try and think about where this object is actually used in your application, and what options you have to provide efficient and clean access to it without disturbing unrelated areas of the app. Although I''ve suggested the Singleton pattern, that''s rarely a great solution, so you might want to rethink your design.

The solution might be to refactor so that the common code becomes a function within some class, and that the connection and query objects are static within that class (for example).


Share this post


Link to post
Share on other sites
quote:

You could try investigating the Singleton pattern.



Hmm .. neva heard of this ... which is what i expected! I am a newbie after all

quote:

The solution might be to refactor so that the common code becomes a function within some class, and that the connection and query objects are static within that class (for example).



Yeah. kewl. I have a handfull of classes only. So if i make the connection AND query objects private, and instanciate them in the ctor, that means i only create ONCE (during the ctor) as opposed to when ever a public function is called.

Now i''m going to have to make sure that if i create the instance in the ctor, that I don''t bottleneck or slow down the Database my keeping the connection ''open'', as opposed to the current method of -> call public function, create conn and query, do stuff with em, end function (conn and query are auto free''d as i leave the scope).




-PK-

Share this post


Link to post
Share on other sites
The Singleton pattern is one of what is referred to as the GoF patterns. These are described in the book Design Patterns, written by 4 authors nicknamed the Gang of Four (GoF, right?). I''d recommend that book as good reading if you ever get a chance. Having said that, the Singleton pattern in the GoF book contains a resource leak. Oops! You probably don''t need to worry about singleton right now as I don''t think it sounds like the solution to your problem.

As for optimising you database connections, I think you hit the nail on the head when you said:

quote:

Now i''m going to have to make sure that if i create the instance in the ctor, that I don''t bottleneck or slow down the Database my keeping the connection ''open''


You need to investigate what sort of resource optimisation your database does, as it may well use connection pooling and various other techniques which make your optimisations either redundant or, as you hinted, the opposite of what you intended.

I suggest you get your code correct first, and make sure that the design seems nice and clean. Only then should you concern yourself with potential performance problems. I mean, is this database issue actually causing you a problem right now? If not, forget about it.


Share this post


Link to post
Share on other sites
quote:

You need to investigate what sort of resource optimisation your database does, as it may well use connection pooling ...


yeah... that''s exactly what i had in mind, but i wasn''t sure. I''m using mysql++ library for mysql on mandrake linux.

I''m used to windows ODBC for SQL, where there is connection polling i''m sure i read.


quote:

I suggest you get your code correct first, and make sure that the design seems nice and clean. Only then should you concern yourself with potential performance problems. I mean, is this database issue actually causing you a problem right now? If not, forget about it.



Yep. the code works perfectly. MySql++ came with some lovely examples, which is what i''ve used in my game. I was hoping to deal with the performance issue NOW, when i''ve only got a handful of DB calls, as opposed to later when i''ll have dozens.

Is it causing me a problem now? Definatly not.



Thanks buddy for your help Most appreciated.




-PK-

Share this post


Link to post
Share on other sites
quote:
Original post by SabreMan
Singleton pattern in the GoF book contains a resource leak. Oops!


actually, that has been discussed over and over and over.. again!
and yes, it does, but it''s easy to solve. (John Vlissedes wrote a column on it for C++ report in ''96 (I haden''t even looked at a compiler then....))
the book isn''t a "this is a good way to code book" (Scott Mayers Effective C++ series is tho) but more of a "this is a good way to think" book. Read it, understand it, take the samples with a truckload of salt.

Share this post


Link to post
Share on other sites
ADO/ODBC/OLE in windows automatically pool db connections for you as long as the connection string, used, is the same down to the last character. So if you where to change the username or password a new connection would be created...

I mention ADO/ODBC/OLE since they all sorta depend on each other ,without to many details, in some way underneeth the hood...

As for how you should connect to the DB depends on the application requirments...

In a broker type application, where the application needs to inetrogate the DB at every x seconds, one connection can be used. Then for each subsequent update, insertion etc a new connection can be used. As mentioned above if you create your connection using the same connection string ADO etc... will try to use a pooled connection. If the application needs to interogate every few minutes or hours, then a connection can be opened and closed as needed since delivery time is not that much of an issue any more.

Although, a poling mechanism that interogates the db every so often is not recomended since access to the DB is frequent. If it can be avoided a push mechanism can be used. Of course pushing the data will require more programming. Pushing can be achieved by making a remote procedure call or calling a module within the DB or something to that extent. This is specific on the DB server. The biger DB servers: Oracle, MSSQL, Informix, DB2 can access programmable modules in one way or the other. I could be wrong for some, but am 100% sure that Oracle can use JAVA classes and MSSQL extended store procedures (DLLs)
For MSSQL server an extended store procedure can be used to make a tcp/ip connection to the application and push the data to it. Again pushing should be done only of Poling can''t be avoided, I think MYSQL is straight up only DB and canot call any modules, so you will have to poll for data.

Hope this helps...

Share this post


Link to post
Share on other sites
quote:
Original post by DigitalDelusion
actually, that has been discussed over and over and over.. again!


And yet, Pure Krome has indicated he does not know about Design Patterns. I suspect that means he has not read these discussions.

quote:

and yes, it does, but it''s easy to solve. (John Vlissedes wrote a column on it for C++ report in ''96 (I haden''t even looked at a compiler then....))
the book isn''t a "this is a good way to code book" (Scott Mayers Effective C++ series is tho) but more of a "this is a good way to think" book. Read it, understand it, take the samples with a truckload of salt.


And your point is...?


Share this post


Link to post
Share on other sites
SabreMan<<"It was to point out to you where you could find a nice discussion of the problems related to it. It was not to say that everyone should know the singleton pattern, also It was to tell people that are considering reading the book, that it''s food for thought, not a coding style guide, many are the ones who''ve missed that";

Share this post


Link to post
Share on other sites
quote:
Original post by SabreMan
I don''t need this pointed out to me.





Im utterly sorry for trying to share information.
I just thought that someone that do point out that memory leak also would be intrested in seeing it solved, I assumed that you would have also supplied the C++ report reference if you knew about it.

Share this post


Link to post
Share on other sites
quote:
Original post by DigitalDelusion
Im utterly sorry for trying to share information.


It looks more to me like you''re trying to pursue me around various different threads and "score points" against me. It''s becoming very tedious very fast.


Share this post


Link to post
Share on other sites
quote:
Original post by Kylotan

I was more concerned about this:
(std::ostream&)query

Does query have an (std::ostream) operator defined? Even if so... eww




Um ... i''m not sure what you mean there ???


I''m using mysql++ library, which i downloaded from the main MySql offical site.

The mysql web site is (any guesses?!) www.mysql.com.
The c++ library i downloaded and i''m using is from http://www.mysql.com/downloads/api-mysql++.html

there are some documentation found on the above link, btw. Maybe that can explain your answer?

if ''query'' does have an (std::ostream) operator defined, why is this bad? (remember i''m the newbie from the other thread )




-PK-

Share this post


Link to post
Share on other sites
quote:
Original post by SabreMan
Have you tried using just "query << buf" rather than "(std::ostream&)query << buf"?


this is the result....

### Normal Compile of -SQAR-
##
#
make ../Bin/Sqar
make[1]: Entering directory `/home/pure/Sqar/Src''
g++ -Wall -g -pipe -I/usr/include/mysql -c -o Main.o Main.cc
g++ -Wall -g -pipe -I/usr/include/mysql -c -o Player.o Player.cc
Player.cc: In member function `void Player::Load(String, String)'':
Player.cc:45: choosing `std::basic_ostream&
std::operator<<(std::basic_ostream&, const char*) [with
_Traits = std::char_traits]'' over `SQLQuery& operator<<(SQLQuery&,
const mysql_ColData&)''
Player.cc:45: because worst conversion for the former is better than worst
conversion for the latter
make[1]: *** [Player.o] Error 1
make[1]: Leaving directory `/home/pure/Sqar/Src''
make: *** [default] Error 2
[pure@echobase Src]$


-PK-

Share this post


Link to post
Share on other sites
OK. I guess that''s not a good idea, then. The cast seems a little odd, but if you''ve gotta do it, you''ve gotta do it.

--
Cats cannot taste sweets.

Share this post


Link to post
Share on other sites
There must be something wrong there, since MySQL++ doesn''t require you to cast it in order to send data to the Query object. So I am worried that you''re actually hiding some error elsewhere. I can''t see how it works by converting the Query to an ostream, since it''s not derived from ostream (according to my header files, anyway). Try casting buf to an SQLString instead?

Of course, if it works already, then it works. But if it doesn''t work, or stops working, check this as it looks very suspect.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost ]

Share this post


Link to post
Share on other sites