PgAdmin Internals
pgAdmin Development
Introduction
The information about pgAdmin development can be located at:
- The pgAdmin developers mailing list is pgadmin-hackers@postgresql.org
Physical Source Lines of Code [SLOC]
The source code of pgAdmin have the following main attributes, found using sloccount program [2]:
Used Version | 1.14.2 |
---|---|
Total Physical Source Lines of Code (SLOC) | 172,137 |
Development Effort Estimate, Person-Years (Person-Months) (Basic COCOMO model, Person-Months = 2.4 * (KSLOC**1.05)) |
44.53 (534.42) |
Schedule Estimate, Years (Months) (Basic COCOMO model, Months = 2.5 * (person-months**0.38)) |
2.27 (27.20) |
Estimated Average Number of Developers (Effort/Schedule) | 19.65 |
Total Estimated Cost to Develop (average salary = $56,286/year, overhead = 2.40). |
$ 6,016,024 |
Another interesting information it's the distribution of the physical source lines of code between different programming languages in the project:
C++ | 163662 (95.08%) |
---|---|
sh | 4331 (2.52%) |
Ansi C | 1636 (0.95%) |
Pascal | 1120 (0.65%) |
yacc | 927 (0.54%) |
lex | 421 (0.24%) |
perl | 40 (0.02%) |
And finally the physical source lines of code distribution between directories:
Directory Name | Sloc | Sloc by Language |
---|---|---|
ui | 34183 | cpp=34182,sh=1 |
include | 23547 | cpp=22651,ansic=896 |
schema | 19165 | cpp=19165 |
dlg | 17987 | cpp=17987 |
frm | 15931 | cpp=15931 |
ogl | 12693 | cpp=12693 |
pgscript | 11561 | cpp=10172,yacc=927,lex=421,sh=41 |
utils | 5320 | cpp=3883,pascal=1120,ansic=295,perl=22 |
gqb | 4724 | cpp=4724 |
slony | 4480 | cpp=4480 |
ctl | 4335 | cpp=4335 |
debugger | 2932 | cpp=2932 |
agent | 2535 | cpp=2535 |
top_dir | 1455 | cpp=1054 |
db | 1364 | cpp=1281,ansic=83 |
Class naming conventions
Naming conventions make programs more understandable by making them easier to read. They can also give information about the function of the identifier-for example, whether it's a constant, package, or class-which can be helpful in understanding the code. For this reason the following rules were followed:
- foo represents an object of type Foo
- fooFactory creates foos
- fooCollection is a collection of foos
- fooCollectionFactory creates a fooCollection
- fooObject is an object that resides under/in foo
- fooObjCollection is a collection of fooObjects
- fooObjFactory creates fooObjects
Coding Style
The following rules gives coding conventions for pgAdmin:
- Braces are always on lines of their own.
- Only preprocessor directives, globals and function headers/closing braces should normally be left-justified
- Indent == Tab (most developers set their tab width to 4).
- Leave a blank line between logical blocks of code for clarity.
- Add a space after all but the last semi-colon in for loops for clarity.
- Introduce each function in a comment
By Example:
Source code before applying coding conventions:
bool gqbArrayCollection::existsObject(gqbObject *item){ gqbObject *found=NULL; int size=gqbArray.GetCount(); for(int i=0;i<size;i++){ if (gqbArray.Item(i)==item){ found=gqbArray.Item(i); break; } } if(found) return true; else return false; }
Source code after applying coding conventions:
// Check if an item exists in the array. bool gqbArrayCollection::existsObject(gqbObject *item) { gqbObject *found=NULL; int size=gqbArray.GetCount(); for (int i=0; i<size; i++) { if (gqbArray.Item(i)==item) { found=gqbArray.Item(i); break; } } if (found) return true; else return false; }
wxWidgets
Because pgAdmin is written in C++ using the wxWidgets we should know some relevant information about it [1]:
- wxWidgets (formerly wxWindows) is a widget toolkit for creating graphical user interfaces (GUIs) for cross-platform applications. wxWidgets enables a program's GUI code to compile and run on several computer platforms with minimal or no code changes. It covers systems such as Microsoft Windows, Mac OS, Linux/Unix (X11, Motif, and GTK+), OpenVMS, OS/2 and AmigaOS. A version for embedded systems is under development.
- The wxWidgets library is implemented in C++, with bindings available for many commonly used programming languages, among them, Python (wxPython), Erlang (wxErlang), Haskell (wxHaskell), Lua (wxLua), Perl (wxPerl), Ruby (wxRuby), Smalltalk (wxSqueak), Java (wx4j) and even JavaScript (wxJavaScript).
- wxWidgets is best described as a native mode toolkit as it provides a thin abstraction to a platform's native widgets, as opposed to emulating the display of widgets using graphic primitives. Calling a native widget on the target platform results in a more native looking interface than toolkits such as Swing (for Java), as well as offering performance and other benefits.
- The toolkit is also not restricted to GUI development, having a built-in ODBC-based database library, an inter-process communication layer, socket networking functionality, and more.
- A good free pdf book to learn wxWidgets can be found at: http://www.informit.com/store/product.aspx?isbn=0131473816 in the download section.
Development Environment
The Development environment for pgAdmin can be in theory any accepted by the widget toolkit for creating graphical user interfaces (GUIs) for cross-platform applications known as wxWidgets, It covers systems such as Microsoft Windows, Mac OS, Linux/Unix (X11, Motif, and GTK+), OpenVMS, OS/2 and AmigaOS. Here describes how to build pgAdmin from source on *nix, Mac and Windows:
Linux, FreeBSD, Solaris and other unix variants
You will need:
- A modern development environment:
- GTK 2.2 or above.
- GNU automake 1.9 or above.
- GNU autoconf 2.59 or above.
- GNU gcc 3.4 or above.
- Following libraries:
- wxGTK 2.8.x from http://www.wxwidgets.org/
- libxml2 2.6.18 or above from http://www.xmlsoft.org/
- libxslt 1.1.x or above from http://www.xmlsoft.org/
- PostgreSQL 8.1 or above from http://www.postgresql.org/
Building
- Install libxml2 and libxslt if they are not already present on your system, per the instructions included with them.
- Install PostgreSQL per the instructions included. It is recommended that you build with OpenSSL support, using the --with-openssl configure option.
- Unpack the wxGTK tarball to a convenient location, and build and install it as follows:
- Note: A script is included in the pgAdmin source tarball(xtra/wx-build/build-wxgtk) which will build and install wxWidgets in each combination of shared/static/debug/release builds for you. (You can follow below steps for wxGTK manual compilation too).
- cd /path/to/wxGTK/source/
- ./configure --with-gtk --enable-gtk2 --enable-unicode
- make
- sudo make install
- Install wxWidgets contrib modules.
- cd contrib/
- make
- sudo make install
- Unpack the pgAdmin tarball to a convenient location, and build and install it as follows:
- bash bootstrap #Required only if building from an SVN / Git checkout
- ./configure
- make all
- sudo make install
If any of the prerequisite components are installed in locations that the configure script cannot find, you may specify their locations on the command line. See the configure help (./configure --help) for details.
Mac OS X
You will need:
- A modern development environment:
- XCode 2.0 or above
- GNU automake 1.9 or above.
- GNU autoconf 2.59 or above.
- wxMac 2.8.x from http://www.wxwidgets.org/
- libxml2 2.6.18 or above from http://www.xmlsoft.org/
- libxslt 1.1.x or above from http://www.xmlsoft.org/
- PostgreSQL 8.1 or above from http://www.postgresql.org/
Building
- Install libxml2 and libxslt per the instructions included with them into a non-system location. The default versions included with OS X Panther and Tiger are too old and will not work correctly with pgAdmin.
- Install PostgreSQL per the instructions included. It is recommended that you build with OpenSSL support, using the --with-openssl configure option.
- Unpack the wxMac tarball to a convenient location, and build and install it as follows:
- cd /path/to/wxMac/source/
- ./configure --with-mac --enable-gtk2 --enable-unicode
- make
- sudo make install
- Install wxWidgets contrib modules:
- cd contrib/
- make
- sudo make install
- Note 1: You may also pass the --enable-universal_binary option to configure to build a Universal binary. This will also require a Universal build of PostgreSQL's libpq library.
- Note 2: A script is included in the pgAdmin source tarball (xtra/wx-build/build-wxmac) which will install a Universal build ofwxWidgets in each combination of shared/static/debug/release builds for you.
- Unpack the pgAdmin tarball to a convenient location, and build and install it as follows:
- bash bootstrap # Required only if building from an SVN / Git checkout
- ./configure --enable-appbundle
- make all
- make install
- This final step will build an OSX appbundle called pgAdmin3.app in the root of your source tree. As this can take a minute or two, the pkg/mac/debug-bundle.sh script may be used to build a non-relocatable 'fake' appbundle using symbolic links directly to the executable files. This appbundle is called pgAdmin3-debug.app, and doesn't need to be rebuilt when pgAdmin is recompiled.
If any of the prerequisite components are installed in locations that the configure script cannot find, you may specify their locations on the command line. See the configure help (./configure --help) for details.
Windows
You will need:
- Windows 2000 or above.
- Microsoft Visual C++ 2005.
- The Windows 2003 R2 Platform SDK [When you install it, select custom install and then only add to selection Microsoft Windows Core SDK and Microsoft Data Access Service (MDAC) SDK]. (Not included with VC++ Express Edition, should be download & installed)
- Windows Installer XML v3.
- wxMSW 2.8.x from http://www.wxwidgets.org/
- libxml2 2.6.18 or above from http://www.xmlsoft.org/
- libxslt 1.1.x or above from http://www.xmlsoft.org/
- iconv 1.9.x or above from http://gnuwin32.sourceforge.net/
- PostgreSQL 8.1 or above from http://www.postgresql.org/
Precompiled XML/XSLT and dependency packages for Windows can be found at http://zlatkovic.com. You probably need zlib 1.2.x as well as libxml2 and libxslt.
Building
- Unpack the wxMSW source code to a convenient location pointed to by the %WXWIN% environment variable.
- Install PostgreSQL to a convenient location pointed to by the %PGDIR% environment variable.
- Unpack the pgAdmin source code to a convenient location.
- From a Visual Studio command prompt, run the wxWidgets build script included in the pgAdmin source tree at xtra/wx-build/build-wxmsw.bat
- Unpack the libxml2, libxslt and dependency binaries in a directory pointed to by the %PGBUILD% environment variable.
- Start Visual C++ and load the pgAdmin solution file. Build the required targets.
Note from microsoft site for Visual C++ Express Edition 2005 Users:
Update: First read this http://www.microsoft.com/express/2005/platformsdk/default.aspx
You can use Visual C++ Express to build .NET Framework applications immediately after installation. In order to use Visual C++ Express to build Win32 applications, you'll need to take just a few more steps. I'll list the steps necessary for building Win32 applications using Visual C+ + Express.
1. Install the Microsoft Platform SDK: Follow the instructions and install the SDK for the x86 platform.
2. Update the Visual C++ directories in the Projects and Solutions section in the Options dialog box. Add the paths to the appropriate subsection:
● Executable files: C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Bin
● Include files: C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include
● Library files: C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Lib
Note: Alternatively, you can update the Visual C++ Directories by modifying the VCProjectEngine. dll.express.config file located in the \vc\vcpackages subdirectory of the Visual C++ Express install location. Please make sure that you also delete the file "vccomponents.dat" located in the "% USERPROFILE%\Local Settings\Application Data\Microsoft\VCExpress\8.0" if it exists before restarting Visual C++ Express Edition.
And / Or simply run this
Star Menu->
Microsoft Platform SDK for Windows Server 2003 R2->
Visual Studio Registration->
Register PSDK Directories with Visual Studio.
Only use this recommendations if you reach any of this errors:
Update the corewin_express.vsprops file: One more step is needed to make the Win32 template work in Visual C++ Express. This can be done in two ways.
1. Click on Project (on each one pgAdmin3, pgaevent, pgAgent), Properties, Linker, Input, Additional Dependencies and made sure the folllowing were all in the list (or else you will get unresovled externals to Windows API).
user32.lib gdi32.lib oleaut32.lib ole32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib rpcrt4.lib wsock32.lib odbc32.lib advapi32.lib
This avoid errors from type LNK2019
2.You need to edit the corewin_express.vsprops file (found in C:\Program Files\Microsoft Visual Studio 8\VC
\VCProjectDefaults) and Change the string that reads: AdditionalDependencies="kernel32.lib"
to AdditionalDependencies="kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
shell32.lib ole32.lib oleaut32.lib uuid.lib"
To avoid error VCBLD0001 "VCProjectEngine.dll" Could not be loaded on non-eglish version of visual c++ express edition (spanish, french and others). This Problem seems to be that for non english versions, vcbuild cannot load the specific languages dll. SOLUTION:
copy the content of the localized folder (for french it is ...vcpackages\1036, spanish it is ...vcpackages\3082) in vcpackages. It worked on french and spanish version.
3. VC++ 2005 express bug: Some errors relate to imposibility of upgrade of vcbuild /nologo /upgrade wx_%%f.dsp, can be solve in this way: open with VC C++ express each .DSP file (adv aui base core html net wxexpat wxjpeg wxpng wxregex wxtiff wxzlib xml xrc ogl stc) and allow conversion of format, save and after that step just run script build-wxmsw.bat again.
4. Sometimes in certain machines, the script of pgadmin build-wxmsw.bat cannot compile wxwidgets (some kind of bug in cmd vc++ prompot) just open each of the .dsp files visually with the IDE (adv aui base core html net wxexpat wxjpeg wxpng wxregex wxtiff wxzlib xml xrc ogl stc) and compile manually in Unicode Debug and Release mode (both).
Check this url: http://wiki.wxwidgets.org/Troubleshooting_building_wxWidgets_using_Microsoft_VC
5. Sometimes you can avoid the error fatal error C1083: Cannot Open file: 'windows.h': No such file or directory if using build-wxmsw.bat script and only follow the above instructions and try to compile wxwidgets library. This solution works for me:
a.) Open the build-wxmsw.bat script and this lines:
REM Location of wxWidgets source set WX=%WXWIN% set HERE=%CD% after this add the lines
REM Fix Error error C1083 'windows.h' (use /useenv option when compiling) set PDSKWIN=C:\Archivos de programa\Microsoft Platform SDK for Windows Server 2003 R2 set INCLUDE=%PDSKWIN%\Include;%INCLUDE% set LIB=%PDSKWIN%\Lib;%LIB%
b.) Look for this string "vcbuild /nohtmllog /nologo" and change for this one " vcbuild /useenv /nohtmllog /nologo twice.
inside cd %WX%\build\msw loop
...
vcbuild /useenv /nohtmllog /nologo wx_%%f.vcproj "Unicode %%b"
and inside cd ..\..\contrib\build loop
vcbuild /useenv /nohtmllog /nologo %%f.vcproj "Unicode %%b"
6. Error: ...\include\wx/platform.h(196) : fatal error C1083: Cannot open include file: 'wx/setup.h': No such file or directory This error occurs when you don't add the following directory... %WXWIN%\include\msvc (replace %WXWIN% for right value)
..in the options : VC> Tools> Options> Projects and Solutions> Directories> Include files (top right combo box)
add above directory: %WXWIN%\include\msvc
Class Hierarchy
[Add info here!]
SVN Directory Structure
pgadmin
agent
pgAdmin Agent related classes:
- dlgJob.cpp - PostgreSQL Job Property
- dlgSchedule.cpp - PostgreSQL Schedule Property
- dlgStep.cpp - PostgreSQL Step Property
- pgaStep.cpp - PostgreSQL Agent Step
- pgaJob.cpp - PostgreSQL Agent Job
- pgaSchedule.cpp - PostgreSQL Agent Schedule
- pgaStep.cpp - PostgreSQL Agent Step
db
Contains postgresql database related files:
- keywords.c - lexical token lookup for reserved words in PostgreSQL
- pgConn.cpp - PostgreSQL Connection class
- pgQueryThread.cpp - PostgreSQL threaded query class
- pgSet.cpp - PostgreSQL ResultSet class
dlg
Contains the source code for all dialogs used by pgAdmin like by example:
- dlgOperator.cpp - PostgreSQL Operator Property
- dlgHbaConfig.cpp - Configure setting
- dlgFindReplace.cpp - Search and replace
And more...
include
Contains all headers files (.h) used by pgAdmin, is divided in several folders for organization purpose.
schema
Contains all classes related to postgresql schemas, like by example:
- pgSchema.cpp - schema class
- pgCollection.cpp - Simple object for use with 'collection' nodes
- pgForeignKey.cpp - ForeignKey class
and others.
ui
Contains xrc dialogue resource files.
ctl
Contains the source code for controls used by pgAdmin:
- calbox.cpp - Date-picker control box
- ctlComboBox.cpp - enhanced combobox control
- ctlListView.cpp - enhanced listview control
- ctlMenuToolbar.cpp - Menu tool bar
- Note: This code is used with the authors permission from Paul Nelson (http://www.pnelsoncomposer.com/)
- ctlSecurityPanel.cpp - Panel with security information
- ctlSQLBox.cpp - SQL syntax highlighting textbox
- ctlSQLGrid.cpp - SQL Query result window
- ctlSQLResult.cpp - SQL Query result window
- ctlTree.cpp - wxTreeCtrl containing pgObjects
- explainCanvas.cpp - Explain Canvas
- explainShape.cpp - Explain Shapes
- timespin.cpp - timeSpin SpinCtrl
- xh_calb.cpp - wxCalendarBox handler
- xh_ctlcombo.cpp - ctlComboBox handler
- xh_ctltree.cpp - ctlTree handler
- xh_sqlbox.cpp - ctlSQLBox handler
- xh_timespin.cpp - wxTimeSpinCtrl handler
debugger
Contains debugger related classes like:
- debugger.cpp - Debugger factories
- dlgDirectDbg.cpp - debugger
- frmDebugger.cpp - debugger
And more
frm
Contains forms related classes like:
- frmAbout.cpp - About Box
- frmMain.cpp - The main form
- events.cpp - Event handlers, browser and statistics functions for frmMain.
- frmPassword.cpp - Change password
- frmQuery.cpp - SQL Query Box
- frmReport.cpp - The report file dialogue
slony
Constains classes related to administration of Slony-I Clusters.
utils
Utility classes used by pgAdmin like:
- factory.cpp - Object classes factory
- favourites.cpp - Query favourites
- md5.cpp - MD5 password encryption functions
- misc.cpp - Miscellaneous Utilities
- pgconfig.cpp - backend configuration classes
- sysLogger.cpp - Log handling class
- sysProcess.cpp - External process
- sysSettings.cpp - Settings handling class
- utffile.cpp - file io with BOM interpretation
And more.
Developer Notes
To add actions to the main window (frmMain)
- Create the frmXXX class that will render the new function.
- Create an actionFactory (or contextActionFactory, if the action will display in context menus too) derived factory for each action to be performed, and register it in frmMain::CreateMenus(). Never touch menu.h, or anything for that. Easy examples are frmGrantWizard or frmEditGrid.
- Implement CheckEnable() for each factory, checking the current object if the action applies.
- Implement StartDialog(), which brings up the dialog.
Following this, you should be able to add new actions on objects by just adding the source and registering the new menu in frmMain.cpp. If you think you need to modify more files, you're probably wrong.
To add objects to the object tree
- Implement the class with proper hierarchy. pgCast and dlgCast are simple examples.
- Instantiate a collection in the pgXXX object where it should be located under.
Property page dialogue layout
Design of dialogs should follow these rules as much as possible
- Standard dialog heights are 150, 250, and 280
- Standard dialog widths are 220, and 300
- Notebook is at 2,2d, size (216,216d)
- Standard button size is (50,15d)
- First control at (5,5d)
- Standard controls are at (70,[y] d), size (135,12d)
- Vertical constrol spacing is 15d, for radio buttons and checkboxes 12d
- Static text has a vertical offset of 2 relative to other controls
- Static text should be designed with 50 % space in reserve, to leave enough space for translated strings.
References
[1] http://en.wikipedia.org/wiki/WxWidgets
[2] http://www.dwheeler.com/sloccount/