Как получить возможные значения столбца типа SET

Доброго времени суток! Создал объект по инструкции Ильи Уткина тут. Все работает отлично, НО у меня в таблице есть столбец типа SET (на подобии селекта), знает ли кто способ вывести возможные значения этого столбца. Знаю что в SQL можно вывести через SHOW COLUMN, а как через xPDO это сделать?

P.S. В столбце возможны значения: 'Петя', 'Вася', 'Игорь'. Нужен метод который вернет массив этих значений.
Павел Степанов
30 октября 2017, 16:13
modx.pro
2 003
0

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

Alexey Medvedev
30 октября 2017, 20:03
0
xPDO немного ограничен для работы в полную силу с БД. Предлагаю Вам самостоятельно написать запрос с помощью xpdo.query

Определить все возможные значения для a SET столбец, использовать SHOW COLUMNS FROM tbl_name LIKE set_col и синтаксический анализ SET определение в Type столбец вывода.

Также по-идее должен работать обычный SELECT.
О типе SET
mysql> SELECT col FROM myset;
+------+
| col  |
+------+
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
+------+
5 rows in set (0.04 sec)
    Павел Степанов
    30 октября 2017, 20:43
    0
    function get_set_values( $table, $field )
    <?php
    get_set_values('modx_online_exam_order','subject');
    function get_set_values( $table, $field )
    {
        $result = $modx->query("SHOW COLUMNS FROM $table LIKE $field");
        $row = $result->fetch(PDO::FETCH_ASSOC);
        return print_r($row,true);
    }
    [2017-10-30 20:42:10] (WARN @ /home/m/public_html/core/components/console/processors/exec.class.php(24) : eval()'d code : 5)
    PHP notice: Undefined variable: modx
    
    Fatal error: Uncaught Error: Call to a member function query() on null in /home/m/public_html/core/components/console/processors/exec.class.php(24) : eval()'d code:5 Stack trace: #0 /home/m/public_html/core/components/console/processors/exec.class.php(24) : eval()'d code(2): get_set_values('modx_online_exa...', 'subject') #1 /home/m/public_html/core/components/console/processors/exec.class.php(24): eval() #2 /home/m/public_html/core/model/modx/modprocessor.class.php(173): ConsoleExecProcessor->process() #3 /home/m/public_html/core/model/modx/modx.class.php(1706): modProcessor->run() #4 /home/m/public_html/core/model/modx/modconnectorresponse.class.php(140): modX->runProcessor('exec', Array, Array) #5 /home/m/public_html/core/model/modx/modconnectorrequest.class.php(82): modConnectorResponse->outputContent(Array) #6 /home/m/public_html/core/model/modx/modconnectorrequest.class.php(69): modConnectorRequest->prepareResponse(Array) #7 /hom in /home/m/public_html/core/components/console/processors/exec.class.php(24) : eval()'d code on line 5
    Вероятно я что-то не так понял?
      Павел Степанов
      30 октября 2017, 21:45
      0
      Как думаете, а из описания объекта нельзя как-нибудь достать значения?
      components/objectname/model/objectname/objectname.mysql.schema.xml
      Ведь модель-то уже описана.
        Alexey Medvedev
        30 октября 2017, 23:00
        0
        Если это обычная функция, то необходимо передать класс modx.
        function get_set_values( $modx, $table, $field )
        {
            $result = $modx->query("SHOW COLUMNS FROM $table LIKE $field");
            $row = $result->fetch(PDO::FETCH_ASSOC);
            return print_r($row,true);
        }
        Если это функция часть класса, то тогда
        $this->modx->query();
        И ещё используйте подготовленные запросы или фильтруйте данные передаваемые в SQL.

        Можете привести структуру таблицы, часть данных и для чего вы будете использовать данные из колонки типа SET, чтобы можно было с чем-то работать, а то это мысли в пустоту.

        Если хотите можете направить всё через контакты в профиле.
          Павел Степанов
          30 октября 2017, 23:13
          0
          А разве PDO автоматически не обрабатывает данные ?!
          Хочу использовать SET для формы где будет input select (как раз сюда и будет помещаться массив данных). Чтобы при внесении новых пунктов в SET это автоматом подтягивалось в форму.

          Для примера: в SET находится список услуг. При добавлении новой услуги, она появляется в форме, в этом выпадающем списке.
            Alexey Medvedev
            30 октября 2017, 23:29
            0
            xPDO обрабатывает только подготовленные запросы, в том числе и по схеме. Он собирает подготовленный запрос на основе схемы, а при чистом запросе вы должны подготовить всё сами.

            А чего так сложно? Почему бы не сделать всё обычным полем (longtext) и хранить данные в json или сделать отдельную таблицу с услугами (id,title,price и т.д.).

            Структуру таблицы, пожалуйста, приведите.
              Павел Степанов
              30 октября 2017, 23:43
              0
              Сложность в том, что уже есть объект, которым удобно пользоваться без sql портянок. Плюс потом нужно будет по услугам делать поиск (придется возиться со связыванием таблиц). Соответственно зачем делать еще одну таблицу, если можно обойтись одним созданным для этих целей столбцом.
              <?xml version="1.0" encoding="UTF-8"?>
              <model package="OnlineOrder" baseClass="xPDOObject" platform="mysql" defaultEngine="MyISAM" version="1.1">
              	<object class="OnlineOrder" table="online_order" extends="xPDOSimpleObject">
              		<field key="date_event" dbtype="datetime" phptype="datetime" null="false" />
              		<field key="usluga" dbtype="set" precision="'стирка','прачка','уборка'" phptype="string" null="false" />
              		<field key="user_name" dbtype="varchar" precision="50" phptype="string" null="false" />
              		<field key="user_vk_url" dbtype="varchar" precision="60" phptype="string" null="false" />
              		<field key="user_vk_id" dbtype="bigint" precision="20" attributes="unsigned" phptype="integer" null="false" />
              		<field key="update_order" dbtype="timestamp" phptype="timestamp" null="false" default="CURRENT_TIMESTAMP"  extra="on update current_timestamp" />
              		<field key="create_order" dbtype="timestamp" phptype="timestamp" null="false" default="CURRENT_TIMESTAMP" />
              	</object>
              </model>
                Павел Степанов
                30 октября 2017, 23:54
                0
                Соответственно ищу метод на подобии:
                $item = $modx->newObject('OnlineOrder');
                $item = $ПолучитьВсеЗначенияПоляSET('usluga');
      Павел Степанов
      31 октября 2017, 00:55
      0
      В общем сделал иначе: услуги прописал через migx. xPDO много методов перерыл, подходящего не нашел.
      $result = $modx->query("SHOW COLUMNS FROM $table LIKE $field")
      так и не заработал, ругаясь: fetch undefined
        Волков Николай
        31 октября 2017, 05:58
        +1
        $class — имя класса из schema для нужной таблицы.
        $column — название колонки для получения.
        $sortdir — Направление сортировки у значений
        $query — фильтр для поиска среди значений
        $limit — кол-во значений для вывода
        $offset — сколько позиций пропустить для вывода

        $array = array();
        
        if(!isset($limit)) $limit = 0;
        if(!isset($offset)) $offset = 0;
        if(!isset($sortdir)) $sortdir = 'ASC';
        
        $c = $modx->newQuery( $class );
        $c->select($column);
        $c->sortby($column);
        $c->sortdir($sortdir);
        $c->groupby($column);
        $c->limit($limit, $offset);
        if(!empty($query)){
        	$values[] = $query;
        	$c->where(array($column.':LIKE'=>'%'.$query.'%'));
        }
        
        if($c->prepare() && $c->stmt->execute()){
        	$values = array_merge($values, $c->stmt->fetchAll(PDO::FETCH_COLUMN, 0));
        }
          Павел Степанов
          31 октября 2017, 14:50
          0
          $array = array();
          
          if(!isset($limit)) $limit = 0;
          if(!isset($offset)) $offset = 0;
          if(!isset($sortdir)) $sortdir = 'ASC';
          $class = 'OnlineOrder';
          $column = 'usluga';
          $c = $modx->newQuery( $class );
          $c->select($column);
          $c->sortby($column);
          $c->sortdir($sortdir);
          $c->groupby($column);
          $c->limit($limit, $offset);
          if(!empty($query)){
          	$values[] = $query;
          	$c->where(array($column.':LIKE'=>'%'.$query.'%'));
          }
          
          if($c->prepare() && $c->stmt->execute()){
          	$values = array_merge($values, $c->stmt->fetchAll(PDO::FETCH_COLUMN, 0));
          }
          Uncaught Error: Call to undefined method xPDOQuery_mysql::sortdir()
          Делаю через консоль, кроме этого больше ничего не пишу, я видимо что-то не понимаю?!
            Волков Николай
            31 октября 2017, 14:55
            0
            Ссорян, случайно немного перепутал синктаксис :-))))

            $array = array();
            
            if(!isset($limit)) $limit = 0;
            if(!isset($offset)) $offset = 0;
            if(!isset($sortdir)) $sortdir = 'ASC';
            $class = 'OnlineOrder';
            $column = 'usluga';
            
            $c = $modx->newQuery( $class );
            $c->select($column);
            $c->sortby($column, sortdir);
            $c->groupby($column);
            $c->limit($limit, $offset);
            if(!empty($query)){
            	$values[] = $query;
            	$c->where(array($column.':LIKE'=>'%'.$query.'%'));
            }
            
            if($c->prepare() && $c->stmt->execute()){
            	$values = array_merge($values, $c->stmt->fetchAll(PDO::FETCH_COLUMN, 0));
            }
          Волков Николай
          31 октября 2017, 06:06
          0
          Увидел сообщение, что в schema:
          <field key="usluga" dbtype="set" precision="'стирка','прачка','уборка'" phptype="string" null="false" />
          Я хренею, как можно было не найти через xPDO способы для получения значений у колонки, но при этом найти этот вид колонок для БД.

          Друг, для указания массива значений возможных ты выбрал самый %:% способ. А что будет, если потребуется добавить еще один вариант услуги? Ну или банально заказчик потребует сделать все с заглавной буквы?
            Alexey Medvedev
            31 октября 2017, 07:20
            0
            Мне вот интересно, где такой тип прописан в xPDO. Я пролистал много страниц мануалов, но так и не нашел. Скорее всего автор просто прописал тип Set.
              Волков Николай
              31 октября 2017, 07:26
              0
              Ну я бы на твоем месте копал бы не в xPDO, а в PDO… Глядишь, также, как и я, за 5 минут найдешь :-)
                Alexey Medvedev
                31 октября 2017, 07:33
                0
                Просвяти, может я ещё не проснулся. Но PDO не использует XML-схемы.
                Павел Степанов
                31 октября 2017, 14:41
                0
                Я создал таблицу phpmyadmin с столбцом типа SET, cгенерировал объект через CMP Generator.
                Павел Степанов
                31 октября 2017, 14:38
                0
                %*?! перепутал SET с ENUM. Планировал ENUM использовать.
                Вид колонок ENUM автоматически является индексом, соответственно для поиска по БД, эт хорошо. Да и если анализировать таблицу(PROCEDURE ANALYSE()), он всегда советует использовать ENUM.
                Насчет массива, так ведь в этом и плюс, добавляешь в БД новый тип услуги и он автоматом подтягивается (возможно я конечно мыслю через Пифогора, но вроде удобно).Единственное schema нужно перегенерировать.
                Alexey Medvedev
                31 октября 2017, 07:14
                0
                Зачем всё так усложнять :( Сделал — молодец. Но предчувствую, что потом будут трудности.
                  Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                  19