Programming tutorials, examples and code snippets. C++, Java, Perl, PHP and javascript. Enterprise examples using javaEE, JNDI and Beans. Core tutorials using sockets, threads, database, IPC, XML etc. Web 2 widgets using javascrpt. Simple easy to understand step by step tutorials,
Double dispatch is a way to call different (but-related) concrete functions depending on the runtime types of the various objects involved in the call. IT basically replacing static compile time casting with dynamic resolving of calls.
Here is an example of the a double dispatch. Let's say it's a game. You have a wildanimal that attacks types of humans, and a warrior which derives from human. Let us consider a wildanimal attacking a warrior. I strongly suggest running this code for a better understanding.
The problem is on line 60 you have w->attack(h). This leads to static compile time function overloading and you end up selecting the 'Human Attack' at line 44. This leads to a wild animal attacking a human despite the fact that it should be attacking a warrior.
The solution is to have a DD that allows the proper dynamic cast by using the 'this' pointer (line 26). Now when you call h->attackedbywildanimal(w); at line 54 you will get the correct wild animal attacking a warrior instead of a human.
Note that a simpler but far less flexible solution would have been to simply statically cast the pointer at line 50 to be w->attack((warrior*)h);.
Note that to have all the code in a single file I needed class definitions at the top and the wildanimal implementation is actuall at the bottom. Remind me to use java next time!
Design pattern periodic table. The Gang Of four (GoF) design patterns consist of the fundamental creational, structural and behavioural patterns that form the basis for all other patterns. Are these in fact fundamental? Can they be refactored? Let us explore this topic to better understand desgin patterns and their use in everyday programming.
GoF's original books was "Design Patterns: Elements of Reusable Object-Oriented Software" by ErichGamma, RichardHelm, RalphJohnson and John Vlissides.
Aim
The aim of this bit of code is to implement an SQL Server ODBC C++ Database Pool in Windows. A Database pool is normally used by applications to speed up the process of getting a Connection.
Assumptions
This article assumes that you have SQL Server installed and running. For purposes of this example the the project directory is CppDatabasePool. Also it is assumed that you have VC++ installed and configured. See Problems and Solutions Installing VC++ Express Edition, to install and run vcvars32.bat.
The files used in this are given below. Workspace
_|_CrossHelper.h
_|_CrossHelper.cpp
_|_CommonDatabasePool.cpp
_|_mysql
_|__|_MySQLPool.h
_|__|_MySQLPool.cpp
_|_oracle
_|__|_OraclePool.h
_|__|_OraclePool.cpp
_|_sqlserver
_|__|_SQLSvrPool.h
_|__|_SQLSvrPool.cpp
_|_examples
_|__|_ExampleOracle.cpp
_|__|_ExampleMySQL.cpp
_|__|_ExampleSQLSvr.cpp
_|__|_makefile.oracle
_|__|_makefile.mysql
_|__|_makefile.sqlsvr
CrossHelper.h and CrossHelper.cpp - Define and implement the crossplatform functionality between windows and linux - I haven't finished the linux part yet.
CommonDatabasePool.cpp - This is the primary file that has a template and a map that stores the cached connections and a thread that runs to ping the database connections to keep them alive and prevent an inactive timeout. The idea is to potentially be able to use this template with different database implementations .
sqlserver/SQLSvrPool.h and sqlserver/SQLSvrPool.cpp - These classes actually inherit from the template above and implement the C++ ODBC specific tasks. You will be using this class but not editing it.
examples/ExampleSQLSvr.cpp - This has an example of how you use the pool.
makefile.sqlsvr - Used to build the example. DO NOT forget the "/D WINDOWSXX" flag as this is needed to compile the widows version. Also remember to substitute your local directories for the ones in the bat file. You should link to odbc32.lib binary for compile.
Below is the ExampleSQLSvr.cpp file.
1. /* Copyright 2009 Righteous Ninja AKA P.S. Ching*/
2. #include <iostream>
3. #include "..\sqlserver\SQLSvrPool.h"
4. 5. using namespace std;
6. 7. int main(){
8. 9. SQLSvrPool* sqlsvrpool = new SQLSvrPool( "localhost", //hostnam
10. "MyDatabase", //database
11. "sa", //username
12. "Admin-123", //password
13. 300000, //keepalive timeout (milliseconds)
14. "SELECT top 1 name FROM dbo.sysobjects"); //keepalive statement
15. 16. /*Create a pool that will have 3 cached connections and will swell upto a
17. total of 5 connections. Returns the number of cached connections or -1 on error
18. */
19. if(sqlsvrpool->CreatePool(3, 5)<=0){
20. cout<<"Error creating database pool\n";
21. cout<<sqlsvrpool->GetLastSystemError()<<endl; //If it's asystem error
22. goto EXAMPLE_END;
23. }
24. 25. /*Dispaly the pool information*/
26. cout<<(*sqlsvrpool);
27. 28. SQLHANDLE* psqlconnectionhandle;
29. SQLHANDLE sqlstatementhandle;
30. 31. 32. /*Test the validity of the pool at anytime - not really required*/
33. if(!sqlsvrpool->IsPoolValid())
34. goto EXAMPLE_END;
35. 36. /*Get a connection from the pool*/
37. if((psqlconnectionhandle=sqlsvrpool->GetConnectionFromPool())==0){
38. cout<<"You have reached the maximum amout allowed - 5 in this example\n";
39. goto EXAMPLE_END;
40. }
41. 42. /*Get a statement handle from the connection*/
43. if(SQL_SUCCESS!=SQLAllocHandle(SQL_HANDLE_STMT, *psqlconnectionhandle, &sqlstatementhandle)){
44. sqlsvrpool->ShowSQLError(cout, SQL_HANDLE_DBC, *psqlconnectionhandle);
45. goto EXAMPLE_END;
46. }
47. 48. /*Execute the query and display the results. Do not Free the database connection handle.
49. This will be released via the ReleaseConnectionToPool back to the pool.
50. */
51. if(SQL_SUCCESS!=SQLExecDirect(sqlstatementhandle, (SQLCHAR*)"select * from testtable", SQL_NTS)){
52. sqlsvrpool->ShowSQLError(cout, SQL_HANDLE_STMT, sqlstatementhandle);
53. goto EXAMPLE_END;
54. }
55. else{
56. char name[64];
57. char address[64];
58. int id;
59. while(SQLFetch(sqlstatementhandle)==SQL_SUCCESS){
60. SQLGetData(sqlstatementhandle, 1, SQL_C_ULONG, &id, 0, NULL);
61. SQLGetData(sqlstatementhandle, 2, SQL_C_CHAR, name, 64, NULL);
62. SQLGetData(sqlstatementhandle, 3, SQL_C_CHAR, address, 64, NULL);
63. cout<<id<<" "<<name<<" "<<address<<endl;
64. }
65. }
66. SQLFreeHandle(SQL_HANDLE_STMT, sqlstatementhandle );
67. 68. /*Dispaly the pool information*/
69. cout<<(*sqlsvrpool);
70. 71. 72. /*Release the connection back into the pool*/
73. sqlsvrpool->ReleaseConnectionToPool(psqlconnectionhandle);
74. 75. /*Dispaly the pool information*/
76. cout<<(*sqlsvrpool);
77. 78. char c;
79. cout<<"Enter character to exit\n";
80. cin>>c;
81. 82. EXAMPLE_END:
83. 84. /*Destroy the database pool*/
85. if(sqlsvrpool->DestroyPool()>0){
86. cout<<"There are still some un-released connections in the pool\n";
87. }
88. 89. delete sqlsvrpool;
90. 91. return 0;
92. }
93.
Hide line numbers
As you can see the basic steps are..
SQLSvrPool* sqlsvrpool = new SQLSvrPool("hostname", "mydatabase", "username","password", 300000, "SELECT top 1 name FROM dbo.sysobjects"); The keepalive thread will issue the "SELECT top 1 name FROM dbo.sysobjects" statement every 300 seconds across all the inactive connections in the cache to keep them alive.
sqlsvrpool ->CreatePool(3, 5); This creates a cache with 3 stored connections that will swell to a max of 5 connections when required. If you go above 5 connections without releasing any then you will get a 0 when you next call GetConnectionFromPool().
Open a command prompt and go to the "examples" direcotory. Compile the files by running nmake. Make sure to substitute your local directories for the ones in the file. There should be the oracle oci include directory and the oraocci10.lib binary for compile.
Add these paths to your existing path so that the executable can find the required libraries. Again, don't forget to replace the directories with the ones on your local machine. Basically you need to give the 'bin' diretory and the 'oci\lib\msvc\vc7' directory in your of your Oracle client installation.
Aim
The aim of this tutorial is to give a quick introduction to Ant. We will look at the basics of a build file and go through some of the options available. Ant buildfile is very similar to nmake/name. Leave any questions or problems as comments and I will endeavour to answer them.
Assumptions
This article assumes that you have a compatible version of java (JDK) and Ant installed.
Aim
The aim of this Windows C++ example is to demonstrate multi-threading, signalling, semaphores and mutexes using a simple producer and consumer example in C++ on Windows. This will use WINAPI functions such as CreateThread, WaitForMultipleObjects, CreateSemaphore, CreateMutex, ReleaseMutex and ReleaseSemaphore. Leave any questions or problems as comments and I will endeavour to answer them.
This application uses an integer queue. The producer adds values to this queue from 1 to 99 by pushing. Each time it adds a value it notifies a thread via a semaphore that there is something to consume. A consumer thread then consumes this value by popping it. Write the application and save is as thread.cpp.
Line11: Randomly generate a sleep time between 0 and 100 milliseconds.
Lines 28-30: Start all the threads giving the same MyData variable to them so the semaphore and the mutex is shared between all of them.
Line 45 : Both consumer threads wait on the semaphore.
Line 73: The producer thread triggers the semaphore allowing one waiting thread to proceed.
Lines 47 & 54: Lock and unlock mutexes allowing only a single consumer thread to run this section of code. This is like a critical section or a 'synchronized' section java.
Line 32: Wait for all the threads to finish processing. Like the join command in Linux.
Open a prompt to the working directory and compile the code using the windows cl.exe compiler. You just need to include the pdh.lib.
..workspace\WinapiThreadExample>cl thread.cpp
Now run the program in the command prompt. You should see something similar to what is shown below.
The first column is the values produced by the producer, the second column is the value consumed by the consumer and the third column is the threadid of the consumers (in brackets) and producer. Note that there are 2 consumers in this example, hence the two consumer thread IDs 2996 and 1108 in this example