21/02/2010

World of Goo

Home

Rozgłos i zainteresowanie zdobywają dwa rodzaje gier komputerowych. Te, które są tworzone przez wielkie studia developerskie i mają budżety sięgające dziesiątek milionów dolarów oraz te tworzone w małych studiach, stosunkowo niewielkim nakładem pieniędzy ale nowatorskie, przyciągające nietypowym pomysłem i podejściem do tematu. Te drugie przeważnie nie zachwycają grafiką czy rozmachem ale potrafią wciągnąć na długie godziny. Na taką grę natknąłem się ostatnio.

Word of Goo czyli świat glutów ;) to logiczno, zręcznościowa gra, w której ogromne znaczenie odgrywają prawa fizyki. Grę charakteryzuje specyficzne poczucie humoru i nietypowa oprawa graficzna, a rozgrywka jest naprawdę wciągająca. W skrócie polega na budowaniu różnorakich konstrukcji (mostów, wież itp.) z tytułowych glutów. Może i brzmi to trochę dziwnie ale daje bardzo dużo radości.

Nie chciałbym sie tutaj rozpisywać ponieważ w sieci można znaleźć niejedną dobrą recenzję tej gry. Od siebie serdecznie polecam ten tytuł każdemu kto lubi trochę pomyśleć, ceni innowacyjność i lubi dobrą zabawę. Grę można kupić już za 20 zł!

18/02/2010

Enterprise Library, Informix i CLOB

Home

Data Access Application Block to część Enterprise Library oparta o ADO.NET odpowiedzialna za komunikację z bazą danych. Jedną z bardzo miłych cech tego modułu jest to, że w dużym stopniu ukrywa przed programistą rodzaj bazy danych z jakim pracuje. Uprasza to pisanie aplikacji kompatybilnych z wieloma bazami danych.

Oczywiście nie wszystko jest takie różowe o czym przekonałem się ostatnio. W tej chwili pracuję głównie z bazą danych Informix firmy IBM i Data Access Application Block radził sobie z nią całkiem dobrze ale do czasu kiedy postanowiłem wykorzystać typ bazodanowy CLOB służący do przechowywania dużych obiektów znakowych.

Nie wnikając w szczegóły zapis danych do kolumny o typie CLOB nie udał mi się w ogóle, a odczyt częściowo :) Częściowo ponieważ mogłem odczytać tylko fragment danych. Nie wykluczam możliwości, że mogłem popełnić jakiś błąd ale nie chcąc tracić czasu problem rozwiązałem wykorzystując sterownik ADO.NET firmy IBM przeznaczony tylko do obsługi Informix'a. Biblioteka ze sterownikiem nazywa sie IBM.Data.Informix.dll i instalowana jest razem z Client SDK. U mnie znajdowała się w lokalizacji C:\Program Files (x86)\Informix\Client-SDK\bin\netf20. Model pracy z klasami z tej biblioteki jest prawie taki sam jak z standardowymi klasami ADO.NET. Mamy więc klasę IfxCommand, która dziedziczy z DbCommand, IfxConnecton, która implementuje interfejs IDbConnection itd. Różnice są niewielkie i dotyczą rzeczy specyficznych dla Informix'a czyli np.: obsługi typu CLOB.

Wykorzystanie biblioteki rozwiązało oczywiście mój problem. Sądzę, że wybór IBM.Data.Informix.dll jest dobrym pomysłem dla każdego kto ma zamiar pracować z bazą danych firmy IBM. Nie ma jednak róży bez kolców. Użycie rozwiązania właściwego dla konkretnej bazy danych zamiast Enterprise Library wpływa negatywnie na przenoszalność aplikacji, a własciwie ją uniemożliwia. Oczywiście klasy specyficzne dla Informix'a można odpowiednio przykryć tak aby ewentualna podmiana była łatwiejsza ale nie jest to równoznaczne z użyciem Data Access Application Block.

Reasumując jeśli chcę zachować przenaszalnośc aplikacji będę musiał zastanowić się jak dostosować tą bibliotekę do współpracy z Enterprise Library.

14/02/2010

Pobranie fabryki klasy COM...

Home

Niedawno zostałem poproszony o pomoc w rozwiązaniu problemu z aplikacją ASP.Net do zarządzania bazą danych, który polegał na pojawianiu się poniższego błędu przy jej uruchamianiu:

"Pobranie fabryki klasy COM dla składnika o identyfikatorze CLSID {10020200-E260-11CF-AE68-00AA004A34D5} nie powiodło się z powodu następującego błędu: 80040154."

Błąd ten oznacza tyle, że w systemie nie ma zarejestrowanej klasy COM o podanym identyfikatorze. Ponieważ miałem pod ręką drugi komputer postanowiłem sprawdzić co kryje się za tajemniczym numerem CLSID. W tym celu uruchomiłem edytor rejestru (regedit) i przeszukałem gałąź HKEY_CLASSES_ROOT\CLSID w poszukiwaniu pasującego identyfikatora. Szczęście uśmiechnęło się do mnie i szybko znalazłem odpowiedni klucz z ścieżką do biblioteki dll:

C:\Program Files\Microsoft SQL Server\80\Tools\binn\SQLDMO.DLL

Dalej poszło już prosto. SQLDMO czyli SQL Distributed Management Objects to zbiór obiektów umożliwiających wykonywanie różnych czynności administracyjnych, które standardowo instalowane są razem SQL Server Client Utilities. Ponieważ nie miałem możliwości zainstalowania tego zestawu narzędzi postanowiłem po prostu skopiować wspomnianą bibliotekę i zarejestrować ją przy pomocy polecenia regsvr32. W rozwiązaniu problemu przydatny okazał sie również ten artykuł pomocy technicznej Microsoft. Dzięki niemu dowiedziałem się, że oprócz biblioteki Sqldmo.dll potrzebny jest też plik zasobów Sqldmo.rll. W artykule wymieniono również listę innych bibliotek związanych z modelem obiektów SQL-DMO. Okazało się jednak, że na problematycznym komputerze brakuje tylko tej jednej biblioteki. Po jej zarejestrowaniu aplikacja ASP.Net zaczęła działać.

31/01/2010

"Decimal byte array constructor requires an array of length four containing valid decimal bytes"

Home

"Decimal byte array constructor requires an array of length four containing valid decimal bytes"

Z takim błędem spotkałem się ostatnio pisząc kod komunikujący się z bazą danych. Niestety ale błąd ten miał również dwie utrudniające jego poprawienie właściwości. Po pierwsze pojawiał się na kilku komputerach ale nie na moim. No cóż syndrom "a u mnie działa" zdarza się każdemu. Po drugie kod w jakim występował zdawał się wyglądać całkowicie niewinnie:
DataSet ds = New DataSet

OleDbDataAdapter adapter = New OleDbDataAdapter
adapter.SelectCommand = New OleDbCommand(Command, Connection)

adapter.Fill(ds)
Dokładniej mówiąc wyjątek pojawiał sie przy wywołaniu metody Fill. Kiedy zapytałem wyszukiwarkę o treść komunikatu znalazłem kilkanaście forów z pytaniami dotyczącymi tego błędy w kontekście komunikacji z różnymi bazami danych (ja używam bazy danych Informix). Niestety prawie wszystkie zadane pytania zostały bez odpowiedzi. Znalazłem jednak wypowiedź sugerującą, że błąd pojawia się jeśli w zapytaniu użyto funkcji agregujących.

Zapytanie, którego ja użyłem zawierało całkiem sporo przykładów użycia funkcji agregujących, postanowiłem więc usunąć je z zapytania i zobaczyć co się stanie. W wyniku modyfikacji zapytania wyjątek nie pojawił się. Miałem więc już jakąś wskazówkę co robić dalej. W następnym kroku dodawałem do zapytania kolejne odwołania do funkcji agregujących żeby zobaczyć, które dokładnie spowoduje błąd.

Po kilku próbach znalazłem kłopotliwy fragment zapytania. Wyglądał on tak:
SELECT ..., SUM(Col1) - Sum(Col2), ... 
W tym momencie przypomniałem sobie pewną rzecz i już wiedziałem jak rozwiązać problem. Tak jak napisałem wcześniej błąd nie pojawiał się na komputerze, na którym pracowałem. Dane, które pobrałem z bazy danych mogłem, więc wyświetlić na kontrolce gridowej. Kiedy zrobiłem to po raz pierwszy zauważyłem, że w niektórych kolumnach liczby prezentowane są z bardzo dużą precyzję pomimo, że na poziomie bazy danych użyto typu DECIMAL o precyzji 2. Problem rozwiązałem wymuszając po prostu odpowiednie formatowanie. Teraz jednak okazało się, że kolumny o "dziwnym" formatowaniu na mojej maszynie pokrywały się z przykładami użycia funckji, które powodowały błąd na innych stacjach.

Pierwszy wniosek jest taki, że wynik operacji arytmetycznych na rezultatach działania funkcji agregujących może mieć wyższą precyzję niż by to wynikało z typu kolumn. W przypadku niektórych działań arytmetycznych ma to oczywiście sens, chociaż nie w przypadku odejmowania czy dodawania. Ale mniejsza o tym. Istotne jest to, że z powodu zwiększonej precyzji nie jest potem możliwe skonstruowanie wartości typu decimal i generowany jest wyjątek. Rozwiązanie jest proste. Trzeba zaokrąglić wynik:
SELECT ..., ROUND(SUM(COl1) - Sum(Col2), 2), ... 
Z tego co się dowiedziałem pomóc może również użycie nowszych sterowników OLEDB. Z drugiej strony na moim komputerze zainstalowana jest taka sama wersja sterowników jak na innych. Różnica jest taka, że ja używam Windows 7 ale trudno powiedzieć czy to ma jakiś wpływ. W każdym razie pytanie czemu błąd nie pojawia się na wszystkich stacjach pozostaje otwarte.

06/01/2010

Uruchamianie aplikacji na 64 bitach

Home

Pierwszy wpis w nowym roku 2010 będzie dotyczył zagadnienia uruchamiania aplikacji .Net'owych na maszynach 64 bitowy. W większości przypadków nie ma z tym żadnego problemu. W końcu IL jest przenośny. Problemy zaczynają się kiedy chcemy wykorzystać w swojej aplikacji biblioteki 32 bitowe. Niestety ale nie jest możliwe aby proces 64 bitowy używał bibliotek 32 bitowych i na odwrót. Przeważnie nie mamy również możliwości przekompilowania biblioteki, z której korzystamy. Ja spotkałem się z tym problem uruchamiając aplikację, która do połączenia z bazą danych korzystała ze sterownika ODBC. W czasie jej uruchomienia pojawiał się komunikat:

Dostawca 'Ifxoledbc.2' nie jest zarejestrowany na lokalnym komputerze.

Komunikat mnie zdziwił ponieważ byłem pewny, że dostawca jest zarejestrowany. Przypomniałem sobie jednak, że jest to sterownik 32 bitowy. Jak sobie poradziłem?

Ogólnie są dwa rozwiązania tego problemu. Po pierwsze można w właściwościach projektu ustawić opcję Target CPU na X86. Domyślna wartość to Any CPU. Jeśli z jakichś powodów nie możemy zrekompilować aplikacji możemy skorzystać z programu corflags. Jest on instalowany razem z Visual Studio i pozwala przełączyć aplikację w 32 bitowy tryb pracy np.:

corflags /32bit+ aplikacja

W razie potrzeby ponownego przełączenia na 64 bitowy tryb pracy używamy następującej składni:

corflags /32bit- aplikacja