2012-02-10

SQLLite

Dla jednego z moich projektów: Manga Crawler postanowiłem podczas rozbudowy programu przejść na plikobazę SQLLite. Dostęp do niej zamierzam uzyskać poprzez jakiś ORM (prawdopodobnie NHibernate). Na razie chciałem uruchomić tylko dostęp poprzez ADO z wykorzystaniem System.Data.SQLite.

Jak zawsze staram się wszystko kompilować z źródeł. System.Data.SQLite jest pod tym względem wyjątkowo oporna. W solucji mamy trzy projekty:

SQLite.Interop.2010 - SQLLite + dodatkowy kod odpowiedzialny za rozszerzania, szyfrowanie, i zmienę zachowania pewnych funkcji z uwagi na GC w .NET. Wszystko jest kompilowane w C++.

System.Data.SQLite.2010 - źródła wrappera ADO w C#.

System.Data.SQLite.Module.2010 - dołączona jako moduł do pierwszego. Źródła takie same jak projekt 2. Zmieniane są tylko opcje kompilacji.

Z uwagi na to, że projekt 2 i 3 mają wspólne źródła ktoś wpadł na pomysł, że można części wspólne projektu powyłączać do osobnych plików i dołączać je. Nie jest to zły pomysł, tylko, że VS nie radzi sobie z tym i w explorerze nie ma żadnych plików.

Wszystkie 3 pliki projektów powinniśmy uważnie przestudiować gdyż mają one dużo niewidocznego z GUI kodu.

Moduł 3 dołączany do 1 to tak naprawdę skompilowane źródła (do języka pośredniego), moduły takie mogą się składać na assembly.

Jak to się dzieje, że nasz projekt 1 po dołączeniu 3 staje się assembly (w trybie mixed-mode, który powala na łączenie kodu niezarządzanego i zarządzanego). Cały projekt choć kompilowany jest zwykły projekt C++ ma poustawiane opcje tak, że w rzeczywistości jest mixed mode DLL.

W czym więc problem.

Jako referencje w naszym programie powinniśmy wskazać projekt 1, ale nie zawiera on zarządzanych źródeł z projektów 2 i 3. Tak więc nasze referencje w kodzie nie zostaną rozwiązane. Jeśli wskażemy projekt 2 to podczas uruchomienia dostaniemy błąd. Projekt drugi kompiluje się do System.Data.SQLite.2010.DLL, wykorzystuje natywne funkcje z SQLite.Interop.2010.DLL. Tak więc dostaniemy błąd o braku SQLite.Interop.2010.DLL. Kiedy kod z 2 jako 3 zostanie umieszczony w 1 żadnego błędu nie dostaniemy, wszystko jest w jednej bibliotece i kod zarządzany importuje symbole z niezarządzanej części tej samej DLLki.

Możemy oczywiście dodawać SQLite.Interop.2010.DLL do miejsca gdzie siedzi exe. Musimy to robić w post-build projektu. VS nie pozwala nam dodać referencję do niezarządanego projektu.

Teraz jak to pisze to przychodzi mi na myśl, że być może projekt 1 powinniśmy ustawić na zarządzalny, cały kod objąć klauzulą UNSAFE. Wtedy taki projekt moglibyśmy dodać do projektu z exe.

Jeśli projekt 2 skopiujemy tam gdzie exe w post-build to zawiera on powielony kod z 2. Nie wiem co się stanie jak załadujemy taką dllke, teoretycznie będziemy ją ładować jako niezarządzaną. Takie rozwiązanie wymaga trzech projektów w mojej solucji, których współdziałanie bez analizy będzie wywoływało wiele pytań. Po co 3, po co w dwóch to samo.

Osobiście zdecydowałem się na przerobienie projektów. Projekt 1 zawiera tylko źródła niezarządzalne i dodawany jest do głównego projektu w post-build. Do głównego projektu dodawany jest projekt 2. Nazwa dllki projektu 1 jest taka jakiej poszukuje projekt 2. Przy okazji powłączałem do plików projektów wszystkie includy.

Niby nic ale z uwagi na to jak to wszystko jest poplątane poszedł na to cały dzień. Osobiście nie jestem fanem takiego mieszania w pliku projektu, by mieszać nasz kod z kodem VS. Co najwyżej tu i tam dodać include do naszych elementów i tyle.

Całkiem przyjemną rzeczą byłaby możliwość ustawiania naszych opcji ustawianych w pliku projektu. Jak na razie jedyną możliwością ich zmiany są parametry podczas kompilacji z linii poleceń.

Przy okazji wywaliłem też jakieś bitmapy, zbędne jak mi się wydaje.

Zobaczymy czy będzie działać.

O ile podczas kolejnych wydań nie będą modyfikowane pliki projektów cała aktualizacja na nowy kod powinna przejść gładko.

Brak komentarzy:

Prześlij komentarz