"Igor V. Rafienko" <igorr@ifi.uio.no> wrote in message
news:xjvheymigzw.fsf@gjallarbru.ifi.uio.no...
> * Jesper Gødvad
>
> > std::string tal = "123456" // et eller andet tal
> > Tallet skal konverteres til en long - det kan jeg godt finde udaf,
> jøss, folk har begynt å lære (det er ikke vondt ment).
Ja, men det ville være rart hvis der var en nemmere måde
> > men jeg skal ikke bruge long værdien til noget.
> Hva skal du med konverteringen da? :)
[eksempler som jeg først forstår senere, i morgen eller om nogle år]
> Men, av ren nysgjerrighet -- hva skal du med dette?
Ak, jeg sidder og programmerer et distribueret database system fra grunden.
Det er en opgave på datamatikeruddannelsen, som jeg kan se jeg ikke er den
eneste der kæmper med udfra andre spørgemål i denne newsgroup.Det bliver en
længere forklaring, men du er jo selv ude om det.
Klienten sender en sql-streng, som min server lexikerer og gemmer i
henholdsvis 'symboltabel' og 'symbolliste'. Symbol-tabellen indeholder som
default de reseverede ord og operatorer, fx:
type, værdi
------------
ord, SELECT
ord, CREATE
ord, TABLE
[...]
operator, =
operator, *
Når lexeren støder på elementer der ikke findes i symboltabellen i forvejen
tilføjes de i enden vector<tabelObjekt>.push_back(<tabelObjekt>) .
Rækkefølgen huskes i en symbolliste der er en list<int> . Hvis vi
forestiller os, at der er 20 reserverede ord og operatorer kunne resultatet
være følgende:
sql: SELECT KUNDER.NAVN, KUNDER.ID FROM KUNDER
liste: 1, 21, 22, 21, 23, 5, 21
Hvor tallet 21 svarer til tabelnavnet 'kunder'.
Da jeg har enumerations til samtlige reserverede ord kan jeg i parseren
slippe for at foretage en string-compare og i stedet:
symbolliste::iterator i;
if ( *i == reSelect ) {
if ( *i > antalReserveredeOrd && tabel[*i].type == enumOrd ) {
cout << "Der står SELECT efterfulgt af et gyldigt tabelnavn";
( Du kan nok gætte hvad jeg skulle bruge distance() til nu )
Når parseren (som eksisterer på serveren sammen med lexeren) har
syntax-checket sql-udtrykket skal jeg sende kommandoen videre den den eller
de tabelservere der indeholder den/de berørte tabeller. Jeg kunne
selvfølgelig sende hele den kontrollerede symbolliste / symboltabel, men da
serveren alligevel skal have et skema over hvor de forskellige tabeller og
felter befinder sig kan jeg lige så godt gøre det nemt for mig selv at kode
tabelserveren og sende det i protokolform.
Streng til tabelserver:
kode: #1, #2, #10, #3, #1, #10, #3, #2
oversat: SELECT, [AntalFelter], { [tabelServerNummer], [tabelNummer],
[feltNummer] }
På tabelserveren kan jeg så igen bruge mine enumerations
if ( modtagetStrengOverNet.at(0) == reSelect ) {
int feltStart;
for ( int i = 0; i < modtagetStrengOverNet.at(1); i++ ) {
feltStart = ( i * 3 ) + 1;
// tabelnummer står på feltStart +1
// feltnummer står på feltStart +2
}
}
Så langt, så godt...
I tilfælde som CREATE TABLE kunder, SELECT ... WHERE navn = 'Svendsen' er
jeg tvunget til at overføre selve strengen, men det gør ikke noget for jeg
ved jvf. min protokol at der skal stå en streng. Derfor tilføjer jeg
(char) streng.size() foran strengen, så jeg ved hvor næste element
starter.
MEN! (nu kommer pointen)
Når jeg så skal sende en int, som fx. WHERE id = 123456 vil jeg sende den
som en 32 bit integer / long.
Ligeledes vil jeg kun have en 4 byte/char repræsentation af integers i mit
filsystem, da filsystemet skal have fast længde så jeg kan bruge seekp() og
seekg().
Jeg svarer på løsningsmulighederne fra dig og Mogens i et senere brev, for
jeg kører på den 13. time og 4. kande kaffe nu.
Tak for hjælpen.
mvh. jesper