قاعدة بيانات الإصدار في التطبيقات المثبتة باستخدام دلفي

StackOverflow https://stackoverflow.com/questions/1804464

سؤال

أنا أعمل على عدد من تطبيقات دلفي التي سوف تحتاج إلى ترقية قاعدة البيانات الخاصة بهم الهياكل في الميدان عندما يتم إطلاق إصدارات جديدة و عندما للمستخدمين اختيار تثبيت وحدات إضافية.التطبيقات باستخدام مجموعة متنوعة من جزءا لا يتجزأ من قواعد البيانات (DBISAM طائرة حاليا ، ولكن هذا قد تغير).

في الماضي لقد فعلت هذا مع DBISAM باستخدام أرقام إصدار من يمكن تخزينها مع كل جدول.أنا شحنت إضافية فارغة مجموعة من ملفات قاعدة البيانات ، في البدء ، مقارنة أرقام إصدارات من كل جدول باستخدام FieldDefs لتحديث تثبيت الجدول إذا لزم الأمر.في حين عملت وجدت أنه أخرق أن السفينة نسخة إحتياطية من قاعدة البيانات والإصدارات الأحدث من DBISAM غيرت الجدول إعادة هيكلة منهجية بحيث سوف تحتاج إلى كتابة هذا على أي حال.

أنا أرى طريقتين لتنفيذ هذا:تخزين رقم الإصدار مع قاعدة البيانات باستخدام DDL النصوص من الإصدارات القديمة إلى أحدث الإصدارات أو تخزين مرجع نسخة من هيكل قاعدة البيانات داخل التطبيق ، مقارنة الإشارة إلى قاعدة البيانات على البدء ، وبعد تطبيق توليد DDL الأوامر ترقية قاعدة البيانات.

أعتقد أنني يجب أن تنفذ أجزاء سواء.لن تريد تطبيق مهرجان دبي السينمائي الدولي في قاعدة البيانات ضد المرجعية هيكل في كل مرة بدء تشغيل التطبيق (بطيء جدا), لذلك سوف تحتاج إلى بنية قاعدة البيانات رقم الإصدار إلى الكشف عن ما إذا كان المستخدم يستخدم قديمة هيكل.إلا أنني لست متأكدا من أنني يمكن أن تثق قبل كتابة البرامج النصية للقيام الهيكلية الترقية عندما تكون قاعدة البيانات قد تم تحديثها جزئيا في الماضي أو عندما قد يكون لدى المستخدم أنفسهم تغير هيكل قاعدة البيانات ، لذلك أنا أميل إلى استخدام إشارة مهرجان دبي السينمائي الدولي عن التحديث الفعلي.

البحث عن السؤال لقد وجدت اثنين من قاعدة بيانات الإصدار الأدوات ولكن يبدو أنهم جميعا تستهدف SQL Server يتم تنفيذها خارج التطبيق الفعلي.أنا أبحث عن عملية من شأنها أن تكون متكاملة في تطبيق التي يمكن أن تتكيف مع مختلف متطلبات قاعدة البيانات (وأنا أعلم أنني سوف تضطر إلى كتابة محولات مخصص سليل الطبقات ، أو رمز الحدث إلى التعامل مع الخلافات في DDL على قواعد البيانات المختلفة ، هذا لا يزعجني).

لا أحد يعرف من أي شيء من على الرف أن يفعل ذلك أو إذا تعذر ذلك ، هل من أحد لديه أي أفكار حول:

  1. أفضل طريقة لتخزين إشارة إصدار عام العلائقية بنية قاعدة البيانات داخل التطبيق.

  2. أفضل طريقة الفرق المرجعية ضد قاعدة البيانات الفعلية.

  3. أفضل طريقة لتوليد DDL تحديث قاعدة البيانات الخاصة بنا.

هل كانت مفيدة؟

المحلول

لدي بلوق وظيفة هنا عن كيف أفعل dbisam قاعدة بيانات الإصدار و sql server.

الأجزاء الهامة هي:

لأن dbisam لا يدعم وجهات النظر ، يتم تخزين رقم إصدار (جنبا إلى جنب مع مجموعة أخرى من المعلومات) في ini الملف في قاعدة بيانات الدليل.

لدي datamodule, TdmodCheckDatabase.هذا وقد TdbisamTable مكون لكل الجدول في قاعدة البيانات.الجدول مكون يحتوي على كافة الحقول في الجدول ، يتم تحديثها كلما الجدول تغيرت.

لجعل التغييرات على قاعدة البيانات ، بعد العملية تم استخدامها:

  1. زيادة رقم الإصدار في التطبيق
  2. إجراء اختبار DB التغييرات.
  3. تحديث الجداول المتأثرة في TdmodCheckDatabase
  4. إذا لزم الأمر (نادرا) إضافة مزيد من الترقية الاستفسارات TdmodCheckDatabase.E. g.تعيين قيم حقول جديدة أو إضافة جديدة بيانات الصفوف.
  5. توليد CreateDatabase وحدة النصي باستخدام تزويد قاعدة البيانات أدوات.
  6. تحديث وحدة الاختبارات التي تتناسب مع ديسيبل

عند تشغيل التطبيق ، فإنه يذهب من خلال العملية التالية

  1. إذا لا توجد قاعدة بيانات وجدت ، ثم تشغيل CreateDatabase الوحدة ومن ثم القيام الخطوة 3
  2. الحصول على رقم الإصدار الحالي من قاعدة البيانات ini
  3. إذا كان أقل من المتوقع رقم الإصدار ثم تشغيل CreateDatabase (لخلق أي جداول جديدة) التحقق من كل عنصر في الجدول TdmodCheckDatabase تطبيق أي جدول التغيرات تشغيل أي دليل البرامج النصية الترقية
  4. تحديث رقم الإصدار في قاعدة البيانات ini

مدونة العينة

class procedure TdmodCheckDatabase.UpgradeDatabase(databasePath: string; currentVersion, newVersion: integer);
var
module: TdmodCheckDatabase;
f: integer;
begin
module:= TdmodCheckDatabase.create(nil);
try
  module.OpenDatabase( databasePath );

  for f:= 0 to module.ComponentCount -1  do
  begin
    if module.Components[f] is TDBISAMTable then
    begin
      try
        // if we need to upgrade table to dbisam 4
        if currentVersion <= DB_VERSION_FOR_DBISAM4 then
          TDBISAMTable(module.Components[f]).UpgradeTable;

        module.UpgradeTable(TDBISAMTable(module.Components[f]));
      except
       // logging and error stuff removed
      end;
    end;
  end;

  for f:= currentVersion + 1 to newVersion do
    module.RunUpgradeScripts(f);

  module.sqlMakeIndexes.ExecSQL; // have to create additional indexes manually
 finally
  module.DBISAMDatabase1.Close;
  module.free;
end;
end;


procedure TdmodCheckDatabase.UpgradeTable(table: TDBISAMTable);
var
 fieldIndex: integer;
 needsRestructure: boolean;
 canonical: TField;
begin
 needsRestructure:= false;

 table.FieldDefs.Update;

 // add any new fields to the FieldDefs
 if table.FieldDefs.Count < table.FieldCount then
 begin
   for fieldIndex := table.FieldDefs.Count to table.Fields.Count -1 do
   begin
     table.FieldDefs.Add(fieldIndex + 1, table.Fields[fieldIndex].FieldName, table.Fields[fieldIndex].DataType, table.Fields[fieldIndex].Size, table.Fields[fieldIndex].Required);
   end;
   needsRestructure:= true;
 end;

 // make sure we have correct size for string fields
 for fieldIndex := 0 to table.FieldDefs.Count -1 do
 begin
   if (table.FieldDefs[fieldIndex].DataType = ftString) then
   begin
     canonical:= table.FindField(table.FieldDefs[fieldIndex].Name);
     if assigned(canonical) and (table.FieldDefs[fieldIndex].Size <> canonical.Size) then
   begin
     // field size has changed
     needsRestructure:= true;
     table.FieldDefs[fieldIndex].Size:= canonical.Size;
   end;
   end;
 end;

 if needsRestructure then
   table.AlterTable(); // upgrades table using the new FieldDef values
end;

procedure TdmodCheckDatabase.RunUpgradeScripts(newVersion: integer);
begin
 case newVersion of
   3: sqlVersion3.ExecSQL;
   9: sqlVersion9.ExecSQL;
   11: begin  // change to DBISAM 4
         sqlVersion11a.ExecSQL;
         sqlVersion11b.ExecSQL;
         sqlVersion11c.ExecSQL;
         sqlVersion11d.ExecSQL;
         sqlVersion11e.ExecSQL;
       end;
   19: sqlVersion19.ExecSQL;
   20: sqlVersion20.ExecSQL;
 end;
end;

نصائح أخرى

قصة مشابهة هنا.نحن متجر DB رقم الإصدار في "النظام" الجدول وتحقق ذلك على بدء التشغيل.(إذا كان الجدول/الميداني/القيمة غير موجودة ثم نحن نعرف انها نسخة 0 أين نحن نسيت أن أضيف أن بعض!)

خلال التنمية و عندما كنا في حاجة إلى ترقية قاعدة البيانات نكتب DDL النصي للقيام بهذا العمل مرة واحدة سعداء بأن هذا العمل موافق يحصل إضافة مورد النص إلى التطبيق.

عند التطبيق يحدد أنه يحتاج إلى ترقية تحميل المورد المناسب(ق) و يعمل عليه/عليها.إذا كان يحتاج إلى ترقية العديد من الإصدارات يجب تشغيل كل برنامج نصي في النظام.تبين أن فقط بضعة أسطر من التعليمات البرمجية في نهاية المطاف.

النقطة الرئيسية أن بدلا من استخدام واجهة المستخدم الرسومية القائمة على أدوات لتعديل الجداول في مخصص أو "عشوائية" الطريقة نكتب في الواقع DDL على الفور.هذا يجعل من الاسهل بكثير, عندما يحين الوقت لبناء الكامل ترقية البرنامج النصي.وهيكل مهرجان دبي السينمائي الدولي فرض ليس مطلوبا.

أنا باستخدام ADO لبلدي قواعد البيانات.أود أيضا أن استخدام الإصدار رقم المخطط ، ولكن فقط كما التعقل الاختيار.لدي برنامج أنا وضعت والذي يستخدم اتصال.GetTableNames والاتصال.GetFieldNames لتحديد أي تعارض ضد مستند XML التي تصف "سيد" قاعدة البيانات الخاصة بنا.إذا كان هناك اختلاف ، ثم بناء المناسبة SQL لإنشاء الحقول المفقودة.لم أكن قطرة إضافية منها.

ثم يكون dbpatch الجدول الذي يحتوي على قائمة من البقع التي حددها اسم فريد.إذا كان هناك بقع محددة في عداد المفقودين ، ثم يتم تطبيق السجل المناسب إضافة إلى dbpatch الجدول.في أغلب الأحيان هذا هو الجديد المخزنة procs أو مجال تغيير حجم أو مؤشرات

أنا أيضا الحفاظ على مين-db-الإصدار, الذي هو أيضا فحص منذ أن تسمح للمستخدمين استخدام نسخة قديمة من العميل ، أنا فقط تسمح لهم استخدام الإصدار >= min-db-الإصدار ، <= cur-db-الإصدار.

ما أقوم به هو تخزين رقم الإصدار في قاعدة البيانات و رقم الإصدار في التطبيق.في كل مرة كنت بحاجة إلى تغيير بنية قاعدة البيانات, إنشاء بعض التعليمات البرمجية تحديث هيكل قاعدة البيانات ، و زيادة رقم الإصدار في التطبيق.عند بدء تشغيل التطبيق ، فإنه يقارن, أرقام, و إذا كان يجب أن يعمل بعض التعليمات البرمجية إلى تحديث بنية قاعدة البيانات و تحديث قاعدة البيانات رقم الإصدار.وبالتالي فإن قاعدة البيانات الآن ما يصل إلى موعد مع التطبيق.قانون بلدي هو شيء من هذا القبيل

if DBVersion < AppVersion then
begin
  for i := DBVersion+1 to AppVersion do
    UpdateStructure(i);
end
else
  if DBVersion > AppVersion then
    raise EWrongVersion.Create('Wrong application for this database');

UpdateStructure فقط تشغيل التعليمات البرمجية الضرورية شيئا مثل :

procedure UpdateStructure(const aVersion : Integer);
begin
  case aVersion of
    1 : //some db code
    2 : //some more db code
    ...
    ...
  end;
  UpdateDatabaseVersion(aVersion);
end;  

يمكنك فعلا استخدام نفس رمز لإنشاء قاعدة بيانات من الصفر

CreateDatabase;
for i := 1 to AppVersion do
  UpdateStructure(i);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top