Btrieve и clarion

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Аватара пользователя
morkovin
Ветеран
Сообщения: 758
Зарегистрирован: 20 Июль 2005, 13:53
Откуда: Volgograd, Russia
Контактная информация:

Btrieve и clarion

Сообщение morkovin »

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

kreator
✯ Ветеран ✯
Сообщения: 3724
Зарегистрирован: 28 Май 2009, 14:54
Откуда: Москва

Btrieve и clarion

Сообщение kreator »

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

Аватара пользователя
porutchik
Бывалый
Сообщения: 62
Зарегистрирован: 01 Февраль 2009, 5:35

Btrieve и clarion

Сообщение porutchik »

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

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

Аватара пользователя
vic7tar
Ветеран
Сообщения: 328
Зарегистрирован: 09 Февраль 2017, 20:12

Btrieve и clarion

Сообщение vic7tar »

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

Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 1667
Зарегистрирован: 06 Ноябрь 2014, 12:48

Btrieve и clarion

Сообщение finsoftrz »

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

Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 1667
Зарегистрирован: 06 Ноябрь 2014, 12:48

Btrieve и clarion

Сообщение finsoftrz »

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

Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 4625
Зарегистрирован: 07 Июль 2005, 9:19
Откуда: г. Ростов-на-ДоМу

Btrieve и clarion

Сообщение Игорь Столяров »

Вроде бы это файловая функция.

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

Никаких файлОВ, входящих в структуру таблицы и т.д.
«V» значит Вендетта !

Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 1667
Зарегистрирован: 06 Ноябрь 2014, 12:48

Btrieve и clarion

Сообщение finsoftrz »

Если это FILE, то логично было бы копировать все физические файлы, имена которых однозначно определяются. Конечно, все это решается написанием своей функции.
Рязань решает.

Аватара пользователя
Admin
Администратор
Сообщения: 3536
Зарегистрирован: 05 Июль 2005, 14:59
Откуда: Хабаровск
Контактная информация:

Btrieve и clarion

Сообщение 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
Рай совершает ошибки ничуть не реже чем ад. Просто у него хорошая пресса

Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 1667
Зарегистрирован: 06 Ноябрь 2014, 12:48

Btrieve и clarion

Сообщение 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 
Рязань решает.

Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 4625
Зарегистрирован: 07 Июль 2005, 9:19
Откуда: г. Ростов-на-ДоМу

Btrieve и clarion

Сообщение Игорь Столяров »

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

Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 1667
Зарегистрирован: 06 Ноябрь 2014, 12:48

Btrieve и clarion

Сообщение finsoftrz »

Мне просто это не надо, я опустил. Мемо поле - это 5 первых символов имени основного файла и замена остального на мем. А дальше по той же схеме.
Рязань решает.

Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 1667
Зарегистрирован: 06 Ноябрь 2014, 12:48

Btrieve и clarion

Сообщение 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 
Рязань решает.

Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 1667
Зарегистрирован: 06 Ноябрь 2014, 12:48

Btrieve и clarion

Сообщение finsoftrz »

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

Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 4625
Зарегистрирован: 07 Июль 2005, 9:19
Откуда: г. Ростов-на-ДоМу

Btrieve и clarion

Сообщение Игорь Столяров »

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

Ответить