Пример #1
0
        static void Main(string[] args)
        {
            var fileName = args.Length > 0 ? args[0] : "default.realm";

            using (var mmf = MemoryMappedFile.CreateFromFile(fileName, FileMode.Open, null, 0, MemoryMappedFileAccess.Read))
                using (var accessor = mmf.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read))
                {
                    var header = RealmFileHeader.ReadFrom(accessor);

                    Console.WriteLine("File Format Version: {0}", header.GetTopRef().FileFormatVersion);

                    // ファイル内では、 ref の値はそのまま使える(追加でアロケーションすると話は別)
                    var topArray = new RealmArray(new ReferenceAccessor(accessor, header.GetTopRef().Ref));

                    Console.WriteLine("Top Array Count: {0}", topArray.Count);

                    // HasRefs な Array に数値が入っているので、最下位ビットが 1 になっている
                    // ビットシフトで元の値が手に入る
                    Console.WriteLine("Logical File Size: {0}", (ulong)topArray[2] >> 1);

                    // 配列の 1 番目がテーブル名リスト
                    var tableNameArray = new RealmArrayString(new ReferenceAccessor(accessor, (ulong)topArray[0]), false);

                    // 2 番目がテーブルのリスト
                    var tableArray = new RealmArray(new ReferenceAccessor(accessor, (ulong)topArray[1]));

                    Console.WriteLine();
                    Console.WriteLine("Tables");
                    for (var i = 0; i < tableNameArray.Count; i++)
                    {
                        var table = new RealmTable(new ReferenceAccessor(accessor, (ulong)tableArray[i]));
                        Console.WriteLine(" - {0} (Count: {1})", tableNameArray[i], table.RowCount);
                        PrintTableSpec(table.Spec, tableNameArray, GetBacklinkTarget, 2);
                    }

                    Console.WriteLine();
                    Console.WriteLine("Contents");
                    for (var i = 0; i < tableNameArray.Count; i++)
                    {
                        var table = new RealmTable(new ReferenceAccessor(accessor, (ulong)tableArray[i]));
                        Console.WriteLine(" - {0} ({1}/{2})", tableNameArray[i], Math.Min(table.RowCount, PrintCount), table.RowCount);
                        PrintTableContent(table, GetBacklinkTarget, 2);
                    }

                    string GetBacklinkTarget(int tableIndex, int columnIndex)
                    {
                        var targetTable      = new RealmTable(tableArray.Ref.NewRef((ulong)tableArray[tableIndex]));
                        var targetColumnName = targetTable.Spec.GetColumn(columnIndex).Name;

                        return(tableNameArray[tableIndex] + "." + targetColumnName);
                    }

                    Debugger.Break();
                }
        }
Пример #2
0
        public TableSpec(ReferenceAccessor @ref)
        {
            this.Ref = @ref;

            var specArray = new RealmArray(@ref);

            this._types = new RealmArray(@ref.NewRef((ulong)specArray[0]));
            this._names = new RealmArrayString(@ref.NewRef((ulong)specArray[1]), false);
            this._attr  = new RealmArray(@ref.NewRef((ulong)specArray[2]));

            if (specArray.Count >= 4)
            {
                var subspecsRef = (ulong)specArray[3];
                if (subspecsRef != 0)
                {
                    this._subspecs = new RealmArray(@ref.NewRef(subspecsRef));
                }
            }
        }
Пример #3
0
        public string GetString(int columnIndex, int rowIndex)
        {
            var spec     = this.Spec.GetColumn(columnIndex);
            var nullable = spec.Nullable;

            if (spec.Type == ColumnType.String)
            {
                var(leaf, indexInLeaf) = this.GetFromBpTree(columnIndex, rowIndex);

                var leafHeader  = new RealmArrayHeader(leaf);
                var longStrings = leafHeader.HasRefs;
                var isBig       = leafHeader.ContextFlag;

                string value;
                if (!longStrings)
                {
                    // 要素はすべて15バイト以下
                    // https://github.com/realm/realm-core/blob/v5.12.7/src/realm/column_string.cpp#L38-L39
                    value = new RealmArrayString(leaf, nullable)[indexInLeaf];
                }
                else if (!isBig)
                {
                    // 要素はすべて63バイト以下
                    value = new RealmArrayStringLong(leaf, nullable)[indexInLeaf];
                }
                else
                {
                    value = new RealmArrayBigBlobs(leaf).GetString(indexInLeaf);
                }

                return(value == null && !nullable ? "" : value);
            }
            else if (spec.Type == ColumnType.StringEnum)
            {
                // Table::optimize (各種言語バインディングからは未使用)で
                // 半分以上の値が重複している String カラムを圧縮したときに誕生する
                throw new NotImplementedException("StringEnum");
            }
            else
            {
                throw new InvalidOperationException($"このカラムの型は {spec.Type} です。");
            }
        }