コード例 #1
0
 public MetaField(BinaryReaderCRC32 rdr)
 {
     IsStorage = rdr.ReadBoolean();
     Name      = rdr.ReadString();
     Size      = rdr.ReadInt32();
     Offset    = rdr.ReadInt32();
 }
コード例 #2
0
            public MetaDataBase(BinaryReaderCRC32 rdr)
            {
                Type     = rdr.ReadInt32();
                Time     = new DateTime(rdr.ReadInt64());
                Version  = rdr.ReadInt32();
                Major    = rdr.ReadInt32();
                Minor    = rdr.ReadInt32();
                Build    = rdr.ReadInt32();
                Revision = rdr.ReadInt32();
                Count    = rdr.ReadInt32();

                rdr.Stream.Position = 1024;

                IsValid = rdr.ReadCheckResetCRC();

                var version = Assembly.GetCallingAssembly().GetName().Version;

                if (version.Major != Major || version.Minor != Minor || version.Build != Build || version.Revision != Revision)
                {
                    IsCodeEqual = false;
                }
                else
                {
                    IsCodeEqual = true;
                }

                if (IsValid)
                {
                    list = new List <MetaTable>(Count);

                    for (var i = 0; i < Count; ++i)
                    {
                        list.Add(new MetaTable(rdr));
                    }

                    // Конвертируем относительные адреса таблиц записей в абсолютные адреса.
                    for (var i = 0; i < Count; ++i)
                    {
                        list[i].Offset += rdr.Stream.Position;
                    }
                }
            }
コード例 #3
0
            public MetaTable(BinaryReaderCRC32 rdr)
            {
                Count      = rdr.ReadInt32();
                Offset     = rdr.ReadInt32();
                Key        = rdr.ReadString();
                Version    = rdr.ReadInt32();
                RecordSize = rdr.ReadInt32();
                Mode       = (PageFileIOMode)rdr.ReadInt32();
                HasStorage = rdr.ReadBoolean();

                var c = rdr.ReadInt32();

                Fields = new List <MetaField>();

                for (var j = 0; j < c; ++j)
                {
                    Fields.Add(new MetaField(rdr));
                }

                IsValid = rdr.ReadCheckResetCRC();
            }
コード例 #4
0
            // Восстановление таблицы из бекапа
            internal bool RestoreTable(ITable itm, ArrayStorage storage, BinaryReaderCRC32 sm, FileStream sd, Log log)
            {
                if (sm.Stream.Position != Offset)
                {
                    sm.Stream.Position = Offset;
                }

                //Debug.WriteLine("Restore " + itm.Key);

                itm.File.SetCount(Count);

                var flag   = true;
                var wtr    = itm.File.CreateStream();
                var sd_br  = new BinaryReader(sd);
                var crc    = new CRC32();
                var crcerr = 0;
                var hasCRC = (itm.CurrentVersion.Mode & PageFileIOMode.CRC32) == PageFileIOMode.CRC32;
                var size   = RecordSize;

                if (!hasCRC)
                {
                    size += size_crc;
                }

                var buf  = new byte[size];
                var list = new List <byte[]>();

                try
                {
                    if (itm.Key == "Users")
                    {
                        int bp = 0;
                    }

                    var sw = Stopwatch.StartNew();

                    //if (itm.Key == "Regions")
                    //{
                    //    int bp = 0;
                    //}

                    // Если есть массивыв переменной длинны
                    if (HasStorage)
                    {
                        // i + 1 - это код
                        for (var i = 0; i < Count; ++i)
                        {
                            var offset = sm.ReadInt64();

                            //Debug.WriteLine("Restore " + itm.Key + ", code: " + (i + 1) + ", offset:" + offset);

                            if (i + 1 == 1350685)
                            {
                                var bp = 0;
                            }

                            if (sd.Position != offset)
                            {
                                sd.Position = offset;
                            }

                            var time = sd_br.ReadInt64();

                            // Проверяем на удаление
                            if (time < 0)
                            {
                                itm.File.deleted.Push(i + 1);

                                continue;
                            }
                            else
                            {
                                // обновляем crc времени
                                crc.Update(time);
                            }

                            list.Clear();

                            // Считаем CRC
                            for (var j = 0; j < Fields.Count; ++j)
                            {
                                var fld = Fields[j];

                                if (fld.IsStorage)
                                {
                                    //Debug.WriteLine("Restore " + itm.Key + ", code: " + (i + 1) + ", field: " + fld.Name + " pos: " + sd.Position);

                                    var len = sd_br.ReadInt32();
                                    var tmp = new byte[len];

                                    sd.Read(tmp, 0, len);

                                    crc.Update(len);
                                    crc.Update(tmp, 0, tmp.Length);

                                    list.Add(tmp);
                                }
                                else
                                {
                                    var off = fld.Offset;

                                    switch (fld.Size)
                                    {
                                    case 1:
                                    {
                                        var val = sd_br.ReadByte();

                                        buf[off] = val;

                                        crc.Update(val);

                                        break;
                                    }

                                    case 2:
                                    {
                                        var val = sd_br.ReadChar();

                                        fixed(byte *ptr = &buf[off])
                                        {
                                            var tmp = (char *)ptr;

                                            *tmp = val;
                                        }

                                        crc.Update(val);

                                        break;
                                    }

                                    case 4:
                                    {
                                        var val = sd_br.ReadUInt32();

                                        fixed(byte *ptr = &buf[off])
                                        {
                                            var tmp = (uint *)ptr;

                                            *tmp = val;
                                        }

                                        crc.Update(val);

                                        break;
                                    }

                                    case 8:
                                    {
                                        var val = sd_br.ReadUInt64();

                                        fixed(byte *ptr = &buf[off])
                                        {
                                            var tmp = (ulong *)ptr;

                                            *tmp = val;
                                        }

                                        crc.Update(val);

                                        break;
                                    }

                                    case 16:
                                    {
                                        var val = sd_br.ReadDecimal();

                                        fixed(byte *ptr = &buf[off])
                                        {
                                            var tmp = (decimal *)ptr;

                                            *tmp = val;
                                        }

                                        crc.Update(val);

                                        break;
                                    }
                                    }
                                }
                            }

                            // Проверяем crc массивов
                            var crc2 = sd_br.ReadInt32();

                            if (crc.Value != crc2)
                            {
                                flag = false;

                                crc.Reset();

                                crcerr++;

                                if (crcerr < 10)
                                {
                                    log.Append("Record code: " + (i + 1) + " error crc32 array check.\r\n");
                                }

                                continue;
                            }

                            // Записываем массивы
                            var n = 0;

                            for (var j = 0; j < Fields.Count; ++j)
                            {
                                var fld = Fields[j];

                                if (fld.IsStorage)
                                {
                                    var tmp = list[n++];
                                    var key = storage.WriteBuffer(0, tmp);

                                    fixed(byte *b = &buf[fld.Offset])
                                    {
                                        var ptr = (long *)b;

                                        *ptr = key;
                                    }

                                    //if (itm.Key == "Users" && i == 0 && fld.Name == "Awatar")
                                    //{
                                    //    DataBase.TestKey = key;
                                    //    DataBase.TestString = System.Text.Encoding.Unicode.GetString(tmp);
                                    //}
                                }
                            }

                            var wtr_offset = PageFile.HeaderSize + (i + 1) * itm.CurrentVersion.RecordSize;

                            //Debug.WriteLine("Write pos: " + wtr_offset);

                            // Устанавливаем позицию
                            if (wtr.Position != wtr_offset)
                            {
                                wtr.Position = wtr_offset;
                            }

                            // Записываем запись
                            if (hasCRC)
                            {
                                crc.Reset();

                                fixed(byte *ptr = &buf[size - size_time_crc])
                                {
                                    var tmp = (long *)ptr;

                                    *tmp = time;
                                }

                                crc.Update(buf, 0, size - size_crc);

                                fixed(byte *ptr = &buf[size - size_crc])
                                {
                                    var tmp = (int *)ptr;

                                    *tmp = crc.Value;
                                }

                                // Данные, время и CRC
                                wtr.Write(buf, 0, size);
                            }
                            else
                            {
                                fixed(byte *ptr = &buf[size - size_time_crc])
                                {
                                    var tmp = (long *)ptr;

                                    *tmp = time;
                                }

                                // Данные и время
                                wtr.Write(buf, size_time, size - size_crc);
                            }

                            crc.Reset();

                            //if (i > 0 && i%100000 == 0)
                            //{
                            //    log.Append("Progresss : ", i, "\r\n");
                            //}
                            if (sw.ElapsedMilliseconds >= 1000)
                            {
                                log.Append("Progresss : ", i, ", ", (i * 100) / Count, "% \r\n");

                                sw.Restart();
                            }
                        }
                    }
                    else
                    {
                        for (var i = 0; i < Count; ++i)
                        {
                            if (i + 1 == 1350685)
                            {
                                var bp = 0;
                            }

                            var offset = sm.ReadInt64();

                            //Debug.WriteLine("Restore " + itm.Key + ", code: " + (i + 1) + ", offset:" + offset);

                            if (sd.Position != offset)
                            {
                                sd.Position = offset;
                            }

                            // Читаем запись
                            sd.Read(buf, 0, size);

                            // Проверяем на удаление
                            fixed(byte *b = &buf[0])
                            {
                                var ptr = (long *)b;

                                if (*ptr < 0)
                                {
                                    itm.File.deleted.Push(i + 1);

                                    continue;
                                }
                                else
                                {
                                    // обновляем crc времени
                                    crc.Update(*ptr);
                                }
                            }

                            // обновляем crc данных
                            crc.Update(buf, size_time, size - size_time_crc);

                            // Проверяем crc данных
                            fixed(byte *b = &buf[size - size_crc])
                            {
                                var ptr = (int *)b;

                                if (crc.Value != *ptr)
                                {
                                    flag = false;

                                    crc.Reset();

                                    crcerr++;

                                    if (crcerr < 10)
                                    {
                                        log.Append("Record code: " + (i + 1) + " error crc32 data check.\r\n");
                                    }

                                    continue;
                                }
                            }

                            var wtr_offset = PageFile.HeaderSize + (i + 1) * itm.CurrentVersion.RecordSize;

                            // Устанавливаем позицию записи
                            if (wtr.Position != wtr_offset)
                            {
                                wtr.Position = wtr_offset;
                            }

                            // Записываем запись
                            if (hasCRC)
                            {
                                // Пересчитываем crc под формат бд
                                crc.Reset();
                                crc.Update(buf, size_time, size - size_time_crc);
                                crc.Update(buf, 0, size_time);

                                fixed(byte *ptr = &buf[size - size_crc])
                                {
                                    var tmp = (int *)ptr;

                                    *tmp = crc.Value;
                                }

                                // Данные
                                wtr.Write(buf, size_time, size - size_time_crc);
                                // Время
                                wtr.Write(buf, 0, size_time);
                                // CRC
                                wtr.Write(buf, size - size_crc, size_crc);
                            }
                            else
                            {
                                // Данные
                                wtr.Write(buf, size_time, size - size_time_crc);
                                // Время
                                wtr.Write(buf, 0, size_time);
                            }

                            crc.Reset();

                            //if (i > 0 && i%100000 == 0)
                            //{
                            //    log.Append("Progresss : ", i, "\r\n");
                            //}
                            if (sw.ElapsedMilliseconds >= 1000)
                            {
                                log.Append("Progresss : ", i, ", ", (i * 100) / Count, "% \r\n");

                                sw.Restart();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    log.Append("Exception: ");
                    log.Append(ex.Message);
                }
                finally
                {
                    wtr.Flush();
                    wtr.Close();
                }

                return(flag);
            }
コード例 #5
0
        // Функция восстанавливает базу из бекапа
        public bool Restore(string path, Log log)
        {
            var flag         = true;
            var not_critical = true;

            FileStream stream_meta = null;
            FileStream stream_data = null;

            try
            {
                var dt = DateTime.Now;

                log.Append("Restore begin at ");
                log.Append(dt.ToString("F"));
                log.Append("\r\n");

                stream_meta = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                stream_data = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);

                var sm = new BinaryReaderCRC32(stream_meta);
                var db = new MetaDataBase(sm);

                if (!db.IsValid)
                {
                    log.Append("Backup header corrupt. CRC32 Fail.");

                    return(false);
                }

                // Очищаем хранилище массивов
                DB.Storage.Clear();

                // Восстановление таблиц
                for (var i = 0; i < db.Count; ++i)
                {
                    var itm = db[i];

                    if (itm.IsValid)
                    {
                        var tbl = DB.GetTableByKey(itm.Key);

                        if (tbl == null)
                        {
                            log.AppendLine("Table " + itm.Key + " not found in current version database.");

                            continue;
                        }

                        log.AppendLine("Restore table " + tbl.Key);

                        var tf = itm.RestoreTable(tbl, DB.Storage, sm, stream_data, log);

                        log.AppendLine(tf ? " Done" : " Fail");

                        flag &= tf;
                    }
                    else
                    {
                        var key = itm.Key.Length < 256 ? itm.Key : itm.Key.Substring(0, 256);

                        log.Append("Table " + key + " header corrupt. CRC32 Fail.");
                    }
                }
            }
            catch (Exception e)
            {
                flag         = false;
                not_critical = false;

                log.Append(e);
            }
            finally
            {
                if (stream_meta != null)
                {
                    stream_meta.Flush();
                    stream_meta.Close();
                }

                if (stream_data != null)
                {
                    stream_data.Flush();
                    stream_data.Close();
                }
            }

            log.Append("\r\n");

            if (flag)
            {
                log.Append("Restore DONE\r\n");
            }
            else
            {
                log.Append("Restore FAIL\r\n");
            }

            return(not_critical && flag);
        }