PgAdmin Internals

From PostgreSQL wiki
Jump to navigationJump to search

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]:

Table 1-1. pgAdmin development effort. Retrieved at 03-16-2012 04:30
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:

Table 1-2. Programming Languages
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:

Table 1-3. Programming Languages divide by directory at pgAdmin folder
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:

  1. Braces are always on lines of their own.
  2. Only preprocessor directives, globals and function headers/closing braces should normally be left-justified
  3. Indent == Tab (most developers set their tab width to 4).
  4. Leave a blank line between logical blocks of code for clarity.
  5. Add a space after all but the last semi-colon in for loops for clarity.
  6. 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.

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:

Building

  1. Install libxml2 and libxslt if they are not already present on your system, per the instructions included with them.
  2. Install PostgreSQL per the instructions included. It is recommended that you build with OpenSSL support, using the --with-openssl configure option.
  3. 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
  4. Install wxWidgets contrib modules.
    • cd contrib/
    • make
    • sudo make install
  5. 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:

Building

  1. 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.
  2. Install PostgreSQL per the instructions included. It is recommended that you build with OpenSSL support, using the --with-openssl configure option.
  3. 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
  4. 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.
  5. 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:

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

  1. Unpack the wxMSW source code to a convenient location pointed to by the %WXWIN% environment variable.
  2. Install PostgreSQL to a convenient location pointed to by the %PGDIR% environment variable.
  3. Unpack the pgAdmin source code to a convenient location.
  4. From a Visual Studio command prompt, run the wxWidgets build script included in the pgAdmin source tree at xtra/wx-build/build-wxmsw.bat
  5. Unpack the libxml2, libxslt and dependency binaries in a directory pointed to by the %PGBUILD% environment variable.
  6. 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.


Common Errors

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
  • 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/