Jak już nie raz wspominałem, chciałbym by sercem MemoryVisualizera był język zapytań oparty o Cypher, a właściwie leżąca pod spodem baza grafowa Neo4j. Ma mi to zapewnić dużą ekspresyjność zapytań oraz (mam nadzieję) dużą szybkość działania. Tutaj pojawia się pewien drobny temat do przemyślenia. Neo4j napisany jest w Javie i szczęściarze piszący w tym języku mogą załączyć ten silnik jako część swojej aplikacji. Niestety w aplikacji .NETowej o takim self-hostowaniu nie może być mowy. Portu Neo4j na .NET nie ma, choć pojawiły się i takie pomysły, np. w formie Neo4Net. Ciekawa dyskusja na ten temat odbyła się na grupie lists.neo4j.org. Nawet jeśli gdzieś, coś da się na tym polu da zdziałać i jest to temat naprawdę ciekawy sam w sobie (np. poprzez IKVM), nie chciałbym czasu przeznaczonego na projekt tracić na portowanie Neo4j. Co do alternatyw, wiem m.in., że istnieje Fallen-8 oraz świeża sprawa, Microsoftowy GraphEngine.io (znany też jako Trinity) ale oba nie wspierają Cyphera, w którym się zabujałem i z którego nie chcę rezygnować. Warto w tym miejscu też wspomnieć o zacnej inicjatywie OpenCypher, ale na chwilę obecną nie mam jak z niej skorzystać. Może kiedyś powyższe silniki spróbują go uwzględnić.
Pozostaje mi więc w projekcie użyć Neo4j jako bazę danych instalowaną stand-alone, działającą jako serwer z dostępem m.in. poprzez REST API. Ze strony Neo4j do pobrania jest wersja "portable", którą da się zarządzać poprzez skryty PowerShell i na chwilę obecną to jedyna opcja jaką widzę. Pytanie czy muszę to jakoś dystrybuować wraz ze swoim projektem. Fajne jest to, że Neo4j (mimo że ma zapewniającą dodatkowe funkcjonalności wersję komercyjną) jest produktem open source w licencji GPL i dostępny na GitHubie. Zatem mój projekt w wersji wykonywalnej zyska jedną dużą zależność - będzie zawierał około 60-70MB dystrybucji Neo4j.
Dystrybucja jednak to nie problem. Co zrobić z kodem źródłowym na GitHubie? Opcji jest kilka:
- mogę wrzucić kod wykonywalny (lub ZIPa) całego Neo4j do swojego repozytorium - wada jest taka, że to ja będę musiał przerzucać te binarki w razie uaktualnień Neo4j. Ale co gorsza, każdy kto sklonuje moje repozytorium będzie musiał ordynarnie zaciągnąć te megabajty danych. Mało eleganckie.
- użycie gitowych submodułów - byłoby świetne, gdyby Neo4j było napisane w .NET. Jednak nie jest i nie chciałbym zmuszać osób pracujących nad projektem do kompilowania tego podprojektu w Javie. Zakładam, że projektem będą zainteresowani .NETowcy więc uczenie ich całego toolingu Javy nie ma tu sensu.
-
Paket - ponieważ oczywiście nie ma Nugeta zawierającego binarki Neo4j, mogę użyć coś podobnego.
Paket to takie rozszerzenie Nugeta, napisane nomen omen w F# i dzięki temu dość popularne w tym środowisku. Paket poza źródłami z serwerów Nugetowych potrafi korzystać ze źródeł Gita oraz po prostu HTTP. Dzięki temu można zaciągnąć nim do projektu pojedyncze pliki z innych repozytoriów GitHuba. Albo plików wystawionych w internecie. I tak też uczynię, ponieważ Neo4j jest dostępny w samowystarczalnym pliku ZIP pod adresem
http://neo4j.com/download-thanks/?edition=community&flavour=winzip.
To oczywiście sprawi, że w chwili gdy Neo4j wystawi ten plik pod innym adresem - projekt przestanie uruchamiać się ze źródeł. Jednak nie spodziewam się, by było to częste. Poza tym - zdecydowana większość przyszłych użytkowników po prostu ściągnie gotową binarkę, a nie będzie kompilować ją ze źródeł.
Zatem Paket, o którym napiszę w kolejnej części, załatwi mi ściąganie dystrybucji Neo4j. Oraz poprzez Nuget ściągnie bibliotekę Neo4jClient, o której kilka słów również w kolejnej części – odpowiadającej za obudowanie RESTowego API po stronie .NET.