1 module layout2dot; 2 import sqlited; 3 import utils; 4 import std.conv : to; 5 import misc; 6 7 string TreeLayoutToDot(Database db) { 8 string result = "digraph table {"; 9 10 Database.MasterTableSchema[] schemas; 11 schemas = readRows!(r => r.deserialize!(Database.MasterTableSchema))(db.rootPage, 12 db.pages); 13 result ~= TreeLayoutToDot(db.rootPage, db.pages, 1); 14 foreach (schema; schemas) { 15 if (schema.rootPage) { 16 result ~= "\n" ~ "\"Root\"" ~ " -> " ~ '"' ~ toQuotedString(schema.rootPage) ~ '"' ~ "\n"; 17 result ~= TreeLayoutToDot(db.pages[schema.rootPage - 1], db.pages, schema.rootPage) ~ "\n"; 18 } 19 } 20 21 return result ~ "}\n"; 22 } 23 24 string toQuotedString(uint i) { 25 return "\"" ~ to!string(i) ~ "\""; 26 } 27 28 string TreeLayoutToDot(Database.BTreePage page, Database.PageRange pages, uint rootPage) { 29 string pref = "\n" ~ toQuotedString(rootPage) ~ " -> "; 30 string result; 31 auto cpa = page.getCellPointerArray(); 32 33 switch (page.pageType) { 34 case Database.BTreePageType.tableInteriorPage: { 35 foreach (cp; cpa) { 36 uint nextPage = BigEndian!uint(page.page[cp .. cp + uint.sizeof]); 37 result ~= pref ~ toQuotedString(nextPage); 38 result ~= TreeLayoutToDot(pages[nextPage - 1], pages, nextPage); 39 } 40 41 uint nextPage = page.header._rightmostPointer; 42 result ~= pref ~ toQuotedString(nextPage); 43 result ~= TreeLayoutToDot(pages[nextPage - 1], pages, nextPage); 44 } 45 break; 46 case Database.BTreePageType.tableLeafPage: { 47 48 } 49 break; 50 default: { 51 } 52 53 } 54 return result; 55 }