Как заставить xpdo НЕ заключать значение в кавычки

Вопрос простой: как заставить xpdo НЕ заключать значение в кавычки:
$query->where(array(array('tvTable3.value:IS' => null),
                    array('tvTable3.value:=' => ''),
                    array('tvTable3.value:<' => 0)),
                    xPDOQuery::SQL_OR);

Здесь мы нуль заключается в кавычки:
`tvTable3`.`value` IS NULL OR `tvTable3`.`value` = '' OR `tvTable3`.`value` <= '0'

Можно, конечно, отказаться от ключа и всё условие целиком записать в качестве значения:
$query->where(array(array('tvTable3.value:IS' => null),
                    array('tvTable3.value:=' => ''),
                    array('tvTable3.value <= 0')),
                    xPDOQuery::SQL_OR);
Но в этом случае мы исключаем значение 0 из xpdo-обработки.
Cyrax_02
21 апреля 2014, 05:20
modx.pro
2 170
0

Комментарии: 13

Василий Наумкин
21 апреля 2014, 09:46
0
Насколько я понимаю, это зависит от прописанной модели объекта. Если поле типа int, то ковычек не будет.

Проверяем:
<?php
$q = $modx->newQuery('modResource');
$q->select('id,pagetitle');
$q->where(array('id:!=' => 0, 'pagetitle:!=' => 0));
$q->prepare();
echo $q->toSQL();

Выводит:
SELECT `id`, `pagetitle` FROM `modx_site_content` AS `modResource` WHERE ( `modResource`.`id` != 0 AND `modResource`.`pagetitle` != '0' )

Как видишь, для id нет ковычек, а для pagetitle — есть.
    Cyrax_02
    21 апреля 2014, 09:54
    0
    Да, с полями ресурсов xpdo работает нормально.
    Не указал сразу — речь идёт о полях TV. При работе с TV xpdo всегода заключает значения в кавычки.
    Да, значения TV-полей физически (на уровне БД) имеют строковый тип. Но xpdo не принимает во внимание тип этих полей, указанных в свойствах TV. Всегда рассматривает их как строки.
      Василий Наумкин
      21 апреля 2014, 09:57
      0
      Ну так если в модели строка, в БД строка — почему в условии должна быть не строка?

      Тип ТВ значения не имеет, потому что это никак не влияет на его способ хранения в БД.
        Василий Наумкин
        21 апреля 2014, 10:08
        0
        Если ты хочешь обойти автоматическую генерацию условий по модели, можно указать в where готовую строку:
        $q->where("`tvTable3`.`value` IS NULL OR `tvTable3`.`value` = '' OR `tvTable3`.`value` <= 0");
          Cyrax_02
          21 апреля 2014, 10:27
          0
          Хотелось бы решить задачу, не исключая значение из xpdo-обработки

          Нелогично получается с точки зрения modx: тип TV-поля указывать можно, все необходимые операции с такими TV-полями посредством xpdo можно выполнять (т.е. формируем почти любые запросы), а корректно сравнивать числовые TV (элементарная операция) посредством xpdo — нельзя. Серьёзная дыра в модели xpdo. Не иначе.
            Василий Наумкин
            21 апреля 2014, 11:26
            0
            Хотелось бы решить задачу, не исключая значение из xpdo-обработки
            Это ты про что? Я говорю, что можно не просить xPDO за тебя генерировать условие, как тебе не нравится, а указать его самостоятельно.

            В моделе указано, что тип поля — строка, поэтому автоматическая генерация оборачивает значение в ковычки. Если указано int — будет без ковычек. Если не устраивает автоматическая обработка, и ты хочешь для строки указать условие как int — пиши его сам.

            Тебе ничего не запрещают — делай как хочешь.

            а корректно сравнивать числовые TV (элементарная операция) посредством xpdo — нельзя
            xPDO — это php класс, он не волшебный, он только готовит запросы и получает данные из БД. Сравнение производит mysql, а не xpdo.

            ТВ — это строка и mysql начхать, что там в MODX указано — в БД это все равно строка и сравниваться она будет как строка, с кавычками ты там указал условие или нет.

            Если ты хочешь выбирать и сравнивать строки как числа — нужно приводить тип данных в mysql, типа
            ORDER BY CAST(`TV`.`value` AS DECIMAL(13,3))
            Например, pdoTools учитывает тип ТВ и говорит сравнивать числа как числа, даты как даты, а не как строки.

            pdoTools тоже работает на xPDOи запрос строится с его помощью. Но это не мешает мне указать правильное для меня условие.
              Cyrax_02
              21 апреля 2014, 12:34
              0
              Запиши тот же самый CAST:
              ORDER BY CAST(`TV`.`value` AS DECIMAL(13,3))
              но для условия where (TV.value < 0)
                Василий Наумкин
                21 апреля 2014, 13:16
                0
                Да мне то нафига это нужно?

                При выборке типы автоматически приводятся, это не сортировка. Mysql выберет одно и тоже, если указать условие хоть строкой, хоть целым числом.

                Или у тебя если число в ковычках — что-то не то выбирается? Будь добр, покажи реальный пример, а то я вообще понять не могу, какой ты фигнёй страдаешь.
                  Cyrax_02
                  21 апреля 2014, 13:28
                  0
                  Я хочу сказать, что даже если и записать поле CAST'ом:
                  $modx->where(array('`TV`.`value` AS DECIMAL(13,3):<' => 0))

                  то xpdo всё равно сформирует sql-запрос со строковым сравнением (заключит нуль в кавычки):
                  WHERE `TV`.`value` AS DECIMAL(13,3) <= '0'

                  Это ответ на пример с ORDER BY CAST
                    Василий Наумкин
                    21 апреля 2014, 13:31
                    0
                    Ты указываешь массив, а не строку. Это говорит xPDO, что нужно обработать указанное значение согласно модели.

                    В модели поле value имеет тип «string», значит нужно обернуть 0 в ковычки. Если ты хочешь избежать автоматической обработки, нужно указать готовое условие без ковычек, строкой, как в этом примере.

                    Неужели до сих пор не понятно?

                    Повторяю свой вопрос еще раз: чего ты вообще хочешь добиться, указывая числа с ковычками или без? Это никак не влияет на результаты выборки, mysql приводит типы самостоятельно.
                      Cyrax_02
                      21 апреля 2014, 14:27
                      0
                      Блин. Что xpdo учитывает только тип данных, указанный в модели, и что xpdo НЕ учитывает тип TV-параметра, указанный в его свойствах, — это понятно.

                      Не понятно, почему xpdo не учитывает тип TV-параметра, указанный в его свойствах. Следуя концепции TV-параметров, при формировании SQL нужно учитывать тип TV-параметра, указанный в его свойствах. Если указан числовой тип, то и операции сравнения должны быть числовыми (значение не должно заключаться в скобки). А то, что на уровне БД значения TV имеют строковый тип — это исключительно способ хранения данных, который выбрали разработчики modx.

                      Согласно концепции TV-параметров, эти параметры являются типизированными. Соотсветственно, и способ их обработки должен отвечать их типу. xpdo всё мешает в кучу.
                        Василий Наумкин
                        21 апреля 2014, 15:08
                        0
                        Вот ты тяжелый…

                        xPDO учитывает тип ТВ параметра. И тип у него, внимание, строка!

                        То что там в админке ты крутишь — xPDO до фонаря, он работает на более низком уровне. В xPDO нет никаких ТВ параметров, это уже из MODX который является надстройкой над xPDO. Для него не имеет значение ничего, кроме модели.

                        В модели нет такого понятия, как «это поле может быть строкой, а может и числом — в зависимости от чекбокса в админке».
                        Точно также, как нет такой фигни и в самой базе данных, ферштейн? Там поле или строка, или число, оно не меняется в зависимости от контекста.

                        Если ты хранишь числа в строках — это тоже строки, как не запрашивай, какие условия не задавай, в таблице это строки!

                        Ты, наверное хочешь, что при каждом запросе ТВ через xPDO, он лез в таблицу ТВ (а таблица с самим ТВ и его значениями — 2 разных таблицы), смотрел там тип ТВ и строил запрос как-то иначе, наплевав на прописанный тип в модели?

                        Так вот, xPDO об этом ничего не знает, потому что ничего такого в модели и БД не бывает в принципе.

                        Я не знаю, как еще понятнее объяснить.
                        Василий Наумкин
                        21 апреля 2014, 15:13
                        0
                        На всякий случай — xPDO это не MODX. Это отдельная ORM, которая используется в MODX и он накручивает дофига всего сверху, включая ТВ параметры для ресурсов.

                        xPDO можно использовать отдельно, и естественно, никаких ТВ параметров там не будет.

                        Вот сайт xPDO, а вот его репозиторий.
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    13