<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected{color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity=60)';}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0px; top:0px;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser

Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])

<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]

----
Also see [[AdvancedOptions]]
<<importTiddlers>>
The following table gives data mapping when binding qore types by value.  Be aware that ~PostgreSQL does only limited implicit type conversions when binding by value; to specify other types, either use a ~PostgreSQL type cast (i.e. {{{::type}}}) or use the [[pgsql_bind()]] function.

|!~QoreType|!~PostgreSQL Type|!Description|h
|{{{Type::Int}}}|{{{INT2, INTEGER, INT8}}}|Depending on the size of the integer, the appropriate ~PostgreSQL type is bound. This is to avoid errors by using a type larger than that specified for the column or variable, as converting from a smaller type to a larger type is done automatically by the server.|
|{{{Type::Float}}}|{{{FLOAT88}}}|Qore float data is converted directly to ~PostgreSQL {{{float8}}} data|
|{{{Type::String}}}|{{{TEXT}}}|The character sencoding is converted to the encoding specified for the connection if necessary.|
|{{{Type::Boolean}}}|{{{BOOLEAN}}}|Qore boolean values are converted directly to the ~PostgreSQL boolean format|
|{{{Type::Date}}}|{{{INTERVAL, TIMESTAMP}}}|Relative date/time values are bound as interval data, absolute date/time values are bound as timestamp data.|
|{{{Type::Binary}}}|{{{BYTEA}}}|Qore binary data is bound directly as bytea data.|
When binding by value, ~PostgreSQL servers do not convert data types as freely as many other database servers; instead the server throws an error if the bound type does not closely match the expected data type.  For example, binding a string or float value to a {{{NUMERIC}}} data type will cause an exception to be thrown. To successfully bind by value, either use a ~PostgreSQL type cast in the SQL text (i.e. {{{::type}}}) or use the [[pgsql_bind()]] function to specify the type to bind.  See [[Binding By Value]] for more information about how types are bound when binding by value with this driver.

For {{{NUMERIC}}} fields, the {{{%d}}} specification in the query string can be used to substitute a numeric value or a literal {{{null}}} directly in the query string, providing the same effect as a bind by value in a very convenient form for the programmer.  For example:

{{{
# the %d will be substituted with the value of $id directly in the query text
# or with a "null" in case $id has no value (or is NULL)
my $results = $db.select("select * from table where id = %d", $id);
}}}

Due to the fact that Qore date/time values do not currently support time zone information, when ~PostgreSQL data including a time zone component is converted to a Qore data type, the time zone information is lost. Also, Qore date/time values support a millisecond resolution, while ~PostgreSQL supports microsecond resolution. All decimal places after milliseconds are discarded when converting to a Qore date/time value. Be aware that values bound to {{{TIMESTAMP WITH TIME ZONE}}} and {{{ABSTIME}}} columns are converted to GMT by the server and returned as GMT, therefore different date/time values may be returned if binding date/time values in local time.

Note that binding by placeholder is not required or supported by this driver as ~PostgreSQL returns values directly; Qore DBI placeholder buffer specifications are ignored when the pgsql driver is used.

When binding arrays, all data types in the Qore list must be identical. When binding multi-dimensional arrays, the number of elements in each list in each array dimension must be the same. These are ~PostgreSQL restrictions (at least up to version 8.2).

When retrieving ~PostgreSQL data, ~PostgreSQL types are converted to Qore types as per [[PostgreSQL to Qore Type Mappings]].

Background: #fff
Foreground: #000
PrimaryPale: #5a0
PrimaryLight: #4a0
PrimaryMid: #020
PrimaryDark: #390
SecondaryPale: #ffc
SecondaryLight: #af0
SecondaryMid: #340
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
David Nichols is the author of the [[Qore programming language|http://qoretechnologies.com/qore]] and of this xmlsec module.
You can reach me at: mailto:[email protected]
[[Introduction]]
[[Transaction Management]]
[[Binding and Types]]
[[Stored Procedures]]
The pgsql module provides a [[PostgreSQL|http://www.postgresql.org]] driver to Qore's DBI system, allowing Qore programs to access ~PostgreSQL databases through the {{{Datasource}}} and {{{DatasourcePool}}} classes.

This module is released under the [[LGPL 2.1|http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html]] and is tagged as such in the module's header (meaning it can be loaded unconditionally regardless of how the Qore library was initialized).

Example of creating a ~PostgreSQL Datasource:

{{{
$db = new Datasource(SQL::DSPGSQL, $user, $pass, $db, $charset, $hostname);
}}}

This driver supports the following DBI capabilities when compiled against ~PostgreSQL 7 or better: {{{DBI_CAP_TRANSACTION_MANAGEMENT}}}, {{{DBI_CAP_CHARSET_SUPPORT}}}, {{{DBI_CAP_LOB_SUPPORT}}}, {{{DBI_CAP_STORED_PROCEDURES}}}, {{{DBI_CAP_BIND_BY_VALUE}}}.

The driver employs efficient binary bindings for all non-text data types and fully supports multidimensional arrays when selecting and binding by value. The driver determines on a per-connection basis by querying server capabilities whether the server uses 8-byte integer or floating-point data for date/time types, and also whether or not a binary day value is included in intervals.

The {{{Datasource::getServerVersion()}}} method is implemented for this driver and returns an integer giving the major, minor, and sub version numbers in a single integer according to the following formula: 

{{{
major_version * 10000 + minor_version * 100 + sub_version
}}}

(For example: 80204 = 8.2.4). The {{{Datasource::getClientVersion()}}} is not implemented for this driver.

Like all Qore components, the ~PostgreSQL DBI driver is thread-safe.
[[Introduction]]
[[Binding and Types]]
[[Transaction Management]]
[[Stored Procedures]]
[[Binding By Value]]
[[PostgreSQL to Qore Type Mappings]]
[[pgsql_bind()]]
''~PostgreSQL to Qore Type Mappings''
|!~PostgreSQL Type|!Qore Type|!Notes|h
|{{{BOOLEAN}}}|{{{Type::Boolean}}}|direct conversion|
|{{{BYTEA}}}|{{{Type::Binary}}}|direct conversion|
|{{{CHAR}}}|{{{Type::String}}}|trailing whitespace is removed|
|{{{BPCHAR}}}|{{{Type::String}}}|trailing whitespace is removed|
|{{{INT8}}}|{{{Type::Int}}}|direct conversion|
|{{{INTEGER}}}|{{{Type::Int}}}|direct conversion|
|{{{OID}}}|{{{Type::Int}}}|direct conversion|
|{{{XID}}}|{{{Type::Int}}}|direct conversion|
|{{{CID}}}|{{{Type::Int}}}|direct conversion|
|{{{INT2}}}|{{{Type::Int}}}|direct conversion|
|{{{TEXT}}}|{{{Type::String}}}|direct conversion|
|{{{CHAR VARYING}}}|{{{Type::String}}}|trailing whitespace is removed|
|{{{NAME}}}|{{{Type::String}}}|direct conversion|
|{{{FLOAT4}}}|{{{Type::Float}}}|direct conversion|
|{{{FLOAT8}}}|{{{Type::Float}}}|direct conversion|
|{{{ABSTIME}}}|{{{Type::Date}}} (absolute)|direct conversion|
|{{{RELTIME}}}|{{{Type::Date}}} (relative)|direct conversion to relative seconds|
|{{{TIMESTAMP}}}|{{{Type::Date}}} (absolute)|When compiled with qore 0.8.0+, microseconds are maintained.|
|{{{TIMESTAMP WITH TIMEZONE}}}|{{{Type::Date}}} (absolute)|When compiled with qore 0.8.0+, microseconds and time zone information are maintained.|
|{{{DATE}}}|{{{Type::Date}}} (absolute)|direct conversion|
|{{{INTERVAL}}}|{{{Type::Date}}} (relative)|direct conversion to relative months, seconds, microseconds (with qore 0.8.0+, otherwise milliseconds), and for servers that send a separate day value, to relative days.|
|{{{TIME}}}|{{{Type::Date}}} (absolute)|When compiled with qore 0.8.0+, microseconds are maintained. Note that the date portion is set to January 1, 1970, the beginning of the 64-bit qore epoch.|
|{{{TIME WITH TIMEZONE}}}|{{{Type::Date}}} (absolute)|When compiled with qore 0.8.0+, microseconds and time zone information are maintained. Note that the date portion is set to January 1, 1970, the beginning of the 64-bit qore epoch.|
|{{{TINTERVAL}}}|{{{Type::String}}}|string format is given in ~PostgreSQL tinterval format ([{{{"YYYY-MM-DD hh:mm:ss"}}} {{{"YYYY-MM-DD hh:mm:ss"}}}])|
|{{{NUMERIC}}}|{{{Type::String}}}|To avoid loss of precision, the information is converted to a string|
|{{{CASH}}}|{{{Type::Float}}}|direct conversion|
|{{{MACADDR}}}|{{{Type::String}}}|format: xx:xx:xx:xx:xx:xx|
|{{{INET}}}|{{{Type::String}}}|ipv4: n.n.n.n/net, ipv6: x:x:x:x:x:x:x:x/net|
|{{{CIDR}}}|{{{Type::String}}}|ipv4: n.../net, ipv6: x:...::/net|
|{{{TID}}}|{{{Type::String}}}|format: (n,n)|
|{{{BIT}}}|{{{Type::Binary}}}|direct conversion|
|{{{VARBIT}}}|{{{Type::Binary}}}|direct conversion|
|{{{POINT}}}|{{{	Type::String}}}|format: n,n|
|{{{LSEG}}}|{{{Type::String}}}|format: (n,n),(n,n)|
|{{{BOX}}}|{{{Type::String}}}|format: (n,n),(n,n)|
|{{{PATH}}}|{{{Type::String}}}|in ~PostgreSQL text format depending on path type|
|{{{POLYGON}}}|{{{Type::String}}}|in ~PostgreSQL text format for polygons ((n,n),...)|
|{{{CIRCLE}}}|{{{Type::String}}}|format: <(n,n),n>|

Qore pgsql Module Documentation
Stored procedure execution is supported; the following is an example of a stored procedure call:

Example ~PostgreSQL {{{PLPG/SQL}}} function:

{{{
create or replace function int_test(val int4) returns int4 as $$
begin
    return val * 2;
end;
$$ language plpgsql;
}}}

Example Qore code to call this function:

{{{
$result = $db.exec("select int_test(%v)", 11);
printf("%N\n", $result);
}}}

Resulting in:

{{{
hash: (1 member)
  int_test : 22
}}}
When the {{{Datasource}}} is not in auto-commit mode, this driver automatically inserts {{{begin}}} statements at the start of each transaction to provide consistent transaction handling across all Qore DBI drivers; it's not necessary to do this manually.

Note that an exception while already in a transaction will have the effect that the pgsql connection cannot be used until the transaction is closed; this is different from most other current Qore DBI drivers. An exception in a {{{Datasource::exec()}}} method as the first statement of a transaction will cause an automatic implicit rollback to be executed to maintain compatibility with other Qore DBI drivers.
Type Constants for [[pgsql_bind()]]

|!Constant|!Description|h
|{{{PG_TYPE_BOOL}}}|{{{boolean}}}|
|{{{PG_TYPE_BYTEA}}}|{{{bytea}}}|
|{{{PG_TYPE_CHAR}}}|{{{char}}}|
|{{{PG_TYPE_NAME}}}|{{{name}}}|
|{{{PG_TYPE_INT8}}}|{{{int8}}}|
|{{{PG_TYPE_INT2}}}|{{{int2}}}|
|{{{PG_TYPE_INT2VECTOR}}}|{{{int2vector}}}|
|{{{PG_TYPE_INT4}}}|{{{integer}}}|
|{{{PG_TYPE_REGPROC}}}|{{{regproc}}}|
|{{{PG_TYPE_TEXT}}}|{{{text}}}|
|{{{PG_TYPE_OID}}}|{{{oid}}}|
|{{{PG_TYPE_TID}}}|{{{tid}}} (tuple id)|
|{{{PG_TYPE_XID}}}|{{{xid}}} (transaction id)|
|{{{PG_TYPE_CID}}}|{{{cid}}} (command identifier)|
|{{{PG_TYPE_VECTOROID}}}|{{{vector}}}|
|{{{PG_TYPE_TYPE_RELTYPE}}}|{{{type_reltype}}}|
|{{{PG_TYPE_ATTRIBUTE_RELTYPE}}}|{{{attribute_reltype}}}|
|{{{PG_TYPE_PROC_RELTYPE}}}|{{{proc_reltype}}}|
|{{{PG_TYPE_CLASS_RELTYPE}}}|{{{class_reltype}}}|
|{{{PG_TYPE_POINT}}}|{{{point}}}|
|{{{PG_TYPE_LSEG}}}|{{{lseg}}} (line segment)|
|{{{PG_TYPE_PATH}}}|{{{path}}}|
|{{{PG_TYPE_BOX}}}|{{{box}}}|
|{{{PG_TYPE_POLYGON}}}|{{{polygon}}}|
|{{{PG_TYPE_LINE}}}|{{{line}}}|
|{{{PG_TYPE_FLOAT4}}}|{{{float4}}}|
|{{{PG_TYPE_FLOAT8}}}|{{{float8}}}|
|{{{PG_TYPE_ABSTIME}}}|{{{abstime}}} (absolute time)|
|{{{PG_TYPE_RELTIME}}}|{{{reltime}}} (relative time)|
|{{{PG_TYPE_TINTERVAL}}}|{{{tinterval}}} (time interval)|
|{{{PG_TYPE_UNKNOWN}}}|{{{unknown}}}|
|{{{PG_TYPE_CIRCLE}}}|{{{circle}}}|
|{{{PG_TYPE_CASH}}}|{{{cash}}}|
|{{{PG_TYPE_MACADDR}}}|{{{macaddr}}} (MAC address)|
|{{{PG_TYPE_INET}}}|{{{inet}}} (INET address)|
|{{{PG_TYPE_CIDR}}}|{{{CIDR}}} (network addresses in Classless Intenet Domain Routing format)|
|{{{PG_TYPE_ACLITEM}}}|{{{aclitem}}}|
|{{{PG_TYPE_BPCHAR}}}|{{{bpchar}}}|
|{{{PG_TYPE_VARCHAR}}}|{{{character varying}}}|
|{{{PG_TYPE_DATE}}}|{{{date}}}|
|{{{PG_TYPE_TIME}}}|{{{time}}}|
|{{{PG_TYPE_TIMESTAMP}}}|{{{timestamp}}}|
|{{{PG_TYPE_TIMESTAMPTZ}}}|{{{timestamp with time zone}}}|
|{{{PG_TYPE_INTERVAL}}}|{{{interval}}}|
|{{{PG_TYPE_TIMETZ}}}|{{{time with time zone}}}|
|{{{PG_TYPE_BIT}}}|{{{bit}}}|
|{{{PG_TYPE_VARBIT}}}|{{{bit varying}}}|
|{{{PG_TYPE_NUMERIC}}}|{{{numeric}}}|
|{{{PG_TYPE_REFCURSOR}}}|{{{refcursor}}}|
|{{{PG_TYPE_REGPROCEDURE}}}|{{{regprocedure}}}|
|{{{PG_TYPE_REGOPER}}}|{{{regoper}}}|
|{{{PG_TYPE_REGOPERATOR}}}|{{{regoperator}}}|
|{{{PG_TYPE_REGCLASS}}}|{{{regclass}}}|
|{{{PG_TYPE_REGTYPE}}}|{{{regtype}}}|
|{{{PG_TYPE_RECORD}}}|{{{record}}}|
|{{{PG_TYPE_CSTRING}}}|{{{cstring}}}|
|{{{PG_TYPE_ANY}}}|{{{any}}}|
|{{{PG_TYPE_VOID}}}|{{{void}}}|
|{{{PG_TYPE_TRIGGER}}}|{{{trigger}}}|
|{{{PG_TYPE_LANGUAGE_HANDLER}}}|{{{language_handler}}}|
|{{{PG_TYPE_INTERNAL}}}|{{{internal}}}|
|{{{PG_TYPE_OPAQUE}}}|{{{opaque}}}|
|{{{PG_TYPE_ANYELEMENT}}}|{{{anyelement}}}|
|{{{PG_TYPE_INT4ARRAY}}}|{{{int4[]}}}|
|{{{PG_TYPE_CIRCLEARRAY}}}|{{{circle[]}}}|
|{{{PG_TYPE_MONEYARRAY}}}|{{{money[]}}}|
|{{{PG_TYPE_BOOLARRAY}}}|{{{bool[]}}}|
|{{{PG_TYPE_BYTEAARRAY}}}|{{{bytea[]}}}|
|{{{PG_TYPE_NAMEARRAY}}}|{{{name[]}}}|
|{{{PG_TYPE_INT2ARRAY}}}|{{{int2[]}}}|
|{{{PG_TYPE_TEXTARRAY}}}|{{{text[]}}}|
|{{{PG_TYPE_OIDARRAY}}}|{{{oid[]}}}|
|{{{PG_TYPE_TIDARRAY}}}|{{{tid[]}}} (array of tuple ~IDs)|
|{{{PG_TYPE_XIDARRAY}}}|{{{xid[]}}} (array of transaction ~IDs)|
|{{{PG_TYPE_CIDARRAY}}}|{{{cid[]}}} (array of command ~IDs)|
|{{{PG_TYPE_BPCHARARRAY}}}|{{{bpchar[]}}}|
|{{{PG_TYPE_VARCHARARRAY}}}|{{{char varying[]}}}|
|{{{PG_TYPE_INT8ARRAY}}}|{{{int8[]}}}|
|{{{PG_TYPE_POINTARRAY}}}|{{{point[]}}}|
|{{{PG_TYPE_LSEGARRAY}}}|{{{lseg[]}}}|
|{{{PG_TYPE_PATHARRAY}}}|{{{path[]}}}|
|{{{PG_TYPE_BOXARRAY}}}|{{{box[]}}}|
|{{{PG_TYPE_FLOAT4ARRAY}}}|{{{float4[]}}}|
|{{{PG_TYPE_FLOAT8ARRAY}}}|{{{float8[]}}}|
|{{{PG_TYPE_ABSTIMEARRAY}}}|{{{abstime[]}}}|
|{{{PG_TYPE_RELTIMEARRAY}}}|{{{reltime[]}}}|
|{{{PG_TYPE_TINTERVALARRAY}}}|{{{tinterval[]}}}|
|{{{PG_TYPE_POLYGONARRAY}}}|{{{polygon[]}}}|
|{{{PG_TYPE_MACADDRARRAY}}}|{{{macaddr[]}}}|
|{{{PG_TYPE_INETARRAY}}}|{{{inet[]}}}|
|{{{PG_TYPE_CIDRARRAY}}}|{{{cidr[]}}}|
|{{{PG_TYPE_TIMESTAMPARRAY}}}|{{{timestamp[]}}}|
|{{{PG_TYPE_DATEARRAY}}}|{{{date[]}}}|
|{{{PG_TYPE_TIMEARRAY}}}|{{{time[]}}}|
|{{{PG_TYPE_TIMESTAMPTZARRAY}}}|{{{timestamp with time zone[]}}}|
|{{{PG_TYPE_INTERVALARRAY}}}|{{{interval[]}}}|
|{{{PG_TYPE_NUMERICARRAY}}}|{{{numeric[]}}}|
|{{{PG_TYPE_TIMETZARRAY}}}|{{{time with time zone[]}}}|
|{{{PG_TYPE_BITARRAY}}}|{{{bit[]}}}|
|{{{PG_TYPE_VARBITARRAY}}}|{{{bit varying[]}}}|
|{{{PG_TYPE_ANYARRAY}}}|{{{any[]}}}|
!Synopsis
Creates a hash data structure understood by the pgsql DBI driver when binding values in SQL queries that allows programmers to directly specify the ~PostgreSQL data type for the bind. Use the [[pgsql type constants|Type Constants for pgsql_bind()]] to specify the ~PostgreSQL data type for the bind. If the value to bind is {{{NOTHING}}} or {{{NULL}}}, a {{{NULL}}} will be bound as the value, regardless of the ~PostgreSQL type code provided as the first argument.
!Usage
{{{
pgsql_bind(pgsql_type_code, value)
}}}
The first argument must be one of the [[pgsql type constants|Type Constants for pgsql_bind()]]; whereas the second argument is the value to bind.
!Example
{{{
# we use pgsql_bind() to bind a money type by value, otherwise the server would raise an error
my $amount = 400.56;
my $results = $db.select("select * from table where amount > %v", pgsql_bind(PG_TYPE_CASH, $amount));
}}}
!Return Value
: {{{hash}}}: The hash returned by the function encodes the desired ~PostgreSQL type for the bind and the value for binding in the {{{^pgtype^}}} and {{{^value^}}} keys.
!Exceptions
: {{{PGSQL-BIND-ERROR}}}: missing type code as first argument