Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

QuickQuery - a database querying tool

0.00/5 (No votes)
7 Feb 2005 1  
A tool for querying all types of databases.

QuickQuery

Introduction

QuickQuery is the second program I wrote on my own in C++, just to experiment. It was an attempt to make an app that could run queries on any type of database. This code was written using VC6 and has been run on Windows 2000 and XP.

Background

I started off trying to make something that the rest of my company could use. I still use it every now and then, but not much. At the time, I was also trying to learn DirectX programming, so you'll see some of that in here, too. :)

Using the code

QuickQuery uses ODBC to run the queries and the CRecordset-derived classes from Microsoft's "catsets" source code. These sets are used to get the primary keys and columns of all the tables in the database. There is functionality there that I didn't implement, but that can still be used.

This program uses a CFormView and switches back and forth between that and a CListView view. By switching to the ListView, you can see all the tables in a database:

Table View

and double-clicking on a table will show you the columns and column types for that table.

Column View

This is done by clicking the double-arrow icon on the toolbar. I used this code that I found somewhere in my MSDN to switch views in a function of my app, called SwitchView():

CView* CQuickQueryApp::SwitchView(CView* pNewView)
{
/*****************************************************************************
Author: BLACKDICE
Purpose: SWITCHES VIEWS BETWEEN A CLISTVIEW OBJECT AND A CFORMVIEW OBJECT--
    THEN RETURNS A POINTER TO THE PREVIOUS VIEW
(STOLEN FROM MSDN)
******************************************************************************/

    CView* pActiveView =
        ((CFrameWnd*) m_pMainWnd)->GetActiveView();
    try
    {

        // Exchange view window ID's so RecalcLayout() works.

        #ifndef _WIN32
        UINT temp = ::GetWindowWord(pActiveView->m_hWnd, GWW_ID);
        ::SetWindowWord(pActiveView->m_hWnd, GWW_ID,
                     ::GetWindowWord(pNewView->m_hWnd, GWW_ID));
        ::SetWindowWord(pNewView->m_hWnd, GWW_ID, temp);
        #else
        UINT temp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);
        ::SetWindowLong(pActiveView->m_hWnd, GWL_ID,
                     ::GetWindowLong(pNewView->m_hWnd, GWL_ID));
        ::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);
        #endif

        pActiveView->ShowWindow(SW_HIDE);
        pNewView->ShowWindow(SW_SHOW);
        ((CFrameWnd*) m_pMainWnd)->SetActiveView(pNewView);
        ((CFrameWnd*) m_pMainWnd)->RecalcLayout();
        pNewView->Invalidate();
    }
    catch(CException* err)
    {
        pErrObject->HandleError(err," "," ");
    }
    catch(...)
    {
        AfxMessageBox("Unhandled Error ");
    }
    return pActiveView;
}

There is also a pretty generic 'Find' dialog that lets you search, when a ListView is active. It allows you to search by column. Although it should probably be a modeless dialog, at the time I made this project, I really didn't know how to do that. :)

Find Dialog

Queries can be saved, as well as the connection string to your last connection so that when you open a query, it connects you to the right database. Your last connection is also saved in the registry so that when you open QuickQuery, it will connect you to the last connection you had open before shutting down.

void CQuickQueryDoc::Serialize(CArchive& ar)
{
    try
    {
        if (ar.IsStoring())
        {
            m_view->UpdateData();
            ar<<m_view->m_strQuery<<m_view->m_CurrentSource;
        }
        else
        {
            //if opening

            if(!m_view) //if view is not yet showing

            {
                ar>>m_docQuery>>m_docSource;
                m_bSerializing = TRUE;

                return;
            }
            //if view has been initialized already

            ar>>m_view->m_strQuery>>m_view->m_CurrentSource;
            AfxGetApp()->WriteProfileString("Database",
                         "LastDatabase",m_view->m_CurrentSource);
            m_view->UpdateData(FALSE);
        }
    }
    catch(CException* err)
    {
        pErrObject->HandleError(err," "," ");
    }
    catch(...)
    {
        AfxMessageBox("Unhandled Error");
    }
}

Points of Interest

The 'About' dialog has a simple PictureBox control that I use to display a spinning Direct3D square, with my old company's logo texture-mapped onto the square. This was made using DirectX 8, but I have version 9 now, and it compiles just fine. Maybe even the DirectX code involved in the dialog will help somebody out! (I can hope, can't I?)

About QuickQuery

As I said, this was my second C++ project, not out of a tutorial, so please don't be too harsh. :)

There is a context-sensitive help file associated with QuickQuery that I never fully finished...so some of it works - some of it doesn't. You'll probably have to change the path to the help file for building purposes.

You are free to do whatever you want with this code. Like I said, it was my very first project, and I had actually forgot about it until I saw it in one of my old folders. If I were to do a project like this over from scratch, I'd use ADO, only using the ODBC function to get the connection string, as I have done since.

Known Issues

When running this program, after shutting down, I see a memory leak in the debug output, but I really have no idea where it is (or much desire to investigate).

This program is a lot larger than it needs to be, mostly because of bitmaps (I hope). There is a bug that occurs sometimes when switching views. Error-handling could be a lot better.

History

  • Posted 12/15/2004.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here