Query XML
En Zittme no escribes SQL directamente: declaras las tablas y las consultas en XML. El mismo código funciona con distintos tipos de base de datos y, como la vinculación de valores es automática, no tienes que preocuparte por la inyección SQL.
Declarar tablas: schemas/*.xml
El nombre del archivo es el nombre de la tabla. El núcleo crea la tabla al instalar el módulo.
<table name="mymodule_item">
<column name="item_srl" type="bigint" notnull="notnull" primarykey="primarykey" />
<column name="member_srl" type="bigint" notnull="notnull" index="idx_member_srl" />
<column name="title" type="varchar" size="250" notnull="notnull" />
<column name="content" type="bigtext" />
<column name="status" type="varchar" size="10" notnull="notnull" default="open" index="idx_status" />
<column name="regdate" type="char" size="14" index="idx_regdate" />
</table>- Tipos principales:
number/bigint/varchar(size obligatorio) /char/text/bigtext/date/float - Por convención, las fechas se guardan en
char(14)como cadenaYYYYMMDDHHIISS(date('YmdHis')). - Los números únicos se obtienen con
getNextSequence()y se guardan en columnas*_srl.
Agregar columnas con el sitio en operación: el núcleo no agrega automáticamente columnas nuevas a una tabla que ya existe. Tienes que hacer dos cosas a la vez: modificar el XML del esquema y llamar a addColumn() en el moduleUpdate de Install.
Declarar consultas: queries/*.xml
SELECT
<query id="getItems" action="select">
<tables>
<table name="mymodule_item" />
</tables>
<columns>
<column name="*" />
</columns>
<conditions>
<condition operation="equal" column="status" var="status" default="open" />
<condition operation="like" column="title" var="s_title" pipe="and" />
<condition operation="more" column="regdate" var="start_regdate" pipe="and" />
</conditions>
<navigation>
<index var="sort_index" default="item_srl" order="desc" />
<list_count var="list_count" default="20" />
<page var="page" default="1" />
</navigation>
</query>vares el nombre del valor que pasas desde PHP. Si no pasas el valor, esa condición se omite por completo. A las condiciones obligatorias agrégalesnotnull="notnull".defaultes el valor predeterminado cuando no hay valor.pipees la conexión (and/or) con la condición anterior. No se usa en la primera condición.
Todas las operation disponibles:
| operation | SQL | Significado |
|---|---|---|
equal | = | Igual |
notequal (=not_equal) | != | Distinto |
more (=gte) | >= | Mayor o igual |
excess (=gt) | > | Mayor que |
less (=lte) | <= | Menor o igual |
below (=lt) | < | Menor que |
like / notlike | LIKE '%value%' | Contiene / no contiene |
like_prefix (=like_head) | LIKE 'value%' | Empieza con |
like_tail (=like_suffix) | LIKE '%value' | Termina con |
search | LIKE '%value%' por palabra | Divide el término de búsqueda en palabras y compara cada una |
in / notin | IN (...) | Incluido / excluido de la lista |
between | BETWEEN | Rango |
null / notnull | IS (NOT) NULL | Comprobación de nulo |
regexp / notregexp | REGEXP | Expresión regular |
- Si pones
list_countypageen<navigation>, el resultado deexecuteQueryArrayincluye la información de paginación (page_navigation).
INSERT / UPDATE / DELETE
<query id="insertItem" action="insert">
<tables>
<table name="mymodule_item" />
</tables>
<columns>
<column name="item_srl" var="item_srl" notnull="notnull" filter="number" />
<column name="title" var="title" notnull="notnull" />
<column name="content" var="content" />
<column name="status" var="status" default="open" />
<column name="regdate" var="regdate" />
</columns>
</query><query id="updateItemStatus" action="update">
<tables>
<table name="mymodule_item" />
</tables>
<columns>
<column name="status" var="status" notnull="notnull" />
</columns>
<conditions>
<condition operation="equal" column="item_srl" var="item_srl" filter="number" notnull="notnull" />
</conditions>
</query>filter="number"es una validación que solo deja pasar números.- Para delete, usa
action="delete"y declara solo conditions. Agrega siempre notnull a las condiciones clave para que no se ejecute un delete/update sin condiciones.
Ejecutar desde PHP
$args = new \stdClass;
$args->status = 'open';
$args->page = (int)\Context::get('page') ?: 1;
$output = executeQueryArray('mymodule.getItems', $args);
if (!$output->toBool())
{
return $output; // DB 오류
}
$items = $output->data; // 항상 배열
$paging = $output->page_navigation; // navigation 선언 시executeQueryes para resultados de un solo registro;executeQueryArraysiempre devuelve el resultado como arreglo. Para listas usa la versión Array.- Si necesitas un join, pon las dos tablas en
<tables>y únelas en<conditions>, o usa<table type="left join">con declaraciones de<conditions>anidadas. Para joins complejos, lo más rápido es consultar el XML de consultas de los módulos del núcleo (board, document).
La trampa más común
Las columnas que no están en <columns> se descartan en silencio. Aunque pases $args->new_column = 'value' desde PHP, si esa columna no está declarada en <columns> del XML de la consulta insert/update, se ignora sin ningún error. Si te pasa que "estoy seguro de que lo guardé, pero no está en la base de datos", casi seguro es esto.
Cuando agregues una columna, modifica estos tres lugares a la vez.
- Agrega la columna en
schemas/table.xml - addColumn en el moduleUpdate de Install (para sitios ya instalados)
- Agrégala en
<columns>del XML de las consultas insert/update relacionadas