Бази даних були природньо поєднані з WWW і CGI з самого початку Web. Фактично, Web є неосяжною всесвітньою базою даних, колекцією даних і ресурсів, доступних за допомогою клацання мишкою.
На вищому рівні, взаємодія з серверними базами даних є одним з найбільш природних застосувань CGI. Кінцевий користувач може представити запит через форму і мати результати, які показуються безпосередньо назад до його вікна перегляду.
Через те, що протягом транзакції з базою даних взаємодія у реальному часі звичайно не потрібна, однієї з головних перешкод CGI (відсутність постійного зв'язку) уникають одразу. Крім того, розмір бази даних майже не впливає на швидкість транзакції, тому що до клієнта посилаються тільки результати запиту. (Будь-хто, хто використовував один з пошуковиків Web, - наприклад, AltaVista або Lycos, може підтвердити це.)
Хоч будь-який вид бази даних доступний через CGI, є декілька типів баз даних, які стали дуже популярними на Павутині:
· Невеликі текстові бази даних. Вони є найлегшими для створення та корисними для багатьох малих або середніх задач. Ці бази даних є просто файлами ASCII з розмежуванням або записами фіксованої довжини. Адресні книги, списки, і такі інші бази даних з обмеженим рядом елементів добре відповідають вимогам саме цього методу.
Бази даних Web. Природніми кандидатами для баз даних Web є безпосередньо Web. Служби, які контролюють великі порції Павутини (наприклад, Usenet, Gopher, і так далі) виникають дуже часто. Це можна також застосувати до локальних мереж і єдиних машин. Індексне програмне забезпечення, подібне до freeWais або Ice може створити базу даних повного сайту, який потім буде доступний через програми CGI.
Великі серверні бази даних. Великі бази даних взагалі зберігаються в сервері деякої бази даних (навіть якщо сервер є також клієнт, як наприклад найбільш загальні базові бази даних Windows). Поки сервер має деякий інтерфейсний метод для інших програмам, інформація в цих базах даних буде доступна з програм CGI.
Практично, бази даних Web можуть бути деякою комбінацією вищевказаних. Кожна база даних має власні потреби, і програми CGI часто повинні бути налагодженими, щоб відповідати вимогам вашої конкретної бази даних.
Інтерфейси Баз даних
Для ефективного поєднання вашої бази даних з Web без будь-яких втрат, CGI повинен використовуватися як в інтерфейсі так і в реалізації взаємодії бази даних.
Інтерфейс CGI
Поперше, треба розглянути те, як користувач збирається ввести запити до бази даних. Форма HTML є найбільш загальним шляхом для користувача, щоб представити інформацію, хоч є і інші шляхи. Як приклад, розглянемо інтерфейс до адресної книги. Проста форма могла б бути схожою з цим:
<HTML><HEAD><TITLE>My Address Book</title></head> <BODY> <H2>Welcome to my address book</h2> To find addresses that match a certain category, fill in that category and then press 'submit'. <FORM ACTION="address.cgi" METHOD="POST"> Name: <INPUT SIZE=45 name="name"><br> Phone: <INPUT SIZE=45 name="phone"><br> Street Address: <INPUT SIZE=45 name="street"><BR> City: <INPUT SIZE=20 name="city"> State: <INPUT SIZE=3 name="state"> Zip: <INPUT SIZE=6 name="zip"><br> <INPUT TYPE=SUBMIT Value=" Submit Query "> <INPUT TYPE=RESET Value=" Reset Form "><br> </body></html>
Ця форма викликає CGI-скрипт address.cgi. Це є інтерфейс взаємодії з базою даних. Намір інтерфейсу - забрати дані з форми, проаналізувати їх, і передати запит до бази даних. Якщо база даних є текстовим ASCII-файлом, інтерфейс є також і реалізацією. Він повинний зробити пошук, інтерпретувати дані, і потім передати результати назад до клієнта. Для серверів баз даних (включаючи такі індекси Web,як freeWais і Ice), інтерфейс повинний надати запиту форму, яку сервер зрозуміє, і потім передати запит до сервера. CGI-програма повинна потім забрати результати і передати їх до користувача. Дуже часто в цьому випадку інтерфейси і реалізації містяться в тій же програмі. На системах, які підтримують це (UNIX, Amiga, і інші), для цього можна застосовувати розгалуження процесу. У Windows-середовищі, необхідні спеціальні програми, які використовують OLE або деякий інший тип зв'язку.
Щоб повернутися до прикладу адресної книги, можна створити в даний момент програму CGI, яка відповість запиту клієнта.
По-перше, нам потрібно знати формат бази даних безпосередньо. Малий текстовий формат є достатнім для наших потреб. Ми повинні використовувати розмежовані дані, хоч записи фіксованої довжини повинні також працювати. Запис прикладу слідує:
0:Elmer J. Fudd:555-1234:42 Jones Lane:Chuckville:CA:90210
Цей формат буде добре обізнаний до будь-кого, хто бачив файл пароля UNIX. Є дві перешкоди до цього формату. Сума всіх полів не може перевищити ніяких обмежень лінійної довжини на будь-якій системі, яку ви використовуєте (в нашому випадку, це не має бути проблемою). Також, розділювач (двокрапка) не повинний з'являтися в будь-якому полі, або це буде сприйнято як початок нового поля. У ідеальному світі, це не повинне бути проблемою (, якщо не хто-небудь, хто живе за адресою "Нью-йорк: Місто"). Але фактично, люди роблять памылки. Таким чином, треба бути ознайомленим з цією потенційною проблемою.
Тепер, коли ми знаємо форму бази даних, ми можемо почати програму CGI, щоб зібрати інформацію від форми. Будь-яка мова може використатися для написання CGI, але в цьому прикладі використано Perl для використання можливостей обробки тексту.
#!/bin/perl require cgi_head; # Дістати дані з форми та роздрукувати заголовок.
!!!!! |
У всіх CGI, написаних на Perl в цьому розділі, модуль cgi_head.pm використовується, для збору інформації від форми і надрукувати необхідний заголовок HTML. Цей модуль розміщує вхід форми з ім'ям 'foo' в асоціативний вхід з ім'ям $FORM{'foo'}. Існує декілька вільнодоступних програм для декількох мов, для виконання цього, включаючи CGI.pm для Perl : http://www.perl.com/perl/CPAN/ |
Тепер, коли дані з форми були прочитані, треба прочитати записи в базі даних безпосередньо. Через те, що ми використовуємо розмежовану базу даних, найлегше прочитати з повної бази даних. База даних поля фіксованої довжини повинна дати нам можливість просуватися через базу даних без читання інформації, але цей метод має власні перешкоди (найбільш очевидне те, що дані не повинні перевищувати незмінну довжину). Ми читаємо базу даних, як плаский ASCIІ-файл і аналізуємо це полінійно, використовуючи зручну Perl-конструкцію while(<FILEHANDLE>)<>.
!!!!! |
Цей приклад вимагав Perl 5.001 або вище, через використання звертань, які не включалися в Perl 4 (або раніше). Perl 5 містить багато покращень та нових можливостей і є необхідним для будь-якого Перломану -доступний на http://www.perl.com/perl/CPAN/<> |
# Спершу, відкрийте базу даних. (тут 'database.txt'.) open (DAT, "database.txt") || die "Can't open the database: $! !.n"; $maxn = 0; # лічильник записів. while (<DAT>) { chop; @field = split(/:/); # розбити запис на окремі поля $n = $field[0]; # Перше поле є ID номером $add[$n]{'name'} = $field[1]; # Потім ім'я $add[$n]{'phone'} = $field[2]; # тел. номер $add[$n]{'street'} = $field[3]; # адреса $add[$n]{'city'} = $field[4]; # місто $add[$n]{'state'} = $field[5]; # країна $add[$n]{'zip'} = $field[6]; # поштовий індекс } $maxn = $n # Встановлено max номер до останнього запису
Тепер, коли база даних була завантажена, нам потрібно порівняти запит користувача з даними :
@results = (); # обнулити вихідний масив. if ($name = $FORM{'name'}) { # пошук за ім'ям, for ($I = 0; $I <= $maxn; $I++) { # пройти по всіх записах if ($name eq $add[$I]{'name'}) { # шукаючи співпадань. push(@results,$I); # якщо найдено, додати номер } if (!@results) { &exitnone; } # якщо нічого не знайдено - вийти. } # Тепер для кожного критерію. Якщо є результати від попереднього # пошуку, шукати в них, і видалити будь-які невідповідні записи. if (($phone = $FORM{'phone'}) && !@results) { for ($I = 0; $I <= $maxn; $I++) { if ($phone eq $add[$I]{'phone'}) { push(@results,$I); } } if (!@results) { &exitnone; } } elsif ($phone = $FORM{'phone'}) { @r2 = @results; foreach $I (@r2) { if ($phone ne $add[$I]{'phone'}) { @results = grep(!/$I/,@results); } } if (!@results) { &exitnone; } } if (($street = $FORM{'street'}0 && !@results) { for ($I = 0; $I <= $maxn; $I++) { if ($street eq $add[$I]{'street'}) { push(@results,$I); } } if (!@results) { &exitnone; } } elsif ($street = $FORM{'street'}) { @r2 = @results; foreach $I (@r2) { if ($street ne $add[$I]{'street'}) { @results = grep(!/$I/,@results); } } if (!@results) { &exitnone; } } if (($city = $FORM{'city'}) && !@results) { for ($I = 0; $I <= $maxn; $I++) { if ($city eq $add[$I]{'city'}) { push(@results,$I); } } if (!@results) { &exitnone; } } elsif ($city = $FORM{'city'}) { @r2 = @results; foreach $I (@r2) { if ($city ne $add[$I]{'city'}) { @results = grep(!/$I/,@results); } } if (!@results) { &exitnone; } } if (($state = $FORM{'state'}) && !@results) { for ($I = 0; $I <= $maxn; $I++) { if ($state eq $add[$I]{'state'}) { push(@results,$I); } } if (!@results) { &exitnone; } } elsif ($state = $FORM{'state'}) { @r2 = @results; foreach $I (@r2) { if ($state ne $add[$I]{'state'}) { @results = grep(!/$I/,@results); } } if (!@results) { &exitnone; } } if (($zip = $FORM{'zip'}) && !@results) { for ($I = 0; $I <= $maxn; $I++) { if ($zip eq $add[$I]{'zip'}) { push(@results,$I); } } if (!@results) { &exitnone; } } elsif ($zip = $FORM{'zip'}) { @r2 = @results; foreach $I (@r2) { if ($zip ne $add[$I]{'zip'}) { @results = grep(!/$I/,@results); } } if (!@results) { &exitnone; } }
У цей момент, або ми маємо успішні співпадання, які зберігаються в масиві @results, або ми не маємо співпаданнь, і в цьому випадку ми викликаємо підпрограму &exitnone. Тепер ми можемо видати клієнту результати (або їх відсутність).
# якщо немає результатівБ видати повідомлення та вийти. sub exitnone { print <<EOE; <HTML><HEAD><TITLE>No matches</title></head> <BODY> <h3>There were no matches that fit your criteria.</h3> <A HREF="addrbk.html">Go</a> back to the form to try again. </body></html> EOE die; } # роздрукувати результати. print <<EOP; <HTML><HEAD><TITLE>Search Results</title></head> <BODY> <h3>The entries that matched your search</h3> <pre> EOP foreach $r (@results) { print <<EOG; ---- Name: $add[$r]{'name'} Phone: $add[$r]{'phone'} Address: $add[$r]{'street'} $add[$r]{'city'}, $add[$r]{'state'} $add[$r]{'zip'} EOG } print <<EOH; </pre><br> Thank you for using my address book. <A HREF="addrbk.html">Go</a> back to the form to make another search. </body></html> EOH
Тепер ми маємо робочий інтерфейс до адресної книги. Є декілька оптимізацій, які могли б бути зроблені, але це помітно лише для декількох дюжин записів. Зверніть увагу, що цей скрипт робить тільки логічний пошук AND на всіх полях. Можливо зробити OR-пошук - через знищення всіх викликів до &exitnone, крім останнього. Таким чином, коли програма не знаходить ніяких співпадань, вона не скінчиться, а перейде до наступного поля. Можна, також дати кінцевому користувачеві можливість вибрати, чи зробити пошук AND або OR за допомогою додавання спадного меню до сторінки форми. Тоді CGI міг би вийти або ні залежно від вибору.
Тепер, коли користувач може шукати у вашій БД за будь-яким критерієм, наступним логічним питанням є те, як додати або перемістити інформацію до бази даних. Ви могли, звичайно, б зробити це вручну, але було б добре дозволити пряме маніпулювання базою даних з Web безпосередньо. Приємно, що це не важко.
У маніпулюванні базою даних безпосередньо різниця між розмежованою і базою даних з записами фіксованої довжини стає важливою. З розмежованим текстом, ви не маєте легкого шляху для визначення місця, де один запис закінчується та інший починається. Таким чином, щоб змінити або викреслити один запис, необхідно переписати всю базу даних. Так в малих базах даних, це не є дійсно великою проблемою, але якщо ваша база даних є великою достатньо, для того, щоб це стало проблемою, можливо буде хорошою ідеєю проглянути використання сервера бази даних.
З базами даних з незмінної довжиною поля, однак, не необхідно переписати повну базу даних, щоб змінити запис. Через те, що довжина кожного запису відома, функції подібні до seek() і tell() (або їхній еквівалент у вашій улюбленій мові) можуть використатися, щоб переписати лише шматок файлу, змінюючи або вилучаючи дані.
Як і з інтерфейсом до пошукового CGI, проста HTML-форма - це все що вимагається, щоб дати споживачам можливість безпосередньо змінити вашу базу даних. Тут знову є приклад адресної книги:
<HTML><HEAD><TITLE>My Address Book</title></head> <BODY> <h4>Fill out the form below to add an entry to the address book</h4> <FORM ACTION="add.cgi" METHOD="POST"> Name: <INPUT SIZE=45 NAME="name"><br> Phone: <INPUT SIZE=45 NAME="phone"><br> Street: <INPUT SIZE=45 NAME="street"><br> City: <INPUT SIZE=20 NAME="city"> State: <INPUT SIZE=3 NAME="state"> Zip: <INPUT SIZE=6 NAME="zip"> <br><br> <INPUT TYPE=SUBMIT VALUE=" Add Entry "> <INPUT TYPE=RESET VALUE=" Reset Form "> </form></body></html>
Ця форма майже однакова до той, яку було виготовлено для пошуку. Різниця в тому, як дані обслуговуються програмою CGI. У цьому випадку, скрипт CGI для додавання запису є набагато простішим, ніж пошуковий скрипт. У цьому випадку, ми допускатимемо, що база даних є файл з дозволом запису.
#!/bin/perl require cgi_head; # Ініціалізація CGI-оточення while (-e "datalock") { sleep 1; } # зачекати, доки звільниться БД system("touch datalock"); # Зачинити БД open (DAT, "database.txt"); # Відкрити БД для запису while (<DAT>) { $line = $_; } # зчитати останній рядок close DAT; if ($line =~ /:/) { @field = split (/:/, $line); $num = $field[0]; # Знайти останній ID номер $num++; } else { $num = 0; } # Створити новий ID open (DAT, ">>database.txt"); # Відкрити БД для додавання # Додати запис до БД print DAT "$num:$FORM{'name'}:$FORM{'phone'}:$FORM{'street'}:$FORM{'city'}:$FORM{'state'}: В$FORM{'zip'}n"; close DAT; system ("rm datalock"); print <<EOF; <HTML><HEAD><TITLE>Addition Successful</title></head> <BODY> <h4>Your entry has been added to the address book</h4> <A HREF="add.html">Go</a> back to the form to add another user. </body></html> EOF
Насправді, цей скрипт CGI просто приєднує новий запис до бази даних. Якщо хтось інший змінює базу даних в той же час, одна із змін буде втрачена або повна база даних стане зіпсованою. Щоб обійти це, ми використовуємо lock-файл, щоб сказати, чи хтось інший пише до бази даних. Це далеко не найелегантніше вирішення, і більшість систем забезпечують функцію flock(), щоб більш ефективно замкнути файл від паралельної вибірки. По-друге, номер ID запису повинен бути визначений. У цьому випадку, ми можемо допускати, що записи будуть послідовно нумеровані і, що останній вхід матиме останній номер ID. Так що ми просто читаємо останню лінію бази даних, захоплюємо номер ID від нього, і потім прирощуємо його, щоб одержати новий номер ID.
Тепер, коли будь-хто може додати записи до адресної книги, може стати необхідним, викреслити або змінити записи. Щоб зробити, це, однак, має бути деякий спосіб для користувача, щоб вказати на бажаний вхід який треба змінити або викреслити. Замість створення всієї нової форми для цього, ми можемо додати ці функціональні можливості до нашого існуючого CGІ-пошуку. Якщо пошук користувача повертає точно один результат, лінія може бути додана до сторінки результату HTML, яка пропонує на вибір змінити або викреслити цей вхід. (Це могло б бути зроблене для більш ніж одного результату досить легко, але ми працюємо з одним заради стислості). Це може бути зроблено за допомогою зміни наступних ліній в дні пошуку CGI:
print <<EOH; </pre><br> Thank you for using my address book. <A HREF="addrbk.html">Go</a> back to the form to make a
на:
print "</pre><br>nThank you for using my address book.n"; print "<A HREF="addrbk.html">Go</a> back to the form to make another search.<br>n"; if ($#results == 0) { print "<A HREF="change.cgi?a=d&n=$result[0]">Delete</a> this entry.<br>n"; print "<A HREF="change.cgi?a=c&n=$result[0]">Modify</a> this entry.<br>n"; } print "</body></html>n";
Додаткові лінії друкують зв'язки з новою програмою CGI, передаючи два значення: вказання параметра - викреслювання або модифікація потрібна, і номер ID запису, щоб викреслити або змінити.
Через те, що наша база даних розмежена, нам буде необхідно відродити повну базу даних, щоб зробити зміну, як показано:
#!/bin/perl require cgi_head; # Ініціалізація CGI-оточення while ( -e "datalock" ) { sleep 1; } # зачекати, доки не звільниться БД system ("touch datalock"); # Замкнути БД. # Завантажити БД open (DAT, "database.txt") || die "Can't open the database: $! !.n"; $maxn = 0; # Лічильик записів. while (<DAT>) { chop; @field = split(/:/); # розбити запис на поля. $n = $field[0]; # перше поле є ID $add[$n]{'name'} = $field[1]; # ім'я $add[$n]{'phone'} = $field[2]; # телефон $add[$n]{'street'} = $field[3]; # адреса $add[$n]{'city'} = $field[4]; # місто $add[$n]{'state'} = $field[5]; # країна $add[$n]{'zip'} = $field[6]; # поштовий індекс $add[$n]{'line'} = $_ . "n"; # весь рядок } $maxn = $n; close DAT; open (DAT, ">database.txt"); # відкрити БД для запису. if ($FORM{'a'} eq "d") { # Якщо треба знищити запис, for ($I = 0; $I <= $maxn; $I++) { #видати всі записи, unless ($I == $FORM{'n'}) { # крім того, який треба зтерти. print DAT $add[$I]{'line'}; } } # видати повідомлення та вийти. print <<EOP; <HTML><HEAD><TITLE>Request successful</title></head> <BODY> <H3>The selected entry has been deleted.</h3> <A HREF="addrbk.html">Go</a> back to make another search. </body></html> EOP close DAT; system ("rm datalock"); die; } elsif ($FORM{'a'} eq "c") { # Якщо користувач хоче змінити вхід, все стає трохи хитрішим. Ми повинні спершу надрукувати зовні форму, подібні до первинної форми, щоб дозволити користувачеві змінити значення запису.
# змінна. print <<EOF; <HTML><HEAD><TITLE>Entry Modification</title></head> <BODY> <h4>Make the desired changes in the form below.</h4> <FORM ACTION="change.cgi" METHOD="POST"> <INPUT TYPE=HIDDEN NAME="a" VALUE="m"> <INPUT TYPE=HIDDEN NAME="n" VALUE="$n"> Name: <INPUT SIZE=45 NAME="name" VALUE="$add[$n]{'name'}"><br> Phone: <INPUT SIZE=45 NAME="phone" VALUE="$add[$n]{'phone'}"><br> Street: <INPUT SIZE=45 NAME="street" VALUE="$add[$n]{'street'}"><br> City: <INPUT SIZE=20 NAME="city" VALUE="$add[$n]{'city'}"> State: <INPUT SIZE=3 NAME="state" VALUE="$add[$n]{'state'}"> Zip: <INPUT SIZE=6 NAME="zip" VALUE="$add[$n]{'zip'}"> <br><br> <INPUT TYPE=SUBMIT VALUE=" Modify Entry "> <INPUT TYPE=RESET VALUE=" Reset Form "> </form></body></html> EOF # Ця форма додає два приховані поля, говорячи CGI, який вхід треба #змінити. for ($I = 0; $I <= $maxn; $I++) { print DAT $add[$I]{'line'}; } close DAT; system ("rm datalock"); die; } elsif ($FORM{'a'} = "m") { # внести зміни до необхідного запису $n = $FORM{'n'}; # Скопіюавти запис до змінної. # Внести зміни. $add[$n]{'name'} = $FORM{'name'}; $add[$n]{'phone'} = $FORM{'phone'}; $add[$n]{'street'} = $FORM{'street'}; $add[$n]{'city'} = $FORM{'city'}; $add[$n]{'state'} = $FORM{'state'}; $add[$n]{'zip'} = $FORM{'zip'}; $add[$n]{'line'} = "$n:$add[$n]{'name'}:$add[$n]{'phone'}:$add[$n]{'street'}:$add[$n]{'city'}:$add[$n]{'state'}: В$add[$n]{'zip'}n"; for ($I = 0; $I <= $maxn; $i++) { print DAT $add[$i]{'line'}; } close DAT; print <<EOE; <HTML><HEAD><TITLE>Modification successful</title></head> <BODY> <H4>The requested entry has been modified.</H4> <A HREF="addrbk.html">Go</a> back to the form to make another search. </body><//html> EOE system ("rm datalock"); die; } else { die; } # This should never be reached.
Звертання до SQL
Ми можемо використовувати ті ж сторінки форми HTML, які ми використовували, наприклад, для текстової бази даних. Перша форма розшукала існуючу базу даних. Показана відповідна програма CGI.
Пошук у базі даних SQL.
#!/bin/perl require cgi_read; use Msql; # завантажити модуль SQL $dbh = Connect Msql; #під'єднатися до серверу mSQL SelectDB $dbh "addresses"; # вибрано БД "addresses $all = "name, phone, street, city, state, zip"; # всі поля адреси $query = ""; # Встановити змінну для запиту. foreach (keys %FORM) { # зібрати всі умови в один рядок $query =. " $_ = $FORM{'$_'} AND"; } $query =~ s/AND$//; $sth = Query $dbh "SELECT $all FROM addresses WHERE $query"; # Відправити запит print "<HTML><HEAD><TITLE>Search Results</title></head><BODY>n"; $I = 0; # немає співпадань. while (@arr = FetchRow $sth) { if ($I == 0) { $I = 1; } # 1 співпадання if ($I == 1) { print "<H4>Your search results are listed below</h4>"; print "<PRE>n"; }; $I++; print <<EOF; -- -- Name: $arr[0] Phone: $arr[1] Street: $arr[2] City: $arr[3] State: $arr[4] Zip: $arr[5] EOF } if ($I == 2) { print "</pre><br>"; print "<A HREF="addrbk.html">Go</a> back to the form to make another Вsearch.<br>n"; print "</body></html>n"; } elsif ($I == 0) { print <<EOE; <HTML><HEAD><TITLE>Search Failed!</title></head><BODY> <h4>There are no entries which match your criteria</h4> <A HREF="addrbk.html">Go</a> back to the form to make another search. </body></html> EOE }
Фактично CGI-код в цьому випадку є в чотири рази менший за рівноцінний у першому прикладі. Крім того, дуже легко додати відповідність підрядку до запитання mSQL. Також помітьте відсутність номерів ID - mSQL є реляційною базою даних прямого доступу. Тобто не потрібно читати всі записи, щоб мати доступ до будь-яких з них.
Дійсна потужність сервера бази даних стає очевидною при безпосередній зміні бази даних.
!!!!! |
Через те, що модифікація бази даних робиться сервером безпосередньо, результати дозволу файла текстових баз даних тут не застосовуються. Замість цього, найбільші сервери баз даних мають власні схеми прав доступу, які можуть бути використатиними, для дозволу доступу тільки для певних користувачей мати до конкретних баз даних. |
Тепер ми розглядаємо CGI, який додає записи до бази даних. Ще раз - ми набуваємо викликані з бази даних замість табличних.
#!/bin/perl require cgi_head; use Msql; $dbh = Connect Msql; # під'єднатися до серверу mSQL SelectDB $dbh "addresses" # Query $dbh "INSERT INTO addresses ( name, phone, street, city, state, zip ) VALUES В('$FORM{'name'}, $FORM{'phone'}, $FORM{'street'}, $FORM{'city'}, $FORM{'zip'} )"; print <<EOF; <HTML><HEAD><TITLE>Addition successful</title><head><BODY> Your entry has been added to the address book. <A HREF="add.html">Go</a> back to the form to add another entry. </body></html> EOF
У випадку пласкої текстової версії, виробляється набагато гнучкіша схема доповнення. Звичайно, найбільша проблема у використанні сервера бази даних - знайти його. Є багато ситуацій, в яких ви не можете мати доступу до нього. Також, якщо текстова база даних стає недостовірною, ви завантажуєте її у ваш улюблений текстовий редактор і виправляєте її. Якщо ваша реляційній база даних стає недостовірною, та ви - не експерт з баз даних, вам краще взяти останні резервні копії.
Тепер, нарешті, вилучення і модифікація записів у базі даних. Подібно текстовій базі даних, зміна повинна бути внесена до форми HTML, яка генерується програмою пошуку. На відміну від текстової бази даних, ми не маємо унікального номера ID, щоб розпізнавати вхід. Таким чином, ми повинні вибрати інший унікальний атрибут, щоб розпізнати вхід. Ми могли б додати номер ID в базу даних, але заради простоти, ми використовуватимемо ім'я, як унікальне поле. (І, якщо ви знаєте два людей з точно тими ж першими, останніми, і середніми іменами, ви знаєте дуже багато людей.)
Програма CGI пошуку
print "</pre><br>"; print "<A HREF="addrbk.html">Go</a> back to the form to make another search.<br>n"; print "</body></html>n";
стає такою :
print "</pre><br>"; print "<A HREF="addrbk.html">Go</a> back to the form to make another search.<br>n"; if ($I == 1) { print "<A HREF="change.cgi?a=d&name=$arr[0]">Delete</a> this entry.<br>"; print "<A HREF="change.cgi?a=c&name=$arr[0]">Modify</a> this entry.<br>"; } print "</body></html>n";
безпосереднє спрощення CGI:
#!/bin/perl require cgi_head; use Msql; $dbh = Connect Msql; SelectDB $dbh "addresses"; $all = "name, phone, street, city, state, zip"; if ($FORM{'a'} eq "d") { Query $dbh "DELETE FROM addresses WHERE name=$FORM{'name'}"; print <<EOF; <HTML><HEAD><TITLE>Deletion successful</title></head><BODY> <h3>Your entry has been deleted</h3> <A HREF="addrbk.html">Go</a> back to the form to make another search. </body></html> EOF die; } elsif ($FORM{'a'} eq "c") { $guy = Query $dbh "SELECT $all FROM addresses WHERE name=$FORM{'name'}"; @guy = FetchRow $guy; print <<EOE; <HTML><HEAD><TITLE>Modify Me</title></head><BODY> <h4>Modify your entry in the form below</h4> <FORM ACTION="change.cgi" METHOD="POST"> <INPUT TYPE=HIDDEN NAME="a" VALUE="m"> Name: <INPUT SIZE=45 NAME="name" VALUE="$guy[0]"><br> Phone: <INPUT SIZE=45 NAME="phone" VALUE="$guy[1]"><br> Street: <INPUT SIZE=45 NAME="street" VALUE="$guy[2]"><br> City: <INPUT SIZE=20 NAME="city" VALUE="$guy[3]"> State: <INPUT SIZE=3 NAME="state" VALUE="$guy[4]"> Zip: <INPUT SIZE=6 NAME="zip" VALUE="$guy[5]"> <br><INPUT TYPE=SUBMIT VALUE=" Modify Entry "> <INPUT TYPE=RESET VALUE=" Reset Form "> </form></body></html> EOE die; } elsif ($FORM{'a'} eq "m") { foreach (keys %FORM) { # забрати дані з форми $query =. " $_ = $FORM{'$_'},; # по одній лінії. } $query =~ s/,$//; # Get rid of that annoying trailing ',' Query $dbh "UPDATE addresses SET $query WHERE name=$FORM{'name'}"; print <<EOF; <HTML><HEAD><TITLE>Modification successful</title></head><BODY> <h3>Your entry has been modified</h3> <A HREF="addrbk.html">Go</a> back to the form to make another search. </body></html> EOF die; # Th' th' that's all folks }
Це так просто, як і у попередньому випадку. П'ятдесят стрічок Perl проти понад однієї сотні. Справжня гнучкість сервера бази даних відкриває двері до різноманітних можливостей.
Висновок
Світ взаємодії бази даних з Web є такий же широким як і зовнішній світ. Для будь-якої проблеми, є дюжини розв'язків, чимсь кращих за інші. Це зводиться до особистої переваги і досвіду. Для особи з навичкою обробки даних в Windows, можливо, буде найлегше використовувати Windows-базу даних як наприклад Paradox або Access разом з одним з готових інтерфейсів CGI для них. Програміст C може віддати перевагу грі з одним з APIs, передбаченого для різних серверів SQL як наприклад Sybase, Oracle, SQL Server, і mSQL. Хто-небудь, який є "тільки іншим Perl-хакер" повинний почувати себе найбільш зручно з одним з багатьох інтерфейсів Perl до серверу бази даних SQL і ODBM (або, можливо, вони повинні тільки написати одного з них для себе).
Всередині цього королівства великої гнучкості, ефективність взаємодії бази даних з Web залежить від багатьох речей:
· Які інструментальні засоби доступні?
Чи є ви адміністратором системи UNIX, підсиленої потужним сервером? Або, можливо, ваш Internet-зв'язок є тільки PPP-з'єднанням з Windows-машиною. Якщо ви використовуєте Windows-платформу, не варто воювати з погано написаними мовами програмування, коли є величезна бібліотека вже доступних інструментальних засобів. Якщо UNIX є вашою опорою, ви можете подумати перед вибиттям артилерійським вогнем декількох тисяч доларів для серверів Sybase або Oracle, коли є безкоштовні інструментальні засоби, як, наприклад, легко доступні mSQL і POSTGRES. (Але з другого боку знову, можливо ваші потреби такі, що лише тільки high-end-сервер баз даних буде достатнім.) Варто бути обізнаним що є для вас доступним.
Який розмір вашого проекту?
Розмір має велике значення. Як ми бачили, пласкі текстові базові бази даних просто не звертають уваги на розмір. 50 MB версія нашої фонової книги могла б поставити навіть найбільш могутній RISC-сервер на коліна. У той же час, треба багато часу, щоб створити БД, яка використовує сервер. Вам потрібно мати дозвіл, і поперед усе, вам потрібно мати доступ до сервера. Якщо ви є студент з університетським account'ом, є шанс, що текст - це все, з чим необхідно мати справу. Навіть сервери баз даних звертають увагу на розмір і складність вашого проекту - зберігання бази даних всіх телефонних номерів в Америці могло б бути заведикою роботою навіть для окремої бази даних, подібної Access або Paradox. З іншого боку, база даних з таблицями, які з'єднуються з таблицями непрямими та переплутанитими шляхами є просто неможлива у вільнодоступних серверах, подібних до mSQL. (POSTGRES має більші функціональні можливості, за рахунок швидкості, складності, і відсутності стандартного інтерфейсу SQL) Перш ніж писати проект, спробуйте передбачити максимальний розмір і план відповідно.
Програмувати або ні?
Зі значним списком ресурсів, показаних раніше в розділі, чому будь-хто має писати власні CGI взагалі? Можливо ви не будете робити цього. кщо ви маєте зайві гроші, є шанс, що що-небудь відповідатиме вашим вимогам. Навіть якщо ви не багатій, ви можливо знайдете щось схоже. Але цього не завжди достатньо. Невеличкого знання того, як CGI спілкуються з базами даних, може вистачити надовго.
Є там альтернатива до CGI?
Павутина є велике місце,вона зростає кожного дня, і CGI є не єдиною грою. Не потрапте до пастки ігнорування нових технологій тільки через те, що вони нові. (У той же час, не будьте сліпим до їхніх дефектів. Кожна нова мова або протокол повинні пройти через період випробування. Протягом цього часу, використання програм, написаних на новій мовй або з новими протоколами, потенційно викликають пошкодження - або безпосередньо, або за допомогою через діри безпеки). Декілька компаній розвинули первинні Web-сервери, які специфічно розробляються з інтерфейсом до баз даних. Наприклад, NeXT Inc.'s WebObjects (http://www.next.com) є новим об'єктно-орієнтованим Web-сервером, який безпосередньо взаємодіє з могутньою внутрішньою базою даних. На додаток до них є Java та величезний галас коло неї на першому році життя в Internet. Java має здатність відкрити прямі зв'язки між сервером і клієнтом, надаючи засоби для коректування бази даних безперервно. Наприклад, використання Java з базою даних наявних цін могло б забезпечити змінюючийся маятник на екрані користувача. Однак , стережіться: Java є типовою "новою технологією" з всім добром і злом, що приходить разом.
Використання CGI для інтеграції баз даних з Web природньо випливає з можливостей CGI. Не звертаючи уваги на недоліки CGI, взаємодія баз даних, можливо, одна з єдиних областей, в яких CGI збережеться як найкращий інструментальний засіб перед обличчям нових технологій.