I webified one of the old All Basic code challenge projects that is based on Gtk and MySQL as the DB. The real benefit as I see it comes to light when you start running detached updates and reports on the server in a multi-threaded task.
csgtkcustomer.sb
' All Basic address book challenge - 9/15/2008
'
' Basic Language: ScriptBasic 2.1 (Windows / Linux)
'
' Authors: Peter van Eerten - www.gtk-server.org
' John Spikowski - www.scriptbasic.org
' GTK-server extension module
INCLUDE gtk.bas
' cURL extension module
INCLUDE curl.bas
GLOBAL CONST TAB = "\t"
GLOBAL CONST NL = "\n"
ch = curl::init()
SUB Fill_Data
' clear the list
gtk_list_store_clear(List_Store)
curl::option(ch,"URL","http://127.0.0.1:8080/mtsb/gtkdbweb.sb")
curl::option(ch,"COOKIEJAR","/home/jrs/SB/test/cookie.txt")
db_response = curl::perform(ch)
WHILE LEN(db_response)
eor = INSTR(db_response,NL)
this_row = LEFT(db_response, eor - 1)
SPLIT this_row BY TAB TO dbrow{"cust_id"},dbrow{"cust_name"},dbrow{"cust_addr"},dbrow{"cust_city"},dbrow{"cust_state"},dbrow{"cust_zip"},dbrow{"cust_phone"}
gtk_list_store_append(List_Store, List_Iter)
gtk_list_store_set(List_Store, List_Iter, 0, dbrow{"cust_id"}, -1)
gtk_list_store_set(List_Store, List_Iter, 1, dbrow{"cust_name"}, -1)
gtk_list_store_set(List_Store, List_Iter, 2, dbrow{"cust_addr"}, -1)
gtk_list_store_set(List_Store, List_Iter, 3, dbrow{"cust_city"}, -1)
gtk_list_store_set(List_Store, List_Iter, 4, dbrow{"cust_state"}, -1)
gtk_list_store_set(List_Store, List_Iter, 5, dbrow{"cust_zip"}, -1)
gtk_list_store_set(List_Store, List_Iter, 6, dbrow{"cust_phone"}, -1)
db_response = MID(db_response, eor + 1)
WEND
END SUB
SUB Add_Edit_Data
' determine which mode we are
IF Add_Edit_Mode = 1 THEN
gtk_list_store_append(List_Store, List_Iter)
END IF
' Get the etries, currently no checking
info[0] = gtk_entry_get_text(EntryID)
info[1] = gtk_entry_get_text(EntryName)
info[2] = gtk_entry_get_text(EntryAddress)
info[3] = gtk_entry_get_text(EntryCity)
info[4] = gtk_entry_get_text(EntryState)
info[5] = gtk_entry_get_text(EntryZip)
info[6] = gtk_entry_get_text(EntryPhone)
' Add mode, store the info into the list widget
FOR i = 0 TO 6
gtk_list_store_set(List_Store, List_Iter, i, info[i], -1)
NEXT i
' Delete the entries
gtk_editable_delete_text(EntryID, 0, -1)
gtk_editable_delete_text(EntryName, 0, -1)
gtk_editable_delete_text(EntryAddress, 0, -1)
gtk_editable_delete_text(EntryCity, 0, -1)
gtk_editable_delete_text(EntryState, 0, -1)
gtk_editable_delete_text(EntryZip, 0, -1)
gtk_editable_delete_text(EntryPhone, 0, -1)
post_str = "cust_id=" & curl::escape(info[0]) & "&cust_name=" & curl::escape(info[1]) & "&cust_addr=" & curl::escape(info[2]) & "&cust_city=" & curl::escape(info[3]) & "&cust_state=" & curl::escape(info[4]) & "&cust_zip=" & curl::escape(info[5]) & "&cust_phone=" & curl::escape(info[6]) & "&maint_flag=" & curl::escape(Add_Edit_Mode)
curl::option(ch,"URL","http://127.0.0.1:8080/mtsb/gtkdbweb.sb")
curl::option(ch,"COOKIE","webcust")
curl::option(ch,"POST")
curl::option(ch,"POSTFIELDS",post_str)
txt = curl::perform(ch)
END SUB
SUB Del_Data
' Check if a row is selected
IF gtk_tree_selection_get_selected(Tree_Sel, "NULL", List_Iter) = "1" THEN
gtk_list_store_remove(List_Store, List_Iter)
post_str = "cust_id=" & curl::escape(info[0]) & "&maint_flag=" & "3"
curl::option(ch,"URL","http://127.0.0.1:8080/mtsb/gtkdbweb.sb")
curl::option(ch,"COOKIE","webcust")
curl::option(ch,"POST")
curl::option(ch,"POSTFIELDS",post_str)
txt = curl::perform(ch)
ELSE
gtk_widget_show_all(Error_Msg)
END IF
END SUB
' MAIN program
' Optionally enable GTK logging
gtk_server_cfg("-log=log.txt")
' Get GLADE definition
xml = glade_xml_new("form.glade")
glade_xml_signal_autoconnect(xml)
' Get main window ID and connect signal
Main_Window = glade_xml_get_widget(xml, "Main_Window")
gtk_server_connect(Main_Window, "delete-event", "Main_Window")
' Get button IDs and connect signals
Add_Button = glade_xml_get_widget(xml, "Add_Button")
gtk_server_connect(Add_Button, "clicked", "Add_Button")
Del_Button = glade_xml_get_widget(xml, "Del_Button")
gtk_server_connect(Del_Button, "clicked", "Del_Button")
Edit_Button = glade_xml_get_widget(xml, "Edit_Button")
gtk_server_connect(Edit_Button, "clicked", "Edit_Button")
Exit_Button = glade_xml_get_widget(xml, "Exit_Button")
gtk_server_connect(Exit_Button, "clicked", "Exit_Button")
' Get scrolled window
Scrolled_Window = glade_xml_get_widget(xml, "Scrolled_Window")
' Define the list
List_Iter = gtk_server_opaque()
GTK::gtk("gtk_server_redefine gtk_list_store_new NONE WIDGET 8 INT INT INT INT INT INT INT INT")
List_Store = GTK::gtk("gtk_list_store_new 7 64 64 64 64 64 64 64")
List_Choice = gtk_tree_view_new_with_model(List_Store)
GTK::gtk("gtk_server_connect " & List_Choice & " button-press-event " & List_Choice & " 1")
gtk_tree_view_set_headers_visible(List_Choice, 1)
gtk_tree_view_set_headers_clickable(List_Choice, 1)
gtk_tree_view_set_grid_lines(List_Choice, 3)
gtk_tree_sortable_set_sort_column_id(List_Store, 0, 0)
Tree_Sel = gtk_tree_view_get_selection(List_Choice)
gtk_tree_selection_set_mode(Tree_Sel, 2)
Txt_Cell = gtk_cell_renderer_text_new()
List_Column0 = gtk_tree_view_column_new_with_attributes("ID", Txt_Cell, "text", 0, "NULL")
gtk_tree_view_append_column(List_Choice, List_Column0)
gtk_tree_view_column_set_resizable(List_Column0, 1)
gtk_tree_view_column_set_clickable(List_Column0, 1)
List_Column1 = gtk_tree_view_column_new_with_attributes("Name", Txt_Cell, "text", 1, "NULL")
gtk_tree_view_append_column(List_Choice, List_Column1)
gtk_tree_view_column_set_resizable(List_Column1, 1)
List_Column2 = gtk_tree_view_column_new_with_attributes("Address", Txt_Cell, "text", 2, "NULL")
gtk_tree_view_append_column(List_Choice, List_Column2)
gtk_tree_view_column_set_resizable(List_Column2, 1)
List_Column3 = gtk_tree_view_column_new_with_attributes("City", Txt_Cell, "text", 3, "NULL")
gtk_tree_view_append_column(List_Choice, List_Column3)
gtk_tree_view_column_set_resizable(List_Column3, 1)
List_Column4 = gtk_tree_view_column_new_with_attributes("State", Txt_Cell, "text", 4, "NULL")
gtk_tree_view_append_column(List_Choice, List_Column4)
gtk_tree_view_column_set_resizable(List_Column4, 1)
List_Column5 = gtk_tree_view_column_new_with_attributes("ZIP", Txt_Cell, "text", 5, "NULL")
gtk_tree_view_append_column(List_Choice, List_Column5)
gtk_tree_view_column_set_resizable(List_Column5, 1)
List_Column6 = gtk_tree_view_column_new_with_attributes("Phone", Txt_Cell, "text", 6, "NULL")
gtk_tree_view_append_column(List_Choice, List_Column6)
gtk_tree_view_column_set_resizable(List_Column6, 1)
gtk_container_add(Scrolled_Window, List_Choice)
gtk_widget_show_all(Scrolled_Window)
' Add entry window
Entry_Field = glade_xml_get_widget(xml, "Entry_Field")
gtk_server_connect(Entry_Field, "delete-event", "Entry_Field")
' Get button ID and connect signal
Entry_Ok_Button = glade_xml_get_widget(xml, "Entry_Ok_Button")
gtk_server_connect(Entry_Ok_Button, "clicked", "Entry_Ok_Button")
Entry_Can_Button = glade_xml_get_widget(xml, "Entry_Can_Button")
gtk_server_connect(Entry_Can_Button, "clicked", "Entry_Can_Button")
' Get ID's for the textentries
EntryID = glade_xml_get_widget(xml, "EntryID")
EntryName = glade_xml_get_widget(xml, "EntryName")
EntryAddress = glade_xml_get_widget(xml, "EntryAddress")
EntryCity = glade_xml_get_widget(xml, "EntryCity")
EntryState = glade_xml_get_widget(xml, "EntryState")
EntryZip = glade_xml_get_widget(xml, "EntryZip")
EntryPhone = glade_xml_get_widget(xml, "EntryPhone")
' Warning dialog, define here because of a bug in Glade
Warning_Msg = gtk_message_dialog_new(Main_Window, 1, 1, 4, "\nAre you sure to delete this entry?", "''")
gtk_window_set_title(Warning_Msg, "Warning")
gtk_server_connect(Warning_Msg, "delete-event", "Warning_Msg")
gtk_server_connect(Warning_Msg, "response", "Warning_Msg_Response")
' Warning dialog, define here because of a bug in Glade
Error_Msg = gtk_message_dialog_new(Main_Window, 1, 3, 2, "\nSelect an entry first!", "''")
gtk_window_set_title(Error_Msg, "Error!")
gtk_server_connect(Error_Msg, "delete-event", "Error_Msg")
' Fill grid with data
CALL Fill_Data()
' Set sort flag
Sort_Flag = 0
' Set edit or add mode - 1=ADD, 2=EDIT
Add_Edit_Mode = 1
' Mainloop starts here
REPEAT
' Get event
event = gtk_server_callback("wait")
' Add entry form
IF event = "Add_Button" THEN
Add_Edit_Mode = 1
gtk_window_set_title(Entry_Field, "Add entry")
gtk_widget_show_all(Entry_Field)
gtk_widget_grab_focus(EntryID)
END IF
' Edit entry form
IF event = "Edit_Button" THEN
Add_Edit_Mode = 2
IF gtk_tree_selection_get_selected(Tree_Sel, "NULL", List_Iter) = "0" THEN
gtk_widget_show_all(Error_Msg)
ELSE
FOR i = 0 TO 6
info[i] = gtk_tree_model_get(List_Store, List_Iter, i, "''", -1)
NEXT i
' Get the etries, currently no checking
gtk_entry_set_text(EntryID, MID(info[0], 4))
gtk_entry_set_text(EntryName, MID(info[1], 4))
gtk_entry_set_text(EntryAddress, MID(info[2], 4))
gtk_entry_set_text(EntryCity, MID(info[3], 4))
gtk_entry_set_text(EntryState, MID(info[4], 4))
gtk_entry_set_text(EntryZip, MID(info[5], 4))
gtk_entry_set_text(EntryPhone, MID(info[6], 4))
gtk_window_set_title(Entry_Field, "Edit entry")
gtk_widget_show_all(Entry_Field)
gtk_widget_grab_focus(EntryID)
END IF
END IF
' These are the buttons on the entry form
IF event = "Entry_Can_Button" OR event = "Entry_Field" THEN
gtk_widget_hide(Entry_Field)
' Delete the entries
gtk_editable_delete_text(EntryID, 0, -1)
gtk_editable_delete_text(EntryName, 0, -1)
gtk_editable_delete_text(EntryAddress, 0, -1)
gtk_editable_delete_text(EntryCity, 0, -1)
gtk_editable_delete_text(EntryState, 0, -1)
gtk_editable_delete_text(EntryZip, 0, -1)
gtk_editable_delete_text(EntryPhone, 0, -1)
END IF
IF event = "Entry_Ok_Button" THEN
CALL Add_Edit_Data()
END IF
' Warning dialog
IF event = "Del_Button" THEN
IF gtk_tree_selection_get_selected(Tree_Sel, "NULL", List_Iter) = "0" THEN
gtk_widget_show_all(Error_Msg)
ELSE
gtk_widget_show_all(Warning_Msg)
END IF
END IF
IF event = "Warning_Msg" THEN gtk_widget_hide(Warning_Msg)
IF event = "Warning_Msg_Response" THEN
response = gtk_server_callback_value(1, "INT")
IF response = -8 THEN CALL Del_Data()
gtk_widget_hide(Warning_Msg)
END IF
' Error dialog
IF event = "Error_Msg" OR event = Error_Msg THEN gtk_widget_hide(Error_Msg)
' Sortable on key
IF event = List_Column0 THEN
Sort_Flag = 1 - Sort_Flag
gtk_tree_sortable_set_sort_column_id(List_Store, 0, Sort_Flag)
END IF
UNTIL event = "Main_Window" OR event = "Exit_Button"
' Cleanup resources
gtk_server_exit()
curl::finish(ch)
gtkdbweb.sb
' Program: gtkdbweb.sb
' Version: 1.0
' Date: 2010-12-27
' By: JRS
INCLUDE cgi.bas
INCLUDE mt.bas
INCLUDE mysql.bas
CONST TAB = "\t"
CONST NL = "\n"
dbh = mysql::RealConnect("localhost","root","xxxx","sbtest")
OPTION cgi$Method cgi::GET or cgi::POST
session_id = cgi::Cookie("webcust")
New_Session:
IF session_id = undef THEN
session_id = mt::NewSessionId()
mt::SetSessionId(session_id)
ELSE
IF mt::CheckSessionId(session_id) = False THEN
session_id = undef
GOTO New_Session
END IF
mt::SetSessionId(session_id)
END IF
IF cgi::RequestMethod() = "POST" THEN GOTO Maintenance
mysql::query(dbh,"SELECT * FROM customer")
cgi::Header(200, "text/html")
cgi::SetCookie("webcust", session_id)
cgi::FinishHeader()
WHILE mysql::FetchHash(dbh, dbrow)
PRINT dbrow{"cust_id"} & TAB & dbrow{"cust_name"} & TAB & dbrow{"cust_addr"} & TAB & dbrow{"cust_city"} & TAB & dbrow{"cust_state"} & TAB & dbrow{"cust_zip"} & TAB & dbrow{"cust_phone"} & NL
WEND
mysql::Close(dbh)
END
Maintenance:
cust_id = cgi::PostParam("cust_id")
cust_name = cgi::PostParam("cust_name")
cust_addr = cgi::PostParam("cust_addr")
cust_city = cgi::PostParam("cust_city")
cust_state = cgi::PostParam("cust_state")
cust_zip = cgi::PostParam("cust_zip")
cust_phone = cgi::PostParam("cust_phone")
maint_flag = cgi::PostParam("maint_flag")
IF maint_flag = "1" THEN SQL = "INSERT INTO customer (cust_id, cust_name, cust_addr, cust_city, cust_state, cust_zip, cust_phone) VALUES ('" & cust_id & "', '" & cust_name & "', '" & cust_addr & "', '" & cust_city & "', '" & cust_state & "', '" & cust_zip & "', '" & cust_phone & "')"
IF maint_flag = "2" THEN SQL = "UPDATE customer SET cust_id = '" & cust_id & "', cust_name = '" & cust_name & "', cust_addr = '" & cust_addr & "', cust_city = '" & cust_city & "', cust_state = '" & cust_state & "', cust_zip = '" & cust_zip & "', cust_phone = '" & cust_phone & "'"
IF maint_flag = "3" THEN SQL = "DELETE FROM customer WHERE cust_id = " & cust_id
mysql::query(dbh, SQL)
cgi::Header(200, "text/html")
cgi::SetCookie("webcust", session_id)
cgi::FinishHeader()
mysql::Close(dbh)
END