Welcome Guest Search | Active Topics | Members | Log In

JOBC, NOBC i praca z identyfikatorami i referencjami Options · View
mdabrowski
Posted: Wednesday, July 01, 2009 2:51:02 PM
Rank: Member

Joined: 6/18/2009
Posts: 24
Points: -25
Location: Warszawa
Hej,

W ramach przedmiotu KOR na studiach internetowych studenci po raz pierwszy dostali do ręki NOBC (mieli wybór czy NOBC czy JOBC) i mieli napisać własną aplikację opartą o bazę danych ODRA.

Zarówno w ramach pracy z JOBC jak i NOBC (różnice dla programisty są minimalne) pojawił się poważny problem w pracy z rekordami. Wyobraźmy sobie standardowy scenariusz w aplikacji klienckiej (posłużę się modelem M0 który wszyscy znamy) - pobieramy wszystkie samochody i prezentujemy w formie tabelki. Użytkownik wybiera z listy jeden samochód i chcemy mu wyświetlić wszystkich jego właścicieli. I tu pojawia się problem. Tworzymy zapytanie
"Car.owner.(fName, lName,...) where ....."
i właśnie...co wpisać do tego where'a? Nasz samochód nie ma żadnego pola które by go jednoznacznie identyfikowało i zgodnie z definicją bazy danych mieć nie musi. Ten sam problem pojawia się przy aktualizacji czy usuwaniu rekordów.

Studenci radzili sobie z tym problemem w sposób "prawą ręką do lewego ucha" dodając do swoich klas pole ID i samodzielnie pilnując jego przyrastania (zazwyczaj prostym "max(ID) + 1" i unikalności. Ale czy to dobra droga? W naszej bazie danych każdy obiekt ma swój OID który nawet jest (czasem) dostępny poprzez JOBC czy NOBC jako "RemoteReference". Jego złożoność jest duża (host, port, schemat, identyfikator) ale na ile patrzyłem w kod ODRY powinniśmy być w stanie go jednoznacznie odwzorować na referencję do obiektu by móc na nim dalej pracować.

Teraz chwila o tym "czasami" co do RemoteReference. Gdy zawołamy "Car.(color, owner groupas a)" dla każdego samochodu dostaniemy worek referencji do jego właścicieli. Zawołanie "ref(Car)" zwróci worek referencji do wszystkich samochodów w bazie. Nie ma natomiast możliwości stworzenia zapytania w taki sposób by jednocześnie dostać składowe obiektu (color, power...) i referencję. A po co? By po stronie klienta, zapamiętać zarówno dane obiektu jak i "uchwyt" do niego.

Moje postulaty:
1. dodanie do każdego obiektu możliwości zawołania na nim .ID by pobrać referencję (RemoteReference).
2. stworzenie konstrukcji w SBQL pozwalającej na użycie danych pobranych z RemoteReference w zapytaniu.

Alternatywnie, jeśli uważacie, że danie użytkownikowi pola do grzebania przy OID'a jest złe/skomplikowane/niebezpieczne itd. wyposażenie SBQL-a w narzędzie typu "IDENTITY" by każdy mógł zadeklarować atrybut unikalny w ramach klasy i nie musiał sam się martwić o jego przyrost.
stencel
Posted: Wednesday, July 01, 2009 3:27:42 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
Code:
Car.owner.(fName, lName,...) where .....


Wystarczy uzyc genialnej stack-basowej konstrukcji "as" i juz:

Code:
(Car as x).(x.owner.(fName, lName,...) where x.plateNum ="WE$56")


Drugi problem rozwiazujemy analogicznie:

Code:
Car.(color, owner groupas a)


Po prostu dodajemy as

Code:
(Car as x) (x, x.color, x.owner groupas a)


lub nawet

Code:
(Car as x) (x as myBelovedID, x.color, x.owner groupas a)

mdabrowski
Posted: Wednesday, July 01, 2009 3:41:21 PM
Rank: Member

Joined: 6/18/2009
Posts: 24
Points: -25
Location: Warszawa
stencel wrote:

Po prostu dodajemy as

Code:
(Car as x).(x as myBelovedID, x.color, x.owner groupas a)



OK. To zadziałało super. Mamy ref do obiektu i jego składowe :) Tyle że klient nie może w żaden sposób wykorzystać tej wiedzy którą zdobył w kolejnym zapytaniu, np. przy aktualizowaniu koloru tego samochodu.

stencel wrote:
Wystarczy uzyc genialnej stack-basowej konstrukcji "as" i juz:

Code:
(Car as x).(x.owner.(fName, lName,...) where x.plateNum ="WE$56")


Super. Zakładasz jednak, że istnieje pewien atrybut "naturalny" który jednoznacznie identyfikuje nasz samochód (plateNum). Co gdy takiego nie ma? Czy każda baza danych musi mieć kod VIN, PESEL czy inne tego typu konstrukcje? Zgodnie z best practices jak to ma miejsce w bazach relacyjnych, nawet gdy nasz typ ma naturalny unikalny typ który mógłby posłużyć za klucz główny stosuje się dodatkowy klucz sztuczny jak wspomniane przeze mnie identity.
stencel
Posted: Wednesday, July 01, 2009 3:53:50 PM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
mdabrowski wrote:
OK. To zadziałało super. Mamy ref do obiektu i jego składowe :) Tyle że klient nie może w żaden sposób wykorzystać tej wiedzy którą zdobył w kolejnym zapytaniu, np. przy aktualizowaniu koloru tego samochodu.


Nie rozumiem. Ma przeciez referencje do obiektu to moze aktualizowac.

mdabrowski wrote:
Super. Zakładasz jednak, że istnieje pewien atrybut "naturalny" który jednoznacznie identyfikuje nasz samochód (plateNum). Co gdy takiego nie ma? Czy każda baza danych musi mieć kod VIN, PESEL czy inne tego typu konstrukcje? Zgodnie z best practices jak to ma miejsce w bazach relacyjnych, nawet gdy nasz typ ma naturalny unikalny typ który mógłby posłużyć za klucz główny stosuje się dodatkowy klucz sztuczny jak wspomniane przeze mnie identity.


Zaraz, zaraz. PlateNum jest naturalna informacja biznesowa. Nie da sie wykonac selekcji jesli dwa byty sa biznesowo nierozroznialne. Jak wybrac ten samochod, ktory nas interesuje, gdy nie wiemy czym sie on charakteryzuje biznesowo? Podaj przyklad jakiegos zapytania, ktore ma sens biznesowy, a nie da sie wyrazic w SBA. Bez tego cala dyskusja jest zbyt wysoko w przestrzeni totalnej abstrakcji.
mdabrowski
Posted: Wednesday, July 01, 2009 4:42:40 PM
Rank: Member

Joined: 6/18/2009
Posts: 24
Points: -25
Location: Warszawa
stencel wrote:
Nie rozumiem. Ma przeciez referencje do obiektu to moze aktualizowac.

No właśnie nie. Odwołam się do przykładu z pierwszego postu. Mamy aplikację w Javie czy C# łączącą się po JOBC/NOBC. Pobieramy wszystkie samochody (włącznie z referencjami, jak pokazałeś) i wyświetlamy na ekranie. Problem w tym, że po stronie aplikacji, dzięki JOBC/NOBC, ta referencja staje się jedynie strukturą danych (host, port, schemat, id) której ni jak nie mogę wykorzystać w kolejnym zapytaniu SBQL kierowanym do bazy.
Dlatego postulowałem o możliwość odtwarzania referencji z tych danych w zapytaniu SBQL na zasadzie "where myBelovedID = reconstruct_ref(host, port, shemat, id)".

Quote:
Zaraz, zaraz. PlateNum jest naturalna informacja biznesowa. Nie da sie wykonac selekcji jesli dwa byty sa biznesowo nierozroznialne. Jak wybrac ten samochod, ktory nas interesuje, gdy nie wiemy czym sie on charakteryzuje biznesowo? Podaj przyklad jakiegos zapytania, ktore ma sens biznesowy, a nie da sie wyrazic w SBA. Bez tego cala dyskusja jest zbyt wysoko w przestrzeni totalnej abstrakcji.

Jeszcze raz odwołam się do przykładu z pierwszego postu. Mamy aplikację kliencką która pobiera z bazy danych wszystkie samochody i wyświetla na ekranie w postaci listy/tabeli. Użytkownik może wybrać dowolny i zacząć na nim pracować (usunąć, zmienić pola, dodać właściciela itp.) Nie wiemy na jakiej podstawie wybrał właśnie ten a nie inny samochód. Może jedyne zielone Ferrari, może trzeci najmocniejszy w zestawieniu, może jedyne Porsche o mocy powyżej 200KM. Nie wiemy tego i trudno się pytać użytkownika jakie jest jego kryterium bo aplikacja musi skonstruować swojego where'a.
Gdyby było tak jak piszesz, że każdy obiekt ma pole jednoznacznie rozróżniające je biznesowo, nie było by w MS SQL opcji IDENTITY, Oracle nie wprowadziłby obiektu typu sequence i każda tebela w RBD miałaby primary key na kolumnie/kolumnach istotnych biznesowo.
stencel
Posted: Thursday, July 02, 2009 1:28:23 AM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
mdabrowski wrote:
No właśnie nie. Odwołam się do przykładu z pierwszego postu. Mamy aplikację w Javie czy C# łączącą się po JOBC/NOBC. Pobieramy wszystkie samochody (włącznie z referencjami, jak pokazałeś) i wyświetlamy na ekranie. Problem w tym, że po stronie aplikacji, dzięki JOBC/NOBC, ta referencja staje się jedynie strukturą danych (host, port, schemat, id) której ni jak nie mogę wykorzystać w kolejnym zapytaniu SBQL kierowanym do bazy.
Dlatego postulowałem o możliwość odtwarzania referencji z tych danych w zapytaniu SBQL na zasadzie "where myBelovedID = reconstruct_ref(host, port, shemat, id)".


Moim zdaniem referencja wysylana na strone klienta powinna byc opaque tzn. zupelnie nieczytelna. Powinien to byc ciag bajtow zupelnie nie-do-zinterpretowania. Rozumiem, ze w tym scenariuszu, klient wybiera jakis samochod do edycji i zmienia mu kolor. Mamy w reku referencje do tego obiektu zwrocona przez zapytanie i tera dzieki parametryzowanemu zapytaniu mozemy dokonac modyfikacji tego obiektu. W JDBC sa parametryzowane zapytania i sa one takze koniecznie w JOBC (choc nie wiem czy sa).

Code:
((Car as x) where x = ?).color := "red"


Uzylem pytajnika na oznaczenie miejsca parametru zapytania zgodnie z konwencja JDBC. W ten sposob nie musimy wiedziec co jest "kluczem" w naszych obiektach. Wykorzystujac sparametryzowane zapytanie mozemy skorzystac z posiadanej przez nas w kliencie referencji do modyfikowanego obiektu.
Mariusz
Posted: Thursday, July 02, 2009 10:04:18 AM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 235
Points: 210
Location: Warsaw
mdabrowski wrote:

Jeszcze raz odwołam się do przykładu z pierwszego postu. Mamy aplikację kliencką która pobiera z bazy danych wszystkie samochody i wyświetla na ekranie w postaci listy/tabeli. Użytkownik może wybrać dowolny i zacząć na nim pracować (usunąć, zmienić pola, dodać właściciela itp.) Nie wiemy na jakiej podstawie wybrał właśnie ten a nie inny samochód. Może jedyne zielone Ferrari, może trzeci najmocniejszy w zestawieniu, może jedyne Porsche o mocy powyżej 200KM. Nie wiemy tego i trudno się pytać użytkownika jakie jest jego kryterium bo aplikacja musi skonstruować swojego where'a.
Gdyby było tak jak piszesz, że każdy obiekt ma pole jednoznacznie rozróżniające je biznesowo, nie było by w MS SQL opcji IDENTITY, Oracle nie wprowadziłby obiektu typu sequence i każda tebela w RBD miałaby primary key na kolumnie/kolumnach istotnych biznesowo.

Miałem dokładnie ten sam problem jakieś 5 lat temu. Potrzebowałem wyświetlić w GUI dane pobrane z ODRA i mieć sposób ich jednoznacznej, generycznej identyfikacji bez względu na budowę biznesową. Analogicznie jak Marcin, postulowałem wprowadzenie identyfikatora. I podobnie jak teraz propozycja nie spotkała się z akceptacją. NIe pamiętam już dokładnie argumentacji, ale chyba coś w stylu, że nie jest to potrzebne bo można radzić sobie inaczej. Więc poradziłem sobie
inaczej dodając identyfikatory do modelu biznesowego, co oczywiście nie jest rozwiązaniem generycznym.

Jeżeli mówimy o prawdziwych aplikacjach biznesowych, korzystających z GUI, to będą takie sytuacje, że nie da się napisać zapytania zwracającego konkretny obiekt. Użytkownik wybrał jakąś pozycję z listy nie kierując się żadnymi szczególnymi kryteriami - musimy mieć generyczny sposób jej zidentyfikowania. I nie - nie jest dobrym sposobem bazowanie na indeksie i odnoszenie się po numerze do elementu w kolekcji. Dane w GUI mogą być potencjalnie przefiltrowane, posortowane, itd. - w takich sytuacjach indeks nie wystarcza. Moim zdaniem jedynym dobrym rozwiązaniem jest danie dostępu do jednoznacznego identyfikatora obiektu (np. w ramach bazy, czy czegoś podobnego).
mdabrowski
Posted: Thursday, July 02, 2009 10:57:37 AM
Rank: Member

Joined: 6/18/2009
Posts: 24
Points: -25
Location: Warszawa
stencel wrote:
Moim zdaniem referencja wysylana na strone klienta powinna byc opaque tzn. zupelnie nieczytelna. Powinien to byc ciag bajtow zupelnie nie-do-zinterpretowania. Rozumiem, ze w tym scenariuszu, klient wybiera jakis samochod do edycji i zmienia mu kolor. Mamy w reku referencje do tego obiektu zwrocona przez zapytanie i tera dzieki parametryzowanemu zapytaniu mozemy dokonac modyfikacji tego obiektu. W JDBC sa parametryzowane zapytania i sa one takze koniecznie w JOBC (choc nie wiem czy sa).

Code:
((Car as x) where x = ?).color := "red"


Uzylem pytajnika na oznaczenie miejsca parametru zapytania zgodnie z konwencja JDBC. W ten sposob nie musimy wiedziec co jest "kluczem" w naszych obiektach. Wykorzystujac sparametryzowane zapytanie mozemy skorzystac z posiadanej przez nas w kliencie referencji do modyfikowanego obiektu.

To jest dokładnie to o co postuluję.
Dla mnie mniej istotne jest czy będzie to referencja w obecnym stylu czy bitowa czy jakakolwiek inna. O czwórce (host,port,schemat,id) mówię ze względu na to, że dziś właśnie to mamy do dyspozycji po stronie klienta ale na tym opcje się kończą.
Serwerowa strona CLI z mechanizmów którego korzysta JOBC czy NOBC nie jest przygotowane na Twoją komendę "((Car as x) where x = ?).color := "red"".I niezależnie od tego, czy po stronie JOBC ta referencja będzie pakowana do zapytania ręcznie czy przez parametryzację (którą JOBC/NOBC potrafią ale tylko w kontekście typów prostych). Na ile rozumiem, CLI potrzebuje zapytanie w formie stringa, więc mechanizm parametryzacji jest tylko pomocą dla programisty by nie musieli odpowiednio formatować liczb czy dat.
Tak to działa obecnie.

Podsumowując, potrzebny jest mechanizm pozwalający przesłać zapisaną przez klienta referencję (z otwartą dyskusją o formie w jakiej klient widzi tą referencję) z powrotem na serwer by móc jej użyć do przyrównania obiektów w kolejnym zapytaniu.

Odgrzebałem ostatnio wątek sprzed lat ponad dwóch, wtedy dyskusja zeszła na temat utworzenia własnego JDBC/JOBC co już mamy i to w komplecie z NOBC. A problem od którego tamta dyskusja wyszła pozostał nierozwiązany.

Moja propozycja rozwiązania tego problemu to zamiana przed wysłaniem do klienta Result.Reference na nietrwały numerek (najlepiej generowany w sposób "niesekwencyjny", by nie było kombinowania przez klientów, że mam referncję n-tą to zapytam się o n+1-szą). Wystarczyłoby wtedy zdefiniować w SBQL-u przyrównanie (referencja = integer) tak, by sięgał do tego lokalnego składu przemapowując ten numerek na referencję.


Mariusz, dzięki. Bo już myślałem, że nie jasno tłumaczę i nikt nie wie o czym mówię.
stencel
Posted: Thursday, July 02, 2009 11:54:13 AM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
mdabrowski wrote:
Na ile rozumiem, CLI potrzebuje zapytanie w formie stringa, więc mechanizm parametryzacji jest tylko pomocą dla programisty by nie musieli odpowiednio formatować liczb czy dat.


Nie, nie i jeszcze raz nie. Mechanizm ten zabezpiecza nas np. przed SBQL-injection, pozwala na prepare statement, a wiec wykorzystanie wielokrotne raz zoptymalizowanego zapytania itd. Nie zgadzam sie ze stwierdzeniem, ze parametryzacja to tylko prosty skrot notacyjny.

mdabrowski wrote:
Moja propozycja rozwiązania tego problemu to zamiana przed wysłaniem do klienta Result.Reference na nietrwały numerek (najlepiej generowany w sposób "niesekwencyjny", by nie było kombinowania przez klientów, że mam referncję n-tą to zapytam się o n+1-szą). Wystarczyłoby wtedy zdefiniować w SBQL-u przyrównanie (referencja = integer) tak, by sięgał do tego lokalnego składu przemapowując ten numerek na referencję.


Zdecydowanie jestem przeciw. Parametryzacja jest mechanizmem o niebo ogolniejszym i pozwalajacym na wiele innych rzeczy wspomnianych wyzej. Warto ja po prostu zaimplementowac.
subieta
Posted: Thursday, July 02, 2009 5:14:38 PM

Rank: Advanced Member

Joined: 12/22/2004
Posts: 675
Points: 704
Location: Legionowo
mdabrowski wrote:
Dlatego postulowałem o możliwość odtwarzania referencji z tych danych w zapytaniu SBQL na zasadzie "where myBelovedID = reconstruct_ref(host, port, shemat, id)".

Mysle, że taka funkcję należałoby zaimplementować dodając ją do SBQL jako funkcję generyczną. Pozwoliłoby to zapamiętywać zwracaną referencję po stronie klienta, a następnie użyć ją później dla dowolnego celu. Oczywiście, ze wszystkimi negatywami takiego rozwiązania, z ktorych najbardziej dyskusyjnym jest możliwość usunięcia obiektu, którego referencja była zapamiętana. Ale to jest także w CORBA więc nic nowego. Wystarczy, aby programista wiedział, ze użycie tej funkcji może się skończyć wyjątkiem. I oczywiście, nigdy nie robić reuse referencji do obiektów. Nieco mniejszy problem dotyczy tego, że ta funkcja może być zdefiniowana dla dowolnego typu referencji. Ale takie funkcje już mamy, np. count. Najmniejswzy problem dotyczy tego, że taka zapiętana referencja jest strukturą. Ale sądzę, ze tak powinno pozostać, przy czym typ tej struktury powinien być niezmienny. Można byłoby więc pisać np. następujący program (sorry, moze nie być to dokładnie Java i nie znam JOBC - chodzi o idee):
Code:
SBQLrefsType Owner;
Owner = JOBC(Car.owner.Person where fName = "Malina"); // zapamiętałem referencje do Maliny
......
JOBC(reconstruct_ref(Owner).has.Car.color := "red")
nina
Posted: Thursday, July 02, 2009 6:11:14 PM
Rank: Advanced Member

Joined: 1/7/2007
Posts: 11
Points: 33
Location: Bkk
Dopoki id jest fizycznym pointerem, zarowno uzycie takiej funkcji jak i "parametrow", oznaczac moze potencjalnie totalna rozwalke bazy danych.
mdabrowski
Posted: Thursday, July 02, 2009 10:32:30 PM
Rank: Member

Joined: 6/18/2009
Posts: 24
Points: -25
Location: Warszawa
subieta wrote:
mdabrowski wrote:
Dlatego postulowałem o możliwość odtwarzania referencji z tych danych w zapytaniu SBQL na zasadzie "where myBelovedID = reconstruct_ref(host, port, shemat, id)".

Mysle, że taka funkcję należałoby zaimplementować dodając ją do SBQL jako funkcję generyczną. Pozwoliłoby to zapamiętywać zwracaną referencję po stronie klienta, a następnie użyć ją później dla dowolnego celu. Oczywiście, ze wszystkimi negatywami takiego rozwiązania, z ktorych najbardziej dyskusyjnym jest możliwość usunięcia obiektu, którego referencja była zapamiętana. Ale to jest także w CORBA więc nic nowego. Wystarczy, aby programista wiedział, ze użycie tej funkcji może się skończyć wyjątkiem. I oczywiście, nigdy nie robić reuse referencji do obiektów. Nieco mniejszy problem dotyczy tego, że ta funkcja może być zdefiniowana dla dowolnego typu referencji. Ale takie funkcje już mamy, np. count. Najmniejswzy problem dotyczy tego, że taka zapiętana referencja jest strukturą. Ale sądzę, ze tak powinno pozostać, przy czym typ tej struktury powinien być niezmienny. Można byłoby więc pisać np. następujący program (sorry, moze nie być to dokładnie Java i nie znam JOBC - chodzi o idee):
Code:
SBQLrefsType Owner;
Owner = JOBC(Car.owner.Person where fName = "Malina"); // zapamiętałem referencje do Maliny
......
JOBC(reconstruct_ref(Owner).has.Car.color := "red")


Widzę, że mamy podobne poglądy. Na mój gust musiałoby to wyglądać tak (piszę w składnie C#/NOBC ale dla Javy będzie podobnie):

Code:
NOBCCommand selcomm = new NOBCCommand("Car.owner.Person where fName = \"Malina\"");
ReferenceResult malinaRef = (ReferenceResult)comm.Execute();

NOBCCommand updatecomm = new NOBCCommand(reconstruct_ref({owner}).has.Car.color := \"red\"");
updatecomm.addRefParam("owner", malinaRef);
updatecomm.Execute();


Programista aplikacji klienckiej zawsze musi być przygotowany na to, że coś się nie powiedzie. To, że nie można odtworzyć referencji na podstawie jego danych, bo ktoś w między czasie usunął obiekt, jest takim samym błędem jak to, że ODRA nie odpowiada wcale lub ktoś wyrzucił cały moduł z którego chciałby skorzystać.

nina wrote:
Dopoki id jest fizycznym pointerem, zarowno uzycie takiej funkcji jak i "parametrow", oznaczac moze potencjalnie totalna rozwalke bazy danych.

Możesz uzasadnić? W końcu ID to tylko numerek - OID wskazujący na obiekt w bazie danych. Jeśli klient jest w stanie dostać się do tego obiektu poprzez skomplikowany where to czemu nie miałby móc zrobić tego samego poprzez zrekonstruowanie zapamiętanej referencji. To co będzie mógł zrobić z tym obiektem nie zależy od tego czy otrzymał uchwyt do niego poprzez selekcję czy odtworzenie referencji.
nina
Posted: Thursday, July 02, 2009 11:52:15 PM
Rank: Advanced Member

Joined: 1/7/2007
Posts: 11
Points: 33
Location: Bkk
Numerek na poziomie bazy danych/jezyka nie jest numerkiem na poziomie systemu. Mylisz wartosc klucza glownego i wskaznika, identyfikator logiczny i fizyczny. Gdyby id byl identyfikatorem logicznym obiektu, to wszystkie obiekty musialyby byc przechowywane w jakiejs tablicy/hashmapie/indeksie. Ale nie sa - id jest poki co fizycznym wskaznikiem na obiekt. Moze to zostac zmienione, ale moga sie z tym wiazac koszty wydajnosciowe nieakceptowalne dla SBA (ktore wymaga czestego dostepu do obiektow po ich OID).

Co mozna zrobic majac reconstruct_ref i OID w postaci wskaznikow? Na przyklad to co ponizej.

Moge sobie zdefiniowac obiekt string:

x : string;

Nastepnie przypisac mu wartosc w postaci ciagu znakow, ale zgodna z wewnetrzna, binarna reprezentacja obiektu:

x := " { idyfikator_rodzaju_obiektu, id obiektu nadrzednego, 4294967296, "x" } "; // nie pamietam dokladnie struktury obiektow STRING_OBJECT

nastepnie dostarczyc do javy referencje do x (id_x)

po czym wykonac operacje

id_z := reconstruct_ref(id_x.getHost(), id_x.getPort(), id_x.getSchema(), id_x.getId() + SIZE_OF_OBJECT_HEADER);

W ten sposob system potraktuje jako obiekt cos co w rzeczywistosci jest wartoscia obiektu string. Kolejna operacja:

while (true) id_z := id_z + "X"

Wynik: baza danych zamazana przez zlosliwego uzytkownika znakami 'X' od offsetu id_x.getId() + SIZE_OF_OBJECT_HEADER do konca pliku danych, utrata spojnosci, crash systemu

W podobny sposob mozna byloby zapewne odczytywac hasla uzytkownikow oraz wykonywac rownie ciekawe rzeczy.

Wniosek: jesli OID jest fizyczny, reconstruct_ref dostarczony z zewnatrz jest nieakceptowalny. Jesli potrzebna jest mozliwosc identyfikowania obiektow na zewnatrz bazy danych, do schematu trzeba wprowadzic atrybut odpowiadajacy kluczowi glownemu.
stencel
Posted: Friday, July 03, 2009 12:37:38 AM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
Zgadzam sie z watpliwosciami Niny i ciesze sie, ze nie jestem sam w tej dyskusji. Pamietajcie tez ze ID, ktore widzi klient wcale nie musi byc logicznym albo fizycznym id obiektu skladowanego. Moze to byc tez id obiektu wirtualnego z perspektywy i zgodnie z zasadami, uzytkownikowi nic do tego. Z jego punktu widzenia identyfikator normalny i wirtualny powinny byc nierozroznialne. A jak sobie przypomnimy identyfikator wirtualny, moze zawierac sporo danych, bo sa tam przeciec ziarna wszystkich perspektyw zagniezdzenia.

Dlaczego nie akceptujecie czystego koncepcyjnie mechanizmy parametrow, tylko chcecie robic jakies workaroundy w postaci odzworowan identyfikatorow na skalary i odwrotnie (reconstruct_ref)?
nina
Posted: Friday, July 03, 2009 1:07:04 AM
Rank: Advanced Member

Joined: 1/7/2007
Posts: 11
Points: 33
Location: Bkk
Parametry tez raczej nie pomoga. To tylko syntaktyczna forma reconstruct_ref. To co jest wyplute z bazy danych bedzie obiektem Javy ktory mozna sobie dowolnie modyfikowac (np. ustalac wartosc id), a nastepnie uzyc jako parametr. Nie ma mozliwosci zeby poza systemem kontrolowac/zabraniac czyjegos dostepu do OIDa, nawet jesli bedzie on "opaque". System nie moze akceptowac referencji dostarczonych z zewnatrz jesli OID jest fizyczny, i tyle. Chyba ze chcemy sie cofnac 20 lat do DOSa i Windows3.11. Obawiam sie jednak ze to nie przejdzie.
stencel
Posted: Friday, July 03, 2009 7:31:04 AM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 598
Points: 74
Location: Raszyn
nina wrote:
Parametry tez raczej nie pomoga. To tylko syntaktyczna forma reconstruct_ref. To co jest wyplute z bazy danych bedzie obiektem Javy ktory mozna sobie dowolnie modyfikowac (np. ustalac wartosc id), a nastepnie uzyc jako parametr. Nie ma mozliwosci zeby poza systemem kontrolowac/zabraniac czyjegos dostepu do OIDa, nawet jesli bedzie on "opaque". System nie moze akceptowac referencji dostarczonych z zewnatrz jesli OID jest fizyczny, i tyle. Chyba ze chcemy sie cofnac 20 lat do DOSa i Windows3.11. Obawiam sie jednak ze to nie przejdzie.


Zaraz, zaraz. Nina, z Twojej wypowiedzi wynika, ze z referencjami obiektow wyslanymi do klienta nie mozna nic zrobic. Z drugiej strony SBA/SBQL przewiduje referencje do obiektow jako jeden z podstawowych elementow zbioru mozliwych wynikow zapytan. To jaki to ma sens?

Po raz kolejny tez slysze ze parametry to tylko jakas syntaktyczna forma czegos. Po stokroc nieprawda! Maja one znacznie wieksze znaczenie niz notacja, np.: zabezpieczenie przed SQL/SBQL injection oraz mozliwosci prepare statement, a wiec wielokrotne wykonywanie tego samego zapytania bez jego reoptymalizacji (a metod optymalizacji dla SBA mamy juz tyle, ze robi sie z procesu optymalizacji dosc kosztowny, ale za to smaczny, pasztet).
Mariusz
Posted: Friday, July 03, 2009 9:31:26 AM

Rank: Advanced Member

Joined: 12/7/2004
Posts: 235
Points: 210
Location: Warsaw
nina wrote:
Numerek na poziomie bazy danych/jezyka nie jest numerkiem na poziomie systemu. Mylisz wartosc klucza glownego i wskaznika, identyfikator logiczny i fizyczny. Gdyby id byl identyfikatorem logicznym obiektu, to wszystkie obiekty musialyby byc przechowywane w jakiejs tablicy/hashmapie/indeksie. Ale nie sa - id jest poki co fizycznym wskaznikiem na obiekt. Moze to zostac zmienione, ale moga sie z tym wiazac koszty wydajnosciowe nieakceptowalne dla SBA (ktore wymaga czestego dostepu do obiektow po ich OID).

Co mozna zrobic majac reconstruct_ref i OID w postaci wskaznikow? Na przyklad to co ponizej.

Moge sobie zdefiniowac obiekt string:

x : string;

Nastepnie przypisac mu wartosc w postaci ciagu znakow, ale zgodna z wewnetrzna, binarna reprezentacja obiektu:

x := " { idyfikator_rodzaju_obiektu, id obiektu nadrzednego, 4294967296, "x" } "; // nie pamietam dokladnie struktury obiektow STRING_OBJECT

nastepnie dostarczyc do javy referencje do x (id_x)

po czym wykonac operacje

id_z := reconstruct_ref(id_x.getHost(), id_x.getPort(), id_x.getSchema(), id_x.getId() + SIZE_OF_OBJECT_HEADER);

W ten sposob system potraktuje jako obiekt cos co w rzeczywistosci jest wartoscia obiektu string. Kolejna operacja:

while (true) id_z := id_z + "X"

Wynik: baza danych zamazana przez zlosliwego uzytkownika znakami 'X' od offsetu id_x.getId() + SIZE_OF_OBJECT_HEADER do konca pliku danych, utrata spojnosci, crash systemu

W podobny sposob mozna byloby zapewne odczytywac hasla uzytkownikow oraz wykonywac rownie ciekawe rzeczy.


Jeżeli dobrze rozumiem to powyższe negatywne działania są możliwe tylko wtedy gdy wprowadzimy arytmetykę wskaźników tak jak np. w C++. Czyli możliwe będzie utworzenie nowego wskaźnika przez dodanie/przesunięcie starego. Marcin proponował aby wskaźniki na obiekty były "losowe" - wtedy nie da się utworzyć kolejnych na podstawie poprzedniego. Konsekwencją jest brak arytmetyki wskaźników i konieczność ich przechowywania w jakiejś kolekcji po stronie BD (tak jak pisała Nina).
nina wrote:

Wniosek: jesli OID jest fizyczny, reconstruct_ref dostarczony z zewnatrz jest nieakceptowalny. Jesli potrzebna jest mozliwosc identyfikowania obiektow na zewnatrz bazy danych, do schematu trzeba wprowadzic atrybut odpowiadajacy kluczowi glownemu.

Jak pokazałem poprzednio (chyba, że mi coś umyka) wprowadzenie czegokolwiek do schematu nie rozwiązuje wszystkich problemów, np. jak zrobić dowolne generyczne narzędzie z GUI, które ma pracować z dowolnymi danymi? Jak w takiej sytuacji identyfikować obiekty wybrane przez użytkownika z poziomu np. Javy?
nina
Posted: Friday, July 03, 2009 10:11:22 AM
Rank: Advanced Member

Joined: 1/7/2007
Posts: 11
Points: 33
Location: Bkk
stencel wrote:
Zaraz, zaraz. Nina, z Twojej wypowiedzi wynika, ze z referencjami obiektow wyslanymi do klienta nie mozna nic zrobic. Z drugiej strony SBA/SBQL przewiduje referencje do obiektow jako jeden z podstawowych elementow zbioru mozliwych wynikow zapytan. To jaki to ma sens?


Taki ze artykul na konferencje to jedno, a rzeczywistosc to drugie. Jest 100 milionow podobnych problemow do rozwiazania zanim z SBQL zrobi sie produkt.

mariusz wrote:
Jak w takiej sytuacji identyfikować obiekty wybrane przez użytkownika z poziomu np. Javy?


Tak samo jak to sie robi w RBD.
mdabrowski
Posted: Friday, July 03, 2009 10:16:59 AM
Rank: Member

Joined: 6/18/2009
Posts: 24
Points: -25
Location: Warszawa
nina wrote:
while (true) id_z := id_z + "X"


To chyba nie jest dziś możliwe. Zakładając, że nasz reconstruct_ref() zwróci odra.sbql.results.runtime.ReferenceResult, ODRA nie pozwala na operacje na nim.

Prosty przykład, mamy zmienną:
Code:
i:integer;

Zawołamy ref(i) i dostajemy właśnie ReferenceResult. I dla tego typu zawołanie dodawania
Code:
ref(i) + 1;

da błąd:
Code:
odra.exceptions.rd.RDCompilationException: (l:1 c:1) value expected in: '(ref(i))' in the context of: '(((ref(i))) + (1))'


Jak znajdę wolną chwilę sprawdzę twój przykład ze stringiem ale myślę, że będzie podobnie.

Wygląda na to, że z Referencją nie można wiele zrobić. I bardzo dobrze. Ja postuluję jedynie by była możliwość przyrównania. Nic więcej do przedstawionych tu celów nie jest potrzebne.
nina
Posted: Friday, July 03, 2009 10:19:37 AM
Rank: Advanced Member

Joined: 1/7/2007
Posts: 11
Points: 33
Location: Bkk
Moj przyklad to tylko pseudokod. Wiadomo ze nie zadziala jak sie go przeklei. Wazna jest idea.
Users browsing this topic
Guest


Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Main Forum RSS : RSS

Powered by Yet Another Forum.net version 1.9.1.6 (NET v2.0) - 11/14/2007
Copyright © 2003-2006 Yet Another Forum.net. All rights reserved.
This page was generated in 0.321 seconds.