1#==========================================================
2# NewDBWiz --
3#
4#    eases newbies through initial database creation
5#==========================================================
6#
7namespace eval NewDBWiz {
8    variable Win
9    variable firsttime
10    variable steps
11    variable host
12    variable pgport
13    # might template1 be changed at PG compile time ???
14    # if so, we need to change it here for PgAccess to know
15    variable templatedb "template1"
16    variable username
17    variable password
18    variable connstr ""
19    variable newdbname
20    variable newdbowner
21    variable newdbautoconn
22    variable newdblocation
23    variable newdbencoding
24    variable pgversion
25}
26
27
28#----------------------------------------------------------
29# ::NewDBWiz::start --
30#
31#   displays, and, if necessary, creates the wizard
32#
33# Arguments:
34#   none
35#
36# Returns:
37#   nothing
38#----------------------------------------------------------
39#
40proc ::NewDBWiz::start {} {
41
42    variable Win
43    variable firsttime
44    variable steps
45
46    # some initialization
47    catch {unset firsttime}
48
49    set Win(wiz) .pgaw:NewDatabaseWizard
50
51    if {[winfo exists $Win(wiz)]} {
52        destroy $Win(wiz)
53    }
54
55    # same layout as the import-export wizard
56    # keep New as title since that was the menu option title
57    tkwizard::tkwizard $Win(wiz) \
58        -title [intlmsg "New"] \
59        -geometry 500x400+100+80
60
61    # determine next step based on user interaction
62    bind $Win(wiz) <<WizNextStep>> {::NewDBWiz::nextStep}
63
64    # set up the finish code
65    bind $Win(wiz) <<WizFinish>> {::NewDBWiz::finish}
66
67    # welcome step
68    $Win(wiz) step {step_welcome} -layout advanced {
69        lappend ::NewDBWiz::steps step_welcome
70        set c [$this widget clientArea]
71        $this stepconfigure \
72            -title [intlmsg "Welcome to the New Database Wizard!"] \
73            -subtitle [intlmsg "Beginner or Advanced"] \
74            -pretext [intlmsg "This is a good place to start if you are new to PostgreSQL and PgAccess.  It can also be helpful if you just need to create a new database.  Please select your level:"]
75        ::NewDBWiz::add_step_welcome $c
76    }; # end step welcome
77
78    # connections management step
79    $Win(wiz) step {step_connections_management} -layout advanced {
80        lappend ::NewDBWiz::steps step_connections_management
81        set c [$this widget clientArea]
82        $this stepconfigure \
83            -title [intlmsg "Connections Management"] \
84            -subtitle [intlmsg "Beginner"] \
85            -pretext [intlmsg "This page will be about creating, modifying, and destroying PgAccess connections to multiple PostgreSQL clusters."]
86        #::NewDBWiz::add_step_connections_management $c
87    }; # end step connections management
88
89    # create connection step
90    $Win(wiz) step {step_create_connection} -layout advanced {
91        lappend ::NewDBWiz::steps step_create_connection
92        set c [$this widget clientArea]
93        $this stepconfigure \
94            -title [intlmsg "Create Connection"] \
95            -subtitle [intlmsg "Advanced"] \
96            -pretext [intlmsg "Choose parameters to connect with a PostgreSQL cluster.  The default 'template1' database will be used to make this connection, but it will not be modified in any way by the wizard.  The user specified must have superuser privileges to continue."] \
97            -posttext {}
98        ::NewDBWiz::add_step_create_connection $c
99    }; # end step create connection
100
101    # create database step
102    $Win(wiz) step {step_create_database} -layout advanced {
103        lappend ::NewDBWiz::steps step_create_connection
104        set c [$this widget clientArea]
105        $this stepconfigure \
106            -title [intlmsg "Create Database"] \
107            -subtitle [intlmsg "Advanced"] \
108            -pretext [intlmsg "Now enter the name of the database to create and, optionally, the name of the owner if this database is for someone else.  This database connection will automatically come under PgAccess management, unless the -noauto command line option was specified at startup."] \
109            -posttext {}
110        ::NewDBWiz::add_step_create_database $c
111    }; # end step create database
112
113    $Win(wiz) show
114    # disable the next button
115    $Win(wiz) configure -nextstep {}
116
117}; # end proc ::NewDBWiz::start
118
119
120#----------------------------------------------------------
121# ::NewDBWiz::nextStep --
122#
123#   fires when the Next button is clicked
124#
125# Arguments:
126#   none
127#
128# Returns:
129#   nothing
130#----------------------------------------------------------
131#
132proc ::NewDBWiz::nextStep {} {
133
134    variable Win
135    variable firsttime
136    variable host
137    variable pgport
138    variable templatedb
139    variable username
140    variable password
141    variable connstr
142    variable pgversion
143
144    set currentStep [$Win(wiz) cget -step]
145
146    if {$currentStep == "step_welcome"} {
147        if {$firsttime} {
148            $Win(wiz) configure -nextstep "step_connections_management"
149        } else {
150            $Win(wiz) configure -nextstep "step_create_connection"
151        }
152    }
153
154    if {$currentStep == "step_create_connection"} {
155        set connstr ""
156        if {$host!=""} {
157            append connstr " host=$host"
158        }
159        if {$pgport!=""} {
160            append connstr " port=$pgport"
161        }
162        if {$templatedb!=""} {
163            append connstr " dbname=$templatedb"
164        }
165        if {$username!=""} {
166            append connstr " user=$username"
167        }
168        if {$password!=""} {
169            append connstr " password=$password"
170        }
171        setCursor CLOCK
172        set connres [catch {set dbconn [pg_connect -conninfo $connstr]} msg]
173        setCursor NORMAL
174        if {$connres} {
175            showError $msg open_database
176            $Win(wiz) configure -nextstep "step_create_connection"
177            return 0
178        }
179        set pgversion [::Database::getPgVersion $dbconn]
180        pg_disconnect $dbconn
181    }
182
183}; # end proc ::NewDBWiz::nextStep
184
185
186#----------------------------------------------------------
187# ::NewDBWiz::finish --
188#
189#   fires when the Finish button is clicked
190#
191# Arguments:
192#   none
193#
194# Returns:
195#   nothing
196#----------------------------------------------------------
197#
198proc ::NewDBWiz::finish {} {
199
200    variable connstr
201    variable templatedb
202    variable newdbname
203    variable newdbowner
204    variable newdbautoconn
205    variable newdblocation
206    variable newdbencoding
207    variable host
208    variable pgport
209    variable username
210    variable password
211    variable pgversion
212
213    set sql "
214        CREATE DATABASE $newdbname
215          WITH TEMPLATE=[::Database::quoteObject $templatedb]
216               ENCODING=$newdbencoding
217    "
218
219    if {$newdblocation!="DEFAULT"} {
220        append sql " LOCATION='$newdblocation'"
221    }
222
223    if {$pgversion>=7.3} {
224        append sql " OWNER $newdbowner"
225    }
226
227    setCursor CLOCK
228    set connres [catch {set dbconn [pg_connect -conninfo $connstr]} msg]
229    set pgres [wpg_exec $dbconn $sql]
230    pg_disconnect $dbconn
231    setCursor NORMAL
232
233    if {$newdbautoconn} {
234        ::Connections::openNewConn $host $pgport $newdbname $username $password
235    }
236
237}; # end proc ::NewDBWiz::nextStep
238
239
240#----------------------------------------------------------
241# ::NewDBWiz::add_step_welcome --
242#
243#   creates the welcome (1st) step for the wizard
244#
245# Arguments:
246#   base_   canvas to draw the step on
247#
248# Returns:
249#   nothing
250#----------------------------------------------------------
251#
252proc ::NewDBWiz::add_step_welcome {base_} {
253
254    variable Win
255
256    set base $base_.fwel
257    set Win(step_welcome) $base_
258
259    frame $base
260    pack $base \
261        -pady 20 \
262        -fill both \
263        -expand 1
264
265    radiobutton $base.rfirst \
266        -text [intlmsg "This is my first time."] \
267        -variable ::NewDBWiz::firsttime \
268        -value 1 \
269        -command {
270            $::NewDBWiz::Win(wiz) eval {
271                $::NewDBWiz::Win(wiz) configure \
272                    -nextstep [lindex $::NewDBWiz::steps end]
273                $::NewDBWiz::Win(wiz) stepconfigure \
274                    -posttext [intlmsg "Click Next to continue."]
275            }
276        }
277    radiobutton $base.rsecond \
278        -text [intlmsg "I know what I'm doing, just let me start working."] \
279        -variable ::NewDBWiz::firsttime \
280        -value 0 \
281        -command {
282            $::NewDBWiz::Win(wiz) eval {
283                $::NewDBWiz::Win(wiz) configure \
284                    -nextstep [lindex $::NewDBWiz::steps end]
285                $::NewDBWiz::Win(wiz) stepconfigure \
286                    -posttext [intlmsg "Click Next to continue."]
287            }
288        }
289
290    pack $base.rfirst \
291        -anchor nw
292    pack $base.rsecond \
293        -anchor nw
294
295}; # end proc ::NewDBWiz::add_step_welcome
296
297
298#----------------------------------------------------------
299# ::NewDBWiz::add_step_create_connection --
300#
301#   set up params for connecting to PostgreSQL
302#
303# Arguments:
304#   base_   canvas to draw the step on
305#
306# Returns:
307#   nothing
308#----------------------------------------------------------
309#
310proc ::NewDBWiz::add_step_create_connection {base_} {
311
312    variable Win
313
314    set base $base_.fcc
315    set Win(step_create_connection) $base_
316
317    frame $base
318    pack $base \
319        -pady 20 \
320        -fill both \
321        -expand 1
322
323    set wijits [list]
324
325    Label $base.lhost \
326        -text [intlmsg "Host"]
327    Entry $base.ehost \
328        -text "localhost" \
329        -textvariable ::NewDBWiz::host
330    lappend wijits [list lhost ehost]
331
332    Label $base.lpgport \
333        -text [intlmsg "Port"]
334    SpinBox $base.sbpgport \
335        -text "5432" \
336        -textvariable ::NewDBWiz::pgport \
337        -range [list 0 65535 1]
338    lappend wijits [list lpgport sbpgport]
339
340    Label $base.lusername \
341        -text [intlmsg "Username"]
342    Entry $base.eusername \
343        -text "" \
344        -textvariable ::NewDBWiz::username
345    lappend wijits [list lusername eusername]
346
347    Label $base.lpassword \
348        -text [intlmsg "Password"]
349    Entry $base.epassword \
350        -text "" \
351        -textvariable ::NewDBWiz::password \
352        -show *
353    lappend wijits [list lpassword epassword]
354
355    set row 0
356    foreach w $wijits {
357        set w0 [lindex $w 0]
358        set w1 [lindex $w 1]
359        grid $base.$w0 \
360            -column 0 \
361            -row $row \
362            -sticky e
363        grid $base.$w1 \
364            -column 1 \
365            -row $row \
366            -sticky news
367        incr row
368    }
369
370}; # end proc ::NewDBWiz::add_step_create_connection
371
372
373#----------------------------------------------------------
374# ::NewDBWiz::add_step_create_database --
375#
376#   create a database on the connection to template1
377#
378# Arguments:
379#   base_   canvas to draw the step on
380#
381# Returns:
382#   nothing
383#----------------------------------------------------------
384#
385proc ::NewDBWiz::add_step_create_database {base_} {
386
387    global PgAcVar
388
389    variable Win
390    variable connstr
391    variable pgversion
392    variable templatedb
393    variable username
394    variable newdbname
395
396    set base $base_.fcd
397    set Win(step_create_database) $base_
398
399    frame $base
400    pack $base \
401        -pady 20 \
402        -fill both \
403        -expand 1
404
405    set wijits [list]
406
407    Label $base.lnewdb \
408        -text [intlmsg "New Database Name"]
409    set Win(cbofdbs) $base.cbnewdb
410    ComboBox $base.cbnewdb \
411        -text "" \
412        -textvariable ::NewDBWiz::newdbname
413    lappend wijits [list lnewdb cbnewdb]
414
415    # maybe they already type the new name into the old dialog
416    if {[info exists PgAcVar(New_Database_Name)]} {
417        set newdbname $PgAcVar(New_Database_Name)
418    }
419
420    # well we cant assign an owner before 7.3
421    if {$pgversion>=7.3} {
422        Label $base.lowner \
423            -text [intlmsg "Owner"]
424        set Win(cbofowners) $base.cbowner
425        ComboBox $base.cbowner \
426            -text $username \
427            -textvariable ::NewDBWiz::newdbowner
428        lappend wijits [list lowner cbowner]
429    }
430
431    Label $base.ltemplatedb \
432        -text [intlmsg "Template"]
433    set Win(cbofdbs2) $base.cbtemplatedb
434    ComboBox $base.cbtemplatedb \
435        -text $templatedb \
436        -textvariable ::NewDBWiz::templatedb
437    lappend wijits [list ltemplatedb cbtemplatedb]
438
439    Label $base.lloc \
440        -text [intlmsg "Location"]
441    Entry $base.eloc \
442        -text "DEFAULT" \
443        -textvariable ::NewDBWiz::newdblocation
444    lappend wijits [list lloc eloc]
445
446    Label $base.lenc \
447        -text [intlmsg "Encoding"]
448    set Win(cbenc) $base.cbenc
449    ComboBox $base.cbenc \
450        -text "DEFAULT" \
451        -textvariable ::NewDBWiz::newdbencoding
452    lappend wijits [list lenc cbenc]
453
454    Label $base.lspace1 \
455        -text ""
456    Label $base.lspace2 \
457        -text ""
458    lappend wijits [list lspace1 lspace2]
459
460    Label $base.lconn \
461        -text ""
462    checkbutton $base.cbconn \
463        -text [intlmsg "Connect immediately after creation."] \
464        -variable ::NewDBWiz::newdbautoconn
465    lappend wijits [list lconn cbconn]
466
467    set row 0
468    foreach w $wijits {
469        set w0 [lindex $w 0]
470        set w1 [lindex $w 1]
471        grid $base.$w0 \
472            -column 0 \
473            -row $row \
474            -sticky e
475        grid $base.$w1 \
476            -column 1 \
477            -row $row \
478            -sticky news
479        incr row
480    }
481
482    # fill in the list of databases and users on the cluster
483    setCursor CLOCK
484    set connres [catch {set dbconn [pg_connect -conninfo $connstr]} msg]
485    $Win(cbofdbs) configure -values \
486        [::Database::getDatabasesList $dbconn 1]
487    $Win(cbofdbs2) configure -values \
488        [::Database::getDatabasesList $dbconn 1]
489    # well we cant assign an owner before 7.3
490    if {$pgversion>=7.3} {
491        $Win(cbofowners) configure -values \
492            [::Database::getUsersList $dbconn]
493    }
494    pg_disconnect $dbconn
495    setCursor NORMAL
496
497}; # end proc ::NewDBWiz::add_step_create_database
498
499
500