cJSON: Формат полей для вложенных структур

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

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Основной тред
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8020
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 94 раза

cJSON: Формат полей для вложенных структур

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

Дед Пахом писал(а): 10 Декабрь 2022, 20:56 Так правила для Doc1 главнее общих правил. Мы это обсуждали.
Да. Но тогда получается, что для "name":"*" аттрибут "IgnoreEmptyArray" лишён смысла.
Потому что для списка мы в любом случае должны добавлять правило с привязкой очереди "IsQueue" / "Instance"
и оно затрёт значение для "name":"*" ... :( В принципе не проблема, зададим "IgnoreEmptyArray" для каждого списка ...
Make Clarion Great Again ! 😎
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3285
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 15 раз
Поблагодарили: 48 раз
Контактная информация:

cJSON: Формат полей для вложенных структур

Сообщение Дед Пахом »

Может быть всё-таки сделать наследование правил: если правило не задано для поля, то оно наследуется из общего правила.
С уважением, ДП
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8020
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 94 раза

cJSON: Формат полей для вложенных структур

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

Дед Пахом писал(а): 10 Декабрь 2022, 21:29 если правило не задано для поля, то оно наследуется из общего правила
Это было бы круто. И я не вижу вопросов совместимости, потому что для опции "ignore" именно так и делается.
А не замахнуться ли тогда и на групповое задание опций по маске (хотя бы первым символам) ? ;) Что-то вроде:

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

   {"Name":"^Flag","IsBool":true}        ! Все теги начинающиеся с "Flag" - булевы
   {"Name":"^List","IsQueue":true}       ! Все теги начинающиеся с "List" - списки
   {"Name":"^_Comment","Ignore":true}    ! Не выгружать / загружать комментарии (JSON5)
   {"Name":"^Date","Format":"@d06.b"}    ! Все теги начинающиеся с "DATE" форматируем как дату.
Make Clarion Great Again ! 😎
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8020
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 94 раза

cJSON: Формат полей для вложенных структур

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

Добрый день !

С челобитной мы Ростова ...
Везде приходится дублировать простой метод экранирования строки, т.к. без него нельзя вообще
(в общем случае) использовать опцию IsRaw или сформировать значения тегов JSON строки вручную.
Я у себя насчитал уже по разным местам 12 копий. Ну это же неправильно ... :(

Рассмотрите пожалуйста возможность добавления этого незамысловатого кода в штатный комплект.
В штатном классе JSON ABC Clarion такой метод есть. Спасибо !

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

! Возвращает экранированное значение тега для строки JSON
json::EscapeString  Procedure(String xValue) !, String
jTag        &cJson
RetVal      Any,Auto
  Code
  jTag &= json::CreateString(xValue)
  If jTag &= Null then Return ''
  else
     RetVal = jTag.ToString()
     jTag.Delete()
     Return RetVal
  end     
Make Clarion Great Again ! 😎
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3285
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 15 раз
Поблагодарили: 48 раз
Контактная информация:

cJSON: Формат полей для вложенных структур

Сообщение Дед Пахом »

Выложил v1.30. Основное:
- Правила для полей наследуются от дефолтного, если не заданы явно.
- Новая опция "RuleHelper" позволяет гибко управлять правилами.
- Пример применения RuleHelper.
Прошу потестировать, у меня было мало времени на это. Но вроде ничего не отломалось.
С уважением, ДП
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8020
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 94 раза

cJSON: Формат полей для вложенных структур

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

Дед Пахом писал(а): 11 Декабрь 2022, 20:12 Но вроде ничего не отломалось
Спасибо, но здесь нужно немного осознать, что произошло ... ;)
Появилась регистрозависимость имён для всех полей, т.е.

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

rh.FindCB  Procedure(String fldName, *typCJsonFieldRule rule)
...
  ! Вот так теперь не работает 
  If    fldName = 'Otdel'   then rule.instance   = Instance(qOtdel,   Thread())
  elsIf fldName = 'Tovar'   then rule.IsQueue    = True
  end
  
  ! А вот так работает 
  If    fldName = 'otdel'   then rule.instance   = Instance(qOtdel,   Thread())
  elsIf fldName = 'tovar'   then rule.IsQueue    = True
  end  
Make Clarion Great Again ! 😎
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3285
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 15 раз
Поблагодарили: 48 раз
Контактная информация:

cJSON: Формат полей для вложенных структур

Сообщение Дед Пахом »

Регистр регулируется параметром pNamesInLowerCase: если он TRUE (по умолчанию), то всё в нижнем регистре, если FALSE - в верхнем (если нет явного NAME('VarName')). Поэтому для сравнения используйте LOWER(fldName)/UPPER(fldName).
С уважением, ДП
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8020
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 94 раза

cJSON: Формат полей для вложенных структур

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

Не вопрос. Бум писать имена в нижнем регистре (или с учётом pNamesInLowerCase) и всё.
Это особенность которую просто нужно знать, т.к. регистр имён в строке Options не имеет значения.
Скорость выгрузки данных с большими Options для RuleHelper (опять) реально выросла в разы ! :ty:

И насколько приятней вместо вот этого вот всего (где нужно выверить каждый знак в строке !):

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

  Root &= json::CreateObject(gPack,,'[' & |
          '{{"name":"*","EmptyString":"ignore","IgnoreZero":true,"IgnoreEmptyObject":true,"IgnoreEmptyArray":true},' & |
          '{{"name":"SCod",       "FormatLeft":"@p<##-#####-#####-#p"},' & |
          '{{"name":"Provodka",   "IsBool":true},'                       & |
          '{{"name":"FlagBack",   "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagNDS",    "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagOplata", "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagSale",   "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagSF",     "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagStorno", "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagUsluga", "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagService","IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagOpl",    "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagCost",   "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagDocF",   "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagClose",  "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagAkziz",  "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagNoStamp","IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagNoSeal", "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagNoNDS",  "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagNoPhone","IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"FlagUrgent", "IsBool":true,"IgnoreFalse":true},'    & |
          '{{"name":"Shet",       "instance":' & Instance(qShet,     Thread()) & '},'  & |
          '{{"name":"TrNakl",     "instance":' & Instance(qTrNakl,   Thread()) & '},'  & |
          '{{"name":"Travel",     "instance":' & Instance(qTravel,   Thread()) & '},'  & |
          '{{"name":"Bank",       "instance":' & Instance(qBank,     Thread()) & '},'  & |
          '{{"name":"Kass",       "instance":' & Instance(qKass,     Thread()) & '},'  & |
          '{{"name":"History",    "instance":' & Instance(qHistory,  Thread()) & '},'  & |
          '{{"name":"Fall",       "instance":' & Instance(qFall,     Thread()) & '},'  & |
          '{{"name":"Plat",       "instance":' & Instance(qPlat,     Thread()) & '},'  & |
          '{{"name":"Client",     "instance":' & Instance(qJClient,  Thread()) & '},'  & |
          '{{"name":"Tovar",      "instance":' & Instance(qJTovar,   Thread()) & '},'  & |
          '{{"name":"Project",    "instance":' & Instance(qJProject, Thread()) & '},'  & |
          '{{"name":"Liza",       "instance":' & Instance(qJLiza,    Thread()) & '},'  & |
          '{{"name":"Otdel",      "instance":' & Instance(qJOtdel,   Thread()) & '},'  & |
          '{{"name":"Spisok",     "IsQueue":true},' & |
          '{{"name":"Exemp",      "IsQueue":true},' & |
          '{{"name":"SList",      "IsQueue":true},' & |
          '{{"name":"TrItem",     "IsQueue":true},' & |
          '{{"name":"Sborka",     "IsQueue":true},' & |
          '{{"name":"Content",    "IsQueue":true},' & |
          '{{"name":"AddBank",    "IsQueue":true}]')
Работать с нормально транслируемым аналогом:

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

  Root &= json::CreateObject(gPack,,'[{{"name":"*","RuleHelper":"' & Address(rh) & '"}]')
  ...
rh.FindCB  Procedure(String fldName, *typCJsonFieldRule rule)
  Code
  rule.EmptyString       = 'ignore'
  rule.IgnoreZero        = True
  rule.IgnoreEmptyObject = True
  rule.IgnoreEmptyArray  = True

  If Sub(fldName,1,4) = 'flag'
     rule.IsBool      = True
     rule.IgnoreFalse = True

  elsIf fldName = 'scod'     then rule.FormatLeft = '@p<##-#####-#####-#p'
  elsIf fldName = 'provodka' then rule.IsBool     = True
  elsIf fldName = 'shet'     then rule.instance   = Instance(qShet,     Thread())
  elsIf fldName = 'trnakl'   then rule.instance   = Instance(qTrNakl,   Thread())
  elsIf fldName = 'travel'   then rule.instance   = Instance(qTravel,   Thread())
  elsIf fldName = 'bank'     then rule.instance   = Instance(qBank,     Thread())
  elsIf fldName = 'kass'     then rule.instance   = Instance(qKass,     Thread())
  elsIf fldName = 'history'  then rule.instance   = Instance(qHistory,  Thread())
  elsIf fldName = 'fall'     then rule.instance   = Instance(qFall,     Thread())
  elsIf fldName = 'plat'     then rule.instance   = Instance(qPlat,     Thread())
  elsIf fldName = 'client'   then rule.instance   = Instance(qJClient,  Thread())
  elsIf fldName = 'tovar'    then rule.instance   = Instance(qJTovar,   Thread())
  elsIf fldName = 'project'  then rule.instance   = Instance(qJProject, Thread())
  elsIf fldName = 'liza'     then rule.instance   = Instance(qJLiza,    Thread())
  elsIf fldName = 'otdel'    then rule.instance   = Instance(qJOtdel,   Thread())
  elsIf fldName = 'spisok'   then rule.IsQueue    = True
  elsIf fldName = 'exemp'    then rule.IsQueue    = True
  elsIf fldName = 'slist'    then rule.IsQueue    = True
  elsIf fldName = 'tritem'   then rule.IsQueue    = True
  elsIf fldName = 'sborka'   then rule.IsQueue    = True
  elsIf fldName = 'content'  then rule.IsQueue    = True
  elsIf fldName = 'addbank'  then rule.IsQueue    = True.
И это я ещё пока не использовал все возможности фильтрации имён в обычном коде ... ;)

Минус (особенность) пока только один: нельзя использовать метод rh.FindCB внутри Routine, и как следствие -
нужно выносить класс и все описания используемых в нём структур данных в общее описание процедуры.
Но это приятные хлопоты. :ty:
Make Clarion Great Again ! 😎
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 5229
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 12 раз
Поблагодарили: 63 раза

cJSON: Формат полей для вложенных структур

Сообщение finsoftrz »

Может, привязать правила к типам данных? Это какая-то титаническая работа анализировать названия полей...
C6/C12, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8020
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 94 раза

cJSON: Формат полей для вложенных структур

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

Тип данных мало, что значит в JSON ... уже обсуждали, что BOOL неотличим от LONG,
BYTE - это и флаг и данные ... LONG и число и дата / время и т.д. Увы ! :(
Make Clarion Great Again ! 😎
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 5229
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 12 раз
Поблагодарили: 63 раза

cJSON: Формат полей для вложенных структур

Сообщение finsoftrz »

Bool это не byte разве? А дату и время можно определить по подстроке в метке, наверняка там присутствуют эти слова. Язык шаблонов не предлагаю, вы ручками все пишите. Когда я делал себе логирование изменений в базе данных, то определял поля с датой и временем по маске ввода в словаре. Поэтому при просмотре лога они отображаются в правильном виде.
C6/C12, ШВС, tps/btrieve.
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 5229
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 12 раз
Поблагодарили: 63 раза

cJSON: Формат полей для вложенных структур

Сообщение finsoftrz »

И какая разница при загрузке/выгрузке, что в byte лежит?
C6/C12, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8020
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 94 раза

cJSON: Формат полей для вложенных структур

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

finsoftrz писал(а): 12 Декабрь 2022, 16:39 Bool это не byte разве?
К сожалению нет. Bool - это Long. ХЗ зачем для логического флага используется 4-байтовая переменная.
Возможно SV оставили запас под кубиты для квантовых процессоров ... ;)
finsoftrz писал(а): 12 Декабрь 2022, 16:41 И какая разница при загрузке/выгрузке, что в byte лежит?
А это зависит от того, кто и как будет это загружать / выгружать ...
Есть такие счастливые форматы и языки, где строка - это TEXT и размер не имеет занчения.
Byte - это цифра, а Bool - это флаг. И "0" у них это цифра, а не флаг и т.д.
Make Clarion Great Again ! 😎
Аватара пользователя
finsoftrz
✯ Ветеран ✯
Сообщения: 5229
Зарегистрирован: 06 Ноябрь 2014, 12:48
Благодарил (а): 12 раз
Поблагодарили: 63 раза

cJSON: Формат полей для вложенных структур

Сообщение finsoftrz »

Все это на автомате разруливается через шаблоны. Врукопашную писать имеет смыл для какой-то небольшой частной задачки. Если делать так какую-то универсальную вещь - и писанины много, и ошибок. Структура базы постепенно может расширяться, тоже тестировать надо не забывать. Шаблон настроил один раз и забыл.
C6/C12, ШВС, tps/btrieve.
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8020
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 94 раза

cJSON: Формат полей для вложенных структур

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

Есть, даже не вопрос, а скорее тема к обсуждению ...

В JSON есть понятие Array, и его вырожденная форма безтеговый массив (EasyArray):
"Digit":[1,2,4 ...] или "Word":["Один","Два" ...]. Очень удобно и лаконично.

В языке Clarion нет понятия "безразмерный массив", поэтому для формирования
"массивом с заранее неизвестным кол-вом значений" используется Queue (или я не прав ?).

Собственно вопрос.
В классе cJSON отсутствует простой механизм трансформации Queue <-> EasyArray для методов
CreateObject / Array / ToGroup / ToQueue. Например как дополнение опций IsQueue / Instance,
когда обрабатывалось бы только первое (или указанное по наименованию) поле из Queue.

Как делать такую обработку мучительным перебором по одной записи или элементу массива - я уже знаю ...
Make Clarion Great Again ! 😎
Закрыто