Страница 9 из 10

Btrieve и clarion

Добавлено: 26 Сентябрь 2019, 13:41
morkovin
kreator писал(а): 26 Сентябрь 2019, 12:08 У вас классный междусобойчик! Как сделать,чтобы "Иванов Иван Иванович" (поле 1000 символов) был уникален.
Передёргиваешь! имхо, речь идёт о справочнике для выбора (Select-a). А в создаваемую запись будет вставляться уникальный код для уникальной записи "Иванов Иван Иванович" в справочнике.

Btrieve и clarion

Добавлено: 26 Сентябрь 2019, 15:56
kreator
morkovin писал(а): 26 Сентябрь 2019, 13:41
kreator писал(а): 26 Сентябрь 2019, 12:08 У вас классный междусобойчик! Как сделать,чтобы "Иванов Иван Иванович" (поле 1000 символов) был уникален.
Передёргиваешь! имхо, речь идёт о справочнике для выбора (Select-a). А в создаваемую запись будет вставляться уникальный код для уникальной записи "Иванов Иван Иванович" в справочнике.
Я имел ввиду сам справочник. У меня многие справочники с уникальностью по наименованию. Единицы измерения, например. Плохой пример, нет смысла отводить под это дело 1000 символов. И всё же.
Ладно, согласен, может и не особо жизненно.

Btrieve и clarion

Добавлено: 27 Сентябрь 2019, 1:57
porutchik
finsoftrz писал(а): 26 Сентябрь 2019, 12:20
kreator писал(а): 26 Сентябрь 2019, 12:08У вас классный междусобойчик! Как сделать,чтобы "Иванов Иван Иванович" (поле 1000 символов) был уникален.
1. Задача не из жизни.
2. Делаем второе поле для ключа по первым или последним символам (где предполагается уникальность), затем в процедурах модификации данных отбираем все записи с ними по ключу (их уже не должно быть много) и проверяем перебором на полное совпадение.
3. Делаем второе поле для ключа, сохраняем в него хэш.

Может еще какие варианты кому в голову придут.
вопрос стоял только в уникальности поля... я бы сделал поле с хэшем и по нему ключ, можно обработать в тригере

Btrieve и clarion

Добавлено: 30 Сентябрь 2019, 17:52
vic7tar
finsoftrz писал(а): 26 Сентябрь 2019, 12:203. ... Делаем второе поле для ключа, сохраняем в него хэш.
...
Не трудоёмко ли с хэшем потом будет работать?

Btrieve и clarion

Добавлено: 30 Сентябрь 2019, 19:27
finsoftrz
vic7tar писал(а): 30 Сентябрь 2019, 17:52
finsoftrz писал(а): 26 Сентябрь 2019, 12:203. ... Делаем второе поле для ключа, сохраняем в него хэш.
...
Не трудоёмко ли с хэшем потом будет работать?
Не знаю, не пробовал. По идее, не должно быть трудоемко. Для меня эта тема не актуальна, я вообще не вижу практического смысла делать уникальные текстовые поля, тем более на сотни байт. Ну, разве всякие guid, которые используют в системах с претензией на глобальность. Я там пошел по первому варианту с сохранением в ключе фрагмента и фильтрацией до полного значения. Максимальное значение, которое я встречал на практике - алкогольные марки длиной 150 символов.

Btrieve и clarion

Добавлено: 26 Октябрь 2019, 17:42
finsoftrz
Операции copy(File) и remove(File), у которых в качестве параметра задана файловая структура, не работают с таблицами, хранящимися в нескольких физических файлах. Хотя, судя по доке, должны.

Btrieve и clarion

Добавлено: 26 Октябрь 2019, 17:59
Игорь Столяров
Вроде бы это файловая функция.

COPY - Копирует файл.
файл - Метка оператора FILE, строковая константа или переменная, которые содержат спецификацию файла, который надлежит скопировать.

Никаких файлОВ, входящих в структуру таблицы и т.д.

Btrieve и clarion

Добавлено: 26 Октябрь 2019, 18:42
finsoftrz
Если это FILE, то логично было бы копировать все физические файлы, имена которых однозначно определяются. Конечно, все это решается написанием своей функции.

Btrieve и clarion

Добавлено: 27 Октябрь 2019, 7:49
Admin
Кусок кода, может чем поможет...

Код: Выделить всё

xDataBackupProClass.GetFileName      PROCEDURE(FILE FileName)
LOC:Temp                             STRING(255)
  CODE
  LOC:Temp = FileName{PROP:Name}
  IF INSTRING('\!', LOC:Temp, 1, 1)
    LOC:Temp = SUB(LOC:Temp, 1, INSTRING('\!', LOC:Temp, 1, 1) - 1)
    RETURN(LOC:Temp)
  END
  IF CLIP(SELF.ExtractExt(FileName{PROP:Name})) = ''
    CASE UPPER(FileName{PROP:Driver})
    OF 'TOPSPEED'
        LOC:Temp = CLIP(LOC:Temp) & '.tps'
    OF 'CLARION'
        LOC:Temp = CLIP(LOC:Temp) & '.dat'
    OF 'CLIPPER'
    OROF 'FOXPRO'
    OROF 'DBASE3'
    OROF 'DBASE4'
      LOC:Temp = CLIP(LOC:Temp) & '.dbf'
    END
  END
  RETURN(SELF.NormalizeFileName(LOC:Temp))
!*************************************************************************************************************************
xDataBackupProClass.GetKeyNames      PROCEDURE
        MAP
AddKeyFile                           PROCEDURE(STRING FileName),BYTE
GenKeyFileName                       PROCEDURE(STRING Ext)
        END
LOC:Temp                             STRING(255)
LOC:File                             STRING(255)
LOC:Key                              STRING(255)
FIQ                  QUEUE,PRE(F_IQ)
Name                   STRING(FILE:MAXFILENAME)
ShortName              STRING(13)
Date                   LONG
Time                   LONG
Size                   LONG
Attrib                 BYTE
                     END
  CODE
  LOC:File = SELF.ExtractPath(SELF.Files.FileLabel{PROP:Name})
  LOOP W# = 1 TO RECORDS(SELF.Keys)
    GET(SELF.Keys, W#)
    IF SELF.Keys.FileNumber = SELF.Files.FileNumber
      IF ERRORCODE() THEN MESSAGE(ERROR(), SELF.CaptionName, ICON:Asterisk) END
      LOC:Key = SELF.ExtractFile(SELF.Files.FileLabel{PROP:Name})
      CASE UPPER(SELF.Files.FileLabel{PROP:Driver})
      OF 'CLARION'
        !keys K??
        LOC:Temp = CLIP(LOC:File) & CLIP(LOC:Key) & '.K??'
        DIRECTORY(FIQ, LOC:Temp, FF_:DIRECTORY)
        LOOP E# = 1 TO RECORDS(FIQ)
          GET(FIQ, E#)
          IF ERRORCODE() THEN MESSAGE(ERROR()) END
          IF FIQ.Name[1] <> '.'
            LOC:Temp = CLIP(LOC:File) & CLIP(FIQ.Name)
            IF AddKeyFile(LOC:Temp) AND SELF.FileExists = FALSE THEN SELF.FileExists = TRUE END
          END
        END
        !memo MEM
        LOC:Temp = CLIP(LOC:File) & CLIP(LOC:Key) & '.MEM'
        IF AddKeyFile(LOC:Temp) AND SELF.FileExists = FALSE THEN SELF.FileExists = TRUE END
      OF 'CLIPPER'
        !key NTX
        GenKeyFileName('NTX')
        !memo DBT
        LOC:Temp = CLIP(LOC:File) & CLIP(LOC:Key) & '.DBT'
        IF AddKeyFile(LOC:Temp) AND SELF.FileExists = FALSE THEN SELF.FileExists = TRUE END
      OF 'FOXPRO'
        !key IDX
        GenKeyFileName('IDX')
        !memo FBT
        LOC:Temp = CLIP(LOC:File) & CLIP(LOC:Key) & '.FBT'
        IF AddKeyFile(LOC:Temp) AND SELF.FileExists = FALSE THEN SELF.FileExists = TRUE END
      OF 'DBASE3'
        !key NDX
        GenKeyFileName('NDX')
        !memo DBT
        LOC:Temp = CLIP(LOC:File) & CLIP(LOC:Key) & '.DBT'
        IF AddKeyFile(LOC:Temp) AND SELF.FileExists = FALSE THEN SELF.FileExists = TRUE END
      OF 'DBASE4'
        !key NDX
        GenKeyFileName('NDX')
        !memo DBT
        LOC:Temp = CLIP(LOC:File) & CLIP(LOC:Key) & '.DBT'
        IF AddKeyFile(LOC:Temp) AND SELF.FileExists = FALSE THEN SELF.FileExists = TRUE END
      END
    END
  END
GenKeyFileName                       PROCEDURE(STRING Ext)
  CODE
  IF SELF.Keys.KeyLabel{PROP:Name} <> ''
    IF CLIP(SELF.ExtractExt(SELF.Keys.KeyLabel{PROP:Name})) = ''
      LOC:Temp = CLIP(LOC:File) & CLIP(SELF.Keys.KeyLabel{PROP:Name}) & '.' & CLIP(Ext)
    ELSE
      LOC:Temp = CLIP(LOC:File) & CLIP(SELF.Keys.KeyLabel{PROP:Name})
    END
  ELSE
    IF CLIP(SELF.ExtractExt(SELF.Keys.KeyName)) = ''
      LOC:Temp = CLIP(LOC:File) & CLIP(SELF.Keys.KeyName) & '.' & CLIP(Ext)
    ELSE
      LOC:Temp = CLIP(LOC:File) & CLIP(SELF.Keys.KeyName)
    END
  END
  IF AddKeyFile(LOC:Temp) AND SELF.FileExists = FALSE THEN SELF.FileExists = TRUE END
AddKeyFile                           PROCEDURE(STRING FileName)
  CODE
  IF FindFile(SELF.NormalizeFileName(FileName))
    SELF.AddList(SELF.NormalizeFileName(FileName))
    RETURN TRUE
  END
  RETURN FALSE

Btrieve и clarion

Добавлено: 27 Октябрь 2019, 8:26
finsoftrz
Да я вчера сделал. Это в шаблоне автоматической конвертации надо было.

Код: Выделить всё

  COPY(%FsFile,loc:filenameS)
  REMOVE(%FsFile)

  if %FsFile{PROP:Driver}='Btrieve'  !для btrieve копируем файлы-продолжения
    loop loc:numBtrv=1 to 99
       if ~exists(FsStrReplace(%FsFile{PROP:NAME},'.dat','.^' & format(loc:numBtrv,@n02)))
          break
       end
       copy(FsStrReplace(%FsFile{PROP:NAME},'.dat','.^' & format(loc:numBtrv,@n02)),FsStrReplace(loc:filenameS,'.dat','.^' & format(loc:numBtrv,@n02)))
       remove(FsStrReplace(%FsFile{PROP:NAME},'.dat','.^' & format(loc:numBtrv,@n02)))
    end
  end 

Btrieve и clarion

Добавлено: 27 Октябрь 2019, 8:34
Игорь Столяров
finsoftrz писал(а): 27 Октябрь 2019, 8:26Да я вчера сделал.
В общем случае, там ведь ещё могут быть файлы с MEMO полями …

Btrieve и clarion

Добавлено: 27 Октябрь 2019, 9:01
finsoftrz
Мне просто это не надо, я опустил. Мемо поле - это 5 первых символов имени основного файла и замена остального на мем. А дальше по той же схеме.

Btrieve и clarion

Добавлено: 27 Октябрь 2019, 9:39
finsoftrz
С memo вот так будет выглядеть:

Код: Выделить всё

  COPY(%FsFile,loc:filenameS)
  REMOVE(%FsFile)

  if %FsFile{PROP:Driver}='Btrieve'  !для btrieve копируем файлы-продолжения
    loop loc:numBtrv=1 to 99
       if ~exists(FsStrReplace(%FsFile{PROP:NAME},'.dat','.^' & format(loc:numBtrv,@n02)))
          break
       end
       copy(FsStrReplace(%FsFile{PROP:NAME},'.dat','.^' & format(loc:numBtrv,@n02)),FsStrReplace(loc:filenameS,'.dat','.^' & format(loc:numBtrv,@n02)))
       remove(FsStrReplace(%FsFile{PROP:NAME},'.dat','.^' & format(loc:numBtrv,@n02)))
    end

    loc:fileMemBtrv=FsFileShort(%FsFile{PROP:NAME},2)
    loc:fileMemBtrv=FsStrReplace(%FsFile{PROP:NAME},clip(loc:fileMemBtrv) & '.dat',clip(sub(loc:fileMemBtrv,1,5)) & 'mem.dat')
    if exists(loc:fileMemBtrv)
       loc:fileMemTargBtrw=FsFileShort(loc:filenameS,2)
       loc:fileMemTargBtrw=FsStrReplace(loc:filenameS,clip(loc:fileMemTargBtrw) & '.dat',clip(sub(loc:fileMemTargBtrw,1,5)) & 'mem.dat')

       COPY(loc:fileMemBtrv,loc:fileMemTargBtrw)
       REMOVE(loc:fileMemBtrv)

       loop loc:numBtrv=1 to 99
          if ~exists(FsStrReplace(loc:fileMemBtrv,'.dat','.^' & format(loc:numBtrv,@n02)))
             break
          end
          copy(FsStrReplace(loc:fileMemBtrv,'.dat','.^' & format(loc:numBtrv,@n02)),FsStrReplace(loc:fileMemTargBtrw,'.dat','.^' & format(loc:numBtrv,@n02)))
          remove(FsStrReplace(loc:fileMemBtrv,'.dat','.^' & format(loc:numBtrv,@n02)))
       end
    end
  end 

Btrieve и clarion

Добавлено: 30 Январь 2020, 12:00
finsoftrz
Ради статистики. Больше полугода крутится боевая база btrieve на терминальном сервере. Было 2 случая сбоя в индексах. Причем на маленьких, мало нагруженных таблицах. Оба раза восстановилось за пять секунд обычным кларионовским full build. На tps за много лет что-то даже не припомню, когда индексы сбивались.

Btrieve и clarion

Добавлено: 30 Январь 2020, 12:25
Игорь Столяров
finsoftrz писал(а): 30 Январь 2020, 12:00 На tps за много лет что-то даже не припомню, когда индексы сбивались.
Основные проблемы с TPS всё-таки возникают при традиционном сетевом доступе к БД (точнее при обрыве сети) или
выключении питания на компьютере с локальной БД в момент выполнения записи (добавления, удаления).
Если у Вас на терминальном сервере решены все аппаратные вопросы + все операции выполняются под транзакциями,
то действительно, там просто нечему сбиваться … :)