wtorek, czerwca 26, 2007

15.11.2006
  • Firma TrendMicro - udostępnia również jak i inne firmy skanner online. Jego instalacja odbywa się poprzez technologię ActiveX (zresztą tak działają wszystkie przeglądarkowe skanery) i jakoś to działa. Dziwne, że nikt nie zrobił skanera dla Mozilli. Może jeszcze za mały rynek dla tych rozwiązań.
  • Użyteczne programy: ba.exe - bios agent do poznania wszystkich wersi BIOS (ważne gdy chcemy go zaktualizować), PC-Clean do czyszczenie systemu, PC Wizard + CPU Z.
  • Siatki do wyświetlania danych - danych w większości przypadków jest dużo, nie mieszczą się na ekranie (formularzu, stronie webowej). Zachodzi potrzeba ich porcjowania. Problemów jest wiele: porcjowanie ma być elastyczne (podawać można jako parametr liczbę wierszy do jednorazowego wyświetlenia), wydajne (nie pobieramy od razu wszystkich danych do pamięci operacyjne lecz jedynie tzw. porcje), efektywne (zwalniamy pulę połączeń z bazą). Aby porcjowanie miało sens musi mieć wsparcie w motorze bazy danych, np. instrukcja SQL SELECT musi wspierać możliwość ograniczenia pobrania danych (FIRST 10, LIMIT 10). Musi być także jakiś mechanizm zaznaczania aktualnej pozycji w tabeli (MS nazywa to bookmark). Do problemu wykorzystania mechanizmów motora bazy można podejść dwojako Należy przeszukać możliwości w zakresie zaznaczania porcji danych w mechanizmach metod dostępu poprzez ODBC (sprawdzone - te mechnizmy działają, patrz przykład w tabelce poniżej)/ JDBC (lub ich odpowiedniki w innych językach np. ADODB w PHP) lub też podejść na niski poziom i wykorzystać specyfikę polecenia SQL SELECT dla danej bazy (korzystać z ROWID, FIRST, procedur wbudowanych) oraz specyfiki aplikacji (specjalne wykorzystanie kluczy głównych). Tak czy inaczej jest to trudny problem dla developera i raczej lepiej zdać się na jakieś gotowe narzędzia, za które czasami trzeba trochę zapłacić. A warto, gdyż możemy od razu skupić się na merytoryce zagadnienia szczególnie gdy klient chce od siatki sortowania, przesuwania (w lewo/prawo) i sortowania kolumn. Czasami mamy szczęście i w danym języku czy środowisku programowania mamy wbudowane takie narzędzia (.NET ma DataGrid, PHP ma tzw. pager'a - notabene kiepsko u niego z wydajnością, JDeveloper/Netbeans oferuje siatki danych całkiem dobrej jakości). Alternatywne podejścia:
    • Inna sprawa to filozoficzna, czy możemy użytkownikowi ukryć dane przez pokazanie mu tylko ich części. Czasami nieświadomy użytkownik szuka jakiś danych na ekranie i stweirdza, że ich tam nie ma (a tym czasem są one na następnych stronach). Przy takim potraktowniu problemu można zrobić tak: użytkownik niech sam określi zapytanie i wybierze jakie dane chce oglądać (nalezy mu udostępnić filtr selekcji bazujący na jego wiedzy o tym co chce zobaczyć + Limit ilości wybranych wierszy w zapytaniu). Nie czarujmy się zbyt dużo danych i tak nie przeanalizuje.
    • Dane mają być porcjowane nie na serwerze ale u klienta. W tym przypadku klient pobiera dane z serwera i wkłada do pojemnika lokalnego zwalniając zasoby połączeniowe z bazą (oddając do puli połączenie). Dzięki temu wszystkie operacja odbywają się lokalnie (na sprzęcie skądinąd coraz bardziej wyrafinowanym). Tak myśli MS - tzw. offline dataset. Nawiasem mówiąc VFP w wersji miał pojęcie tzw. offline table. Dane są przetwarzane lokalnie. Najważniejsze jest to co będzie potem - synchronizacja z danymi na serwerze. Wybrano metodę optymistyczna tj. wolno wszystko edytować i zmieniać a dane są zapisywane do bazy centralnej zakładając, że nie ma konfliktów. Ważną sprawą jest wybór pojemnika klient, może to być nawet przeglądarka internetowa lub coś bardziej skomplikowanego.
  • Zasoby:

Przykład "żywcem" wzięty z produkcji (chodzi!)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- #include file="adovbs.inc" --><HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=8529">

<SCRIPT LANGUAGE=javascript>
<!--
function mSkocz(iSkocz)
{
window.location.href="Karta_List.asp?page="+iSkocz;
}
//-->
</SCRIPT>

<%
Response.Expires = -1000 'Makes the browser not cache this page
Response.Buffer = True 'Buffers the content so our Response.Redirect will work

iRozmiarStr = 10
mW = ""

If Request.QueryString("page") = "" Then
iBiezacaStr = 1
Else
iBiezacaStr = CInt(Request.QueryString("page"))
End If

set cn = CreateObject("ADODB.Connection")
set rs = CreateObject("ADODB.Recordset")
rs.PageSize = iRozmiarStr
' rs.CursorLocation = adUseClient ' Bardzo ważne w przypadku bazy Informix
rs.CacheSize = iRozmiarStr
cnstr = "DSN=mssql;UID=inventuser;PWD=userinvent"
cn.ConnectionString = cnstr
cn.Open
rs.ActiveConnection = cn
rs.Open "Select nr_inw,admin_id,typ_sprz,lokalizacja, pokoj from sprzet order by 1 asc", cnstr, adOpenStatic, adLockReadOnly, adCmdText

iLiczbaStr = rs.PageCount

If iBiezacaStr > iLiczbaStr Then iBiezacaStr = iLiczbaStr
If iBiezacaStr < 1 Then iBiezacaStr = 1

Response.Write "<table FONT='Arial Narrow' ALIGN='CENTER' border='1'>" & vbCrLf

Response.Write vbTab & "<tr>" & vbCrLf

For I = 0 To rs.Fields.Count - 1
Response.Write vbTab & vbTab & "<th>"
Response.Write rs.Fields(I).Name
Response.Write "</th>" & vbCrLf
Next

rs.AbsolutePage = iBiezacaStr

iNRWiersza = 1

Response.Write vbTab & "</tr>" & vbCrLf
Do While iNrWiersza <= iRozmiarStr And Not rs.EOF
Response.Write vbTab & "<tr>" & vbCrLf
Response.Write vbTab & vbTab & "<td>"
Response.Write mPokazLink(rs.Fields(0))
Response.Write "</td>" & vbCrLf
For I = 1 To rs.Fields.Count - 1
Response.Write vbTab & vbTab & "<td>"
Response.Write rs.Fields(I)
Response.Write "</td>" & vbCrLf
Next 'I
Response.Write vbTab & "</tr>" & vbCrLf
iNRWiersza = iNRWiersza + 1
rs.MoveNext
Loop

Response.Write "</table>" & vbCrLf
Response.Write "<p ALIGN='CENTER'>Strona " & iBiezacaStr & " / " & iLiczbaStr
Response.Write ", Rozmiar strony=" & iRozmiarStr & "<p>"
%>
<BODY>
<%
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
%>
</P><P ALIGN='CENTER'>
<%
iNast = iBiezacaStr + 1
iPoprz = iBiezacaStr - 1
iOst = iLiczbaStr
iPierw = 1
Response.Write "<INPUT id=button1 type=button value='Pierwszy' name=button1 onclick='mSkocz(" & iPierw & ")'>"
Response.Write "<INPUT id=button2 type=button value='Poprzed.' name=button2 onclick='mSkocz(" & iPoprz & ")'>"
Response.Write "<INPUT id=button3 type=button value='Następny' name=button3 onclick='mSkocz(" & iNast & ")'>"
Response.Write "<INPUT id=button4 type=button value='Ostatni ' name=button4 onclick='mSkocz(" & iOst & ")'>"
Function mPokazLink(mPole)
mPokazLink = "<B><A HREF='wiersz.asp?mID=" & mPole & "'>" & mPole & "</A></B>"
end function
%>
</P>
</BODY></HTML>

<%
Response.Expires = -1000 'Makes the browser not cache this page
Response.Buffer = True 'Buffers the content so our Response.Redirect will work

' If Session("UserLoggedIn") <> "true" Then
' Response.Redirect("login.asp")
' End If

mKlucz = Request.QueryString("mID")

Response.Write "<P><B>KLUCZ=" & mKlucz & "<P>"

if mKlucz <> "" then
mWhere = " where nr_inw = '" & mKlucz & "'"
end if
set cn = CreateObject("ADODB.Connection")
set rs = CreateObject("ADODB.Recordset")
' cnstr = "DSN=mssql;UID=sa;PWD=piotrola"
cnstr = "DSN=mssql;UID=inventuser;PWD=userinvent"
cn.ConnectionString = cnstr
cn.Open
rs.ActiveConnection = cn
rs.Open "Select * from sprzet" & mWhere, cnstr

Response.Write "<table FONT='Arial Narrow' ALIGN='CENTER' border='1'>" & vbCrLf
For I = 0 To rs.Fields.Count - 1
Response.Write vbTab & "<tr>" & vbCrLf

Response.Write vbTab & vbTab & "<td>"
Response.Write rs.Fields(I).Name
Response.Write "</td>" & vbCrLf

if rs.Fields(I).Type <= 14 then
mAlign = "<td align='right'>"
else
mAlign = "<td align='left'>"
end if
Response.Write vbTab & vbTab & mAlign
Response.Write rs.Fields(I)
Response.Write "</td>" & vbCrLf

Response.Write vbTab & "</tr>" & vbCrLf
Next 'I
Response.Write "</table>" & vbCrLf
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing

%>

sdsds

Brak komentarzy: