{"id":1571,"date":"2011-03-29T22:27:56","date_gmt":"2011-03-29T21:27:56","guid":{"rendered":"http:\/\/www.gamlor.info\/wordpress\/?p=1571"},"modified":"2022-12-11T17:14:54","modified_gmt":"2022-12-11T16:14:54","slug":"making-db4o-linqpad-meta-data","status":"publish","type":"post","link":"https:\/\/www.gamlor.info\/wordpress\/2011\/03\/making-db4o-linqpad-meta-data\/","title":{"rendered":"Making of the db4o LINQPad Driver: Meta-Data"},"content":{"rendered":"<div id=\"attachment_1572\" style=\"width: 310px\" class=\"wp-caption alignright\"><a href=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/03\/meta-data.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-1572\" class=\"size-medium wp-image-1572\" title=\"meta-data\" src=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/03\/meta-data-300x244.png\" alt=\"Meta-Data\" width=\"300\" height=\"244\" srcset=\"https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/03\/meta-data-300x244.png 300w, https:\/\/www.gamlor.info\/wordpress\/wp-content\/uploads\/2011\/03\/meta-data.png 900w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-1572\" class=\"wp-caption-text\">Meta-Data<\/p><\/div>\n<p>This time I\u2019m going to look at the meta-data required for the db4o driver. First I\u2019m showing how to get the meta-data from db4o. Then I explain some internal details of the driver internal representation of this information.<\/p>\n<p>&nbsp;<\/p>\n<p>Side note: I\u2019ve integrated lots of improvements <a href=\"https:\/\/www.gamlor.info\/files\/db4oPad.lpx\">into the driver<\/a>. It now should work with (one dimensional) arrays and auto-properties. Furthermore you can optionally add the assemblies with the original classes.<\/p>\n<h2>Getting Meta-Data from db4o<\/h2>\n<p>The first step is to get the meta-data from the database. Most databases allow you to retrieve information about the stored data. In relational database there\u2019s a system table which contain a description of all tables, views, constrains etc. db4o has an API to get this information. There are two main ways to get information about the stored data in db4o: The <a href=\"http:\/\/developer.db4o.com\/Documentation\/Reference\/db4o-8.0\/net35\/reference\/Content\/advanced_topics\/db4o_meta-information.htm\">stored classes and the known classes API<\/a>.<\/p>\n<p>What\u2019s the difference between the stored classes and known classes? First only returns information about objects which are actually stored in the database. The second also contains information about classes which are otherwise known to db4o. Furthermore the stored classes information is a very low level and minimalistic. The known classes information is much richer. Also db4o used the information from the actual type if it can find it.<\/p>\n<p>I use the known classes API to get the information I need:<\/p>\n<script src=\"https:\/\/gist.github.com\/893226.js?file=db4oMeta.cs\"><\/script><noscript><pre><code class=\"language-c# c#\">using (var db = Db4oEmbedded.OpenFile(&quot;databaseWithArrayFields.db4o&quot;))\n{\n\tvar metaData = db.Ext().KnownClasses();\n\t\/\/ process the data\n\tforeach (var aClass in metaData)\n\t{\n\t\t\/\/ analyse the class\n\t\tvar fields = aClass.GetDeclaredFields();\n\t\tforeach (var aField in fields)\n\t\t{\n\t\t\t\/\/ analyse the field\n\t\t\t\/\/ ..\n\t\t}\n\t}\n}  <\/code><\/pre><\/noscript>\n<h2>Converting to Driver Internal Representation<\/h2>\n<p>The first step which I do is to convert the meta data the an internal representation. Why do I want to do that? The db4o driver cares about different things than db4o does. Therefore I want to have a representation which fulfills the drivers need. For example the driver needs to know if it knows the native type or if it needs to generate a class. On the other hand the driver doesn\u2019t care about reflection abstractions, since that is done by LINQPad itself. Also it\u2019s more handy to write tests with an internal representation which fits its needs.<\/p>\n<p>Currently the implementation has three internal representation of a type. The first one it the \u2018known\u2019 type. That is when the driver was able to find original type, either because it\u2019s a .NET type or because the user supplied the assemblies. The second type is the \u2018simple\u2019 class description, which represents types which couldn\u2019t be found. That means we need to generate a replacement for it. The last one is the array type, which describes an array.<\/p>\n<h2>Parsing Type-Names<\/h2>\n<p>Another strange thing the driver does: It parses the type names. Why is that necessary? db4o encodes the assembly and generics information into type-name, something like the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.type.assemblyqualifiedname.aspx\">AssemblyQualifiedName<\/a> of .NET types. With that name db4o then can find the original type when loading data from the database. Unfortunately the parse and resolve logic is deeply embedded in db4o and isn\u2019t supposed to be a public API. That\u2019s why I implemented my own type-name parser. For that I used the <a href=\"http:\/\/code.google.com\/p\/sprache\/\">wonderful \u2018Sprache\u2019 library<\/a>. It allows me to use LINQ to describe a parser. It\u2019s perfect for stuff where regular expressions are not powerful enough and you need a tiny parser. Take a look at this <a href=\"http:\/\/nblumhardt.com\/2010\/01\/building-an-external-dsl-in-c\/\">blog-post for an introduction<\/a>.<\/p>\n<p>By the way: Currently I parse the type-names correctly to find out the generic arguments etc. However in the further processing generics aren\u2019t properly handled. Some cases work, other will lead to crashes.<\/p>\n<h2>Ready to Generate Types<\/h2>\n<p>So the LINQPad driver extracts meta-data from the database and then converts it to an internal representation. After that the driver is ready to generate the types and query-context required for LINQ-queries. But that\u2019s the content of the next post =)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This time I\u2019m going to look at the meta-data required for the db4o driver. First I\u2019m showing how to get the meta-data from db4o. Then I explain some internal details&hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[126,150],"tags":[100,214],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1571"}],"collection":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/comments?post=1571"}],"version-history":[{"count":8,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1571\/revisions"}],"predecessor-version":[{"id":3939,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/posts\/1571\/revisions\/3939"}],"wp:attachment":[{"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/media?parent=1571"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/categories?post=1571"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gamlor.info\/wordpress\/wp-json\/wp\/v2\/tags?post=1571"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}