📄 sqlitetablelist.mht
字号:
From: =?gb2312?B?08kgV2luZG93cyBJbnRlcm5ldCBFeHBsb3JlciA3ILGjtOY=?=
Subject: SQLiteTablelist
Date: Wed, 16 Apr 2008 23:12:20 +0800
MIME-Version: 1.0
Content-Type: multipart/related;
type="text/html";
boundary="----=_NextPart_000_001A_01C8A017.528B4510"
X-MimeOLE: Produced By Microsoft MimeOLE V6.0.6000.16545
这是 MIME 格式的多方邮件。
------=_NextPart_000_001A_01C8A017.528B4510
Content-Type: text/html;
charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://wiki.tcl.tk/15631
=EF=BB=BF<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" =
"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<HTML lang=3Den><HEAD><TITLE>SQLiteTablelist</TITLE>
<META http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">
<STYLE type=3Dtext/css media=3Dall>@import url( /wikit.css );
</STYLE>
<LINK title=3DRSS href=3D"/rss.xml" type=3Dapplication/rss+xml =
rel=3Dalternate><!--[if lte IE 6]>=0A=
<style type=3D'text/css' media=3D'all'>@import 'ie6.css';</style>=0A=
<![endif]--><!--[if gte IE 7]>
<STYLE type=3Dtext/css media=3Dall>@import url( ie7.css );
</STYLE>
<![endif]-->
<SCRIPT type=3Dtext/javascript>=0A=
function init() {=0A=
// quit if this function has already been called=0A=
if (arguments.callee.done) return;=0A=
=0A=
// flag this function so we don't do the same thing twice=0A=
arguments.callee.done =3D true;=0A=
=0A=
try {=0A=
checkTOC();=0A=
} catch (err) {=0A=
/* nothing */=0A=
}=0A=
};=0A=
=0A=
/* for Mozilla */=0A=
if (document.addEventListener) {=0A=
document.addEventListener("DOMContentLoaded", init, false);=0A=
}=0A=
=0A=
/* for Internet Explorer */=0A=
/*@cc_on @*/=0A=
/*@if (@_win32)=0A=
document.write("<script defer src=3Die_onload.js><\/script>");=0A=
/*@end @*/=0A=
=0A=
/* for other browsers */=0A=
window.onload =3D init;=0A=
</SCRIPT>
<META content=3D"MSHTML 6.00.6000.16643" name=3DGENERATOR></HEAD>
<BODY>
<DIV class=3Dcontainer>
<DIV class=3Dheader>
<DIV class=3Dlogo><A class=3Dlogo =
href=3D"http://wiki.tcl.tk/">wiki.tcl.tk</A> </DIV>
<DIV class=3Dtitle id=3Dtitle><A title=3D"click to see 2 references to =
this page"=20
href=3D"http://wiki.tcl.tk/_ref/15631">SQLiteTablelist</A></DIV>
<DIV class=3Dupdated id=3Dupdated>Updated 2007-09-06 16:29:25 by LV <A =
class=3Ddelta=20
href=3D"http://wiki.tcl.tk/_diff/15631#diff0">=E2=96=B2</A></DIV></DIV>
<DIV id=3Dwrapper>
<DIV id=3Dcontent>
<HR>
<P><IMG alt=3D"" =
src=3D"http://tkfp.sourceforge.net/SqliteTablelist.jpg"></P>
<HR>
<P>By <A href=3D"http://wiki.tcl.tk/2825">Alex Caldwell</A>.</P>
<P>This is a designer/viewer and editor for <A=20
href=3D"http://wiki.tcl.tk/2633">SQLite</A>3 databases. It uses the <A=20
href=3D"http://wiki.tcl.tk/5527">Tablelist</A> widget as the =
viewer/editor. It=20
allows both viewing and editing data in SQLite tables. It allows =
viewing, but=20
not editing SQLite views, since views are not editable in SQLite. =
Changes to the=20
data in the cells in a table are updated in the database automatically. =
You can=20
enter simple <A href=3D"http://wiki.tcl.tk/2097">SQL</A> queries and get =
the=20
results back in a <A href=3D"http://wiki.tcl.tk/477">Tk</A> text widget, =
a=20
Tablelist or both side by side. It was part of a medical project for =
setting up=20
a database of contacts with a mail merge set up. But I thought it would =
be=20
potentially useful as a generalizable tool for working with <A=20
href=3D"http://wiki.tcl.tk/2633">SQLite</A> databases from <A=20
href=3D"http://wiki.tcl.tk/445">Tcl</A>. I'm still working on it, so =
there are a=20
lot of random comments, puts statements and commented out junk that =
didn't work=20
in the code I posted. Sorry about that. In addition to the TclSqlite3 =
[<A=20
href=3D"http://www.tcl.tk/community/tcl2004/Papers/D.RichardHipp/drh.html=
"=20
rel=3Dnofollow>1</A>] [<A href=3D"http://www.sqlite.org/download.html"=20
rel=3Dnofollow>2</A>] extension and the Tablelist extension, it uses an =
<A=20
href=3D"http://wiki.tcl.tk/2081">Iwidgets</A> <A=20
href=3D"http://wiki.tcl.tk/1959">combobox</A> and an an Iwidgets <A=20
href=3D"http://wiki.tcl.tk/2248">paned window</A>, so it also requires =
the=20
Iwidgets extension of <A href=3D"http://wiki.tcl.tk/3087">IncrTcl</A>. =
Thanks to=20
the combobox's built in methods, it can store the SQL queries you type =
in, both=20
during and between sessions, so you can select them from a drop down =
list. If=20
you have a table named "SpokanePhysicians" that has fields named =
FirstName,=20
LastName and Address, you can try the simple "mail merge" demo feature =
by=20
selecting multiple rows and clicking on the "Fax" button. Or, edit the =
code to=20
use a different table name for your mail merging. It's only a demo of =
how the=20
idea would work, and does not actually link to any email or fax merging=20
program.</P>
<HR>
<P><B>CAUTION!!! NOT FOR PRODUCTION USE!!!</B></P>
<P>See discussion below regarding various possible problems. It works =
for our=20
simple database, but may cause problems with other more complex schema =
we have=20
not considered. Do <B>NOT</B> attempt to open an important database and =
try to=20
edit data without backup copies of your data, or it might irreversibly =
<B>DAMAGE=20
YOUR DATABASE!</B> It is a preliminary, and I felt potentially useful =
tool, but=20
has not been thoroughly tested, i.e. <B>I just barely got it working at =
all=20
yesterday!</B> I was hoping to get expert Tcler help for improving it =
and fixing=20
problems. But I was so excited that it was working, I couldn't resist =
posting it=20
on the Wiki. It has a lot of redundant code that needs to be broken out =
and put=20
in procs for reuse and efficiency. Also, why do I always seem to be =
needing to=20
use all those commands built up with a bunch of backquotes? I know there =
must be=20
a better way to do that. Also why can't I summarize a question or answer =
about=20
Tcl in just a few cryptic lines like others on the Tcler's Wiki? Why do =
I need=20
these run-on sentences? Is that why my code is so bloated and hard to=20
understand? Why? Why? Why?</P>
<HR>
<P>I have a "network" version of this program that connects to a Tcl =
server=20
using the Tcl <A href=3D"http://wiki.tcl.tk/1114">socket</A> library, so =
you can=20
connect to your SQLite database remotely. The Tablelist widget is a =
natural fit=20
with the network version, since it uses the Tcl <A=20
href=3D"http://wiki.tcl.tk/440">list</A> data structure, which is easy =
to send=20
over a socket. The <A href=3D"http://wiki.tcl.tk/1877">Tktable</A> =
widget uses the=20
Tcl <A href=3D"http://wiki.tcl.tk/1032">array</A> data structure, which =
has to be=20
"serialized" before it can be sent over the socket and then reassembled =
into=20
arrays on the other end. My network version has no encryption or =
authentication,=20
so it is not secure. But if you want that version, send me an email. It =
requires=20
another program that functions as the server that I did not post =
here.</P>
<HR>
<PRE> # by Alex Caldwell M.D
# alcald2000@yahoo.com
# with much help from
# Dr. Jerry Park D.O.
# park.jerry@gmail.com
package require Tk
package require Tablelist
package require Iwidgets
package require sqlite3
#create some bitmaps for the fax and mail merge buttons
#bitmaps were borrowed from addressbook-0.7 a Tcl/Tk program by Klemens =
Durka
image create bitmap fax -data {
#define fax_width 31
#define fax_height 21
static unsigned char fax_bits[] =3D {
0xf0, 0xff, 0xff, 0x1f, 0x18, 0x00, 0x00, 0x10, 0x08, 0x00, =
0x00, 0x18,
0xe8, 0x39, 0x21, 0x0b, 0x28, 0x44, 0x12, 0x0b, 0x28, 0x44, =
0x0c, 0x0b,
0xe8, 0x7c, 0x0c, 0x0b, 0x2e, 0x44, 0x12, 0x38, 0x2a, 0x44, =
0x21, 0x2b,
0x0a, 0x00, 0x00, 0x28, 0x0a, 0x00, 0x00, 0x28, 0xfa, 0xff, =
0xff, 0x2f,
0x02, 0x00, 0x00, 0x20, 0xfa, 0xff, 0xff, 0x27, 0x0a, 0x30, =
0xf2, 0x24,
0xfa, 0xff, 0xff, 0x2f, 0x02, 0x30, 0x92, 0x2c, 0x02, 0xf0, =
0xff, 0x2f,
0x02, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x20, 0xfe, 0xff, =
0xff, 0x3f};
}
image create bitmap mail -data {
#define brief_width 31
#define brief_height 21
static unsigned char brief_bits[] =3D {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, =
0xff, 0x3f,
0x02, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x20, 0x3a, 0x00, =
0x00, 0x27,
0x02, 0x00, 0x00, 0x25, 0xba, 0x01, 0x00, 0x25, 0x02, 0x00, =
0x00, 0x27,
0x02, 0x00, 0x00, 0x20, 0x02, 0xfc, 0x07, 0x20, 0x02, 0x00, =
0x00, 0x20,
0x02, 0x7c, 0x00, 0x20, 0x02, 0x00, 0x00, 0x20, 0x02, 0xfc, =
0x79, 0x20,
0x02, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x20, 0x02, 0x00, =
0x00, 0x20,
0xfe, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, =
0x00, 0x00};
}
image create bitmap email -data {
#define email_width 31
#define email_height 21
static unsigned char email_bits[] =3D {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, =
0xff, 0x3f,
0x02, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x20, 0x02, 0x00, =
0x00, 0x24,
0x02, 0x00, 0x40, 0x24, 0x02, 0x00, 0x00, 0x24, 0x72, 0x2a, =
0x43, 0x24,
0x8a, 0xbe, 0x44, 0x24, 0x7a, 0xaa, 0x44, 0x24, 0x0a, 0xaa, =
0x44, 0x24,
0x72, 0x2a, 0xeb, 0x2e, 0x02, 0x00, 0x00, 0x20, 0x02, 0x00, =
0x00, 0x20,
0x02, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x20, 0x02, 0x00, =
0x00, 0x20,
0xfe, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, =
0x00, 0x00};
}
set types {
{{SQLite} {.db}}
{{SQLiteExplorer} {.db3}}
{{All Files} {*.*}}
}
sqlite3 db [set database_name [tk_getOpenFile -initialdir "./" -title =
\
"Choose Sqlite Database File" -filetypes $types]]
wm title . "[file tail $database_name] - Tables"
#Eval_Remote $sock {sqlite3 db ./medrolodex.db}
# get the names of all the tables
set table_names [db eval {SELECT name FROM sqlite_master WHERE =
type=3D'table' UNION ALL SELECT name FROM sqlite_temp_master WHERE =
type=3D'table' ORDER BY name;}]
# check the no. of tables - used later to configure views in a green =
foreground color
set no_tables [llength $table_names]
append table_names " [db eval {SELECT name FROM sqlite_master WHERE =
type=3D'view' UNION ALL SELECT name FROM sqlite_temp_master WHERE =
type=3D'view' ORDER BY name;}]"
# create a button for each table which when clicked will create a =
tablelist widget and populate it with data from the table
#foreach table $table_names {
# button ._$table -text $table -command "createtablelist $table"
# pack ._$table -side left
#}
# try a listbox instead to see what works best
frame .topframe
pack .topframe -expand true -fill both
frame .topframe.leftframe
frame .topframe.rightframe
pack .topframe.leftframe -side left -expand true -fill both
pack .topframe.rightframe -side right -expand true -fill y
listbox .topframe.leftframe.list -width 115 -yscrollcommand =
{.topframe.rightframe.scroll set}
pack .topframe.leftframe.list -expand true -fill both
scrollbar .topframe.rightframe.scroll -command =
{.topframe.leftframe.list yview}
pack .topframe.rightframe.scroll -expand true -fill y
foreach table $table_names {
.topframe.leftframe.list insert end $table
}
# configure the foreground color of the views in green to distinguish =
from tables in black
for {set x $no_tables} {$x < [.topframe.leftframe.list index end]} =
{incr x} {
.topframe.leftframe.list itemconfigure $x -foreground green
}
bind .topframe.leftframe.list <Double-Button-1> {
#createtablelist [selection get]
foreach i [selection get] {createtablelist $i}
}
set report_type text
frame .bottomframe
pack .bottomframe -side top -expand true -fill x
button .bottomframe.button1 -text "New Table" -command newTable
pack .bottomframe.button1 -side left -padx 2 -pady 4
button .bottomframe.button2 -text "Delete Selected Table" -command {
dropTable [selection get]
}
pack .bottomframe.button2 -side left -padx 2 -pady 4
frame .sqlframe
pack .sqlframe -side top -expand true -fill x
#label .sqlframe.label -text "SQL Query"
#pack .sqlframe.label -side left
#entry .sqlframe.entry -width 80 -textvariable sqlquery
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -