Home
Features
Alternatives
Developing
Issues
Roadmap
History
Authors
License
QueryPony Home
Developing
This chapter is for programmers to speed up orientation in the code.
As a user, you may rather shy away from here, otherwise you will onyl be puzzled.
Solution Overview
There are three projects in the solution:
-
IOBus. This is a small helper project I have copied
from some other solution.
It's name hints at the purpose to provide delegates for an otherwise
non-communicative library, to send output to the client and to fetch
input from the client. (But this functionality is not even yet utilized.)
-
QueryPonyGui. This project comprises the forms and controls the
user interacts with. This project emits the final binary QueryPony.exe
which you can start. This project has a reference to QueryPonyLib
which performs the database tasks.
-
QueryPonyLib. This is the engine, performing the database tasks.
It has no reference (back to) the GUI, and thus has no native input/output
facilities. But it can receive delegates for input/output purposes
from it's client.
The emission of this project is QueryPonyLib.dll, which represents
an API usable from any .NET program. (The usage may be not so smooth yet.)
Project Settings
Due to the single-file-delivery feature, the project settings of the three
projects are a bit particular. Notably watch out for the following points:
-
Libraries are referenced. Those libaries you may expect appearing
as DLLs in the callers binary output folder (this were the default behaviour).
But the references have set property
'Copy Local = False'.
Thus those DLLs will not appear in the callers binaries output folder.
-
Instead, we copy those libraries manually physically into the callers
project subfolder libs
and tag them with the property BuildAction = Embedded Resource.
This blows up the size of the output binary, instead leaving companion
DLL files beside it.
-
If we copy such DLL physically, and then make changes in it's sources,
the copy will not notice the changes (nor the debugger can
step into such copied DLL easily).
To make sure we have at least always a fresh copy of such library,
the project's Pre-Build Event calls a batchfile to fetch a fresh
copy before compiling.
This requires to have the correct build order.
-
If you then are curious, how the program deals with a library not existing as
file, but incorporated as resource, inspect method provideSingleFileDeployment().
Finally, I am astonished how transparent and smoothly above described project
settings work (after they have been worked out once and settled). But you have to
have those particularities in the corner of your eye, if you start
fiddling with the projects and then experience funny effects.
Learn the Pony New Tricks
Any programmer attempting to chat up to QueryPony,
where can she start? First and foremost: bugfix, bugfix, bugfix!
But if then she is behind inventing new features, there are two main topics:
refine existing database access and implement additional database types.
(1) Refining Existing Database Access
The lowest common denominator between all database types is viewing tables.
This feature is implemented for all addressed database types.
But then, each database has more or less it's individual features.
The steps to approach a refining task may be like follows.
-
In the application's treeview, go to a node, e.g. database, table or field node, rightclick it
and inspect it's context menu. Here you see which access features are implemented,
and here you can judge what you are missing.
-
Then you need to know, where in the code the context menu comes from.
To get an idea, how to add items or to work on items,
the starting point is method *DbBrowser.cs::GetObjectHierarchy(),
where '*' means the name of the respective database.
-
The next important methods to understand are *DbBrowser::GetActionList()
and GetActionText(). Now you have an impression of where the context menu
items come from and how you can manipulate or expand them.
-
To see what happens, if the user decides to execute a command on the Command Tab
on the Query Form, inspect method QueryForm.cs::execute().
-
Above noted locations were definitely not all the locations you need to
inspect, manipulate or supplement. But they serve you as
pointers to launch your expedition.
(2) Adding New Database Implementations
Providing the implementation of yet another database type,
would consist of about the following steps.
-
In QueryPonyLib/DbApi, spawn files *DbClient.cs, *DbBrowser.cs and *QueryOptions.cs
(where the asterisk is the name of the new database)
and adjust the methods to the needs of the new database.
-
If the new database connection comes with a third party library, the project settings
for the single-file-delivery
have to be passed through (as described above).
-
In QueryPonyGui/Gui, in ConnectForm.cs spawn a new tab for the specific database
and adjust it.
-
With 'Find All References', follow the occurrences of a suited variable or a TextBox
from a settled ConnectTab
and supplement the new case at each occurrence (this may be about a dozen places).
-
Test and fill the gaps.
Applied Programming Techniques
This is an overview, which programming techniques in general you can find in QueryPony
(in case e.g. you are interested in sample code sequences for learning C# or the like).
The sophisticated core design techniques (abstract classes, interfaces, threading) date back
to Joseph Albahari's Query Express. The rather surface techniques came added with QueryPony.
-
Abstract classes
-
Interfaces
-
Threading
-
Delegates
-
Settings with complex types
-
Ressource files utilization
-
Use textfiles without storing them to disk
-
Use libraries (*.dll) without storing them on disk
-
Single-file-delivery
-
Forms-on-Tabs (the MDI was sorrily sacrificed for that)
-
Conditional compiling
-
Create Tabs at runtime and place Forms on them (using Winforms)
-
. . .
Commenting Style
If you look into the code indeed, you may be shocked about
a weired commenting style with cryptic numbers all over.
Don't scare off please, just try to ignore cryptic numbers.
Those numbers are timestamps emitted while coding. They serve
multiple purposes, e.g. they are like breadcrumbs to help to find my way
back if I got stuck, or to group far apart sequences together.
They serve as links between locations in code, documentation,
outside files and paper notes. They serve as IDs for various items.
There is a bit hope: timestamps without relevant references have
an expiration. From time to time, I thin them out, so they will
not totally congest the source code.
More Details
If you want read even more details, considerations and raw ideas
about QueryPony development, please inspect file
devnotes.txt.
A specific developer paper is
QueryForm.