Development

sfPropelAlternativeSchemaPlugin/Es (diff)

You must first sign up to be able to contribute.

Changes from Version 1 of sfPropelAlternativeSchemaPlugin/Es

Show
Ignore:
Author:
Javier.Eguiluz (IP: 217.127.103.246)
Timestamp:
02/19/08 08:56:40 (10 years ago)
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • sfPropelAlternativeSchemaPlugin/Es

    v0 v1  
     1= sfPropelAlternativeSchemaPlugin - Extensión a la sintaxis de esquemas de Propel = 
     2 
     3Artículo original: [http://trac.symfony-project.com/wiki/sfPropelAlternativeSchemaPlugin sfPropelAlternativeSchemaPlugin - Extension to the Propel schema syntax]. Traducción realizada por Raúl Alonso - raul (arroba) raulalonso (punto) net 
     4 
     5== Descripción == 
     6 
     7Este plugin amplía el modelo generador de Symfony sobre la base de Propel, de forma que 
     8será posible redefinir las propiedades de un esquema con otro esquema. El uso de este plugin 
     9puede agregar columnas, cambiar los nombres de la tabla, o la conexión de base de datos sin 
     10modificar los actuales esquemas. 
     11 
     12También proporciona una nueva sintaxis YAML para definir esquemas de bases de datos, más 
     13explícita y más legible que la actual. Por último, esta sintaxis alternativa de esquemas añade 
     14algunas nuevas características a los esquemas, como es la posibilidad de definir un 
     15comportamiento desde un esquema. 
     16 
     17== Instalación == 
     18  
     19Para instalar el plugin en un proyecto Symfony, el proceso usual es utilizar Symfony en la línea 
     20de comandos: 
     21{{{ 
     22$ php symfony plugin-install http://plugins.symfony-project.com/sfPropelAlternativeSchemaPlugin 
     23}}} 
     24 
     25Por otra parte, si usted no tiene PEAR instalado, puede descargar el último paquete del plugin 
     26y copiarlo en el directorio plugins del proyecto. 
     27 
     28Posteriormente, borrar la caché para que la carga automática de clases del proyecto pueda leer las nuevas 
     29clases: 
     30{{{ 
     31$ php symfony cc 
     32}}} 
     33 
     34Eso es todo, usted está listo para reemplazar los actuales esquemas y escribir con la nueva 
     35sintaxis. 
     36 
     37== Personalizando un esquema existente == 
     38 
     39Una vez instalado el plugin, un esquema puede redefinirse con otro esquema. Este plugin es 
     40ideal, por ejemplo, para permitir a los usuarios personalizar algunas de las opciones sobre 
     41aquellos esquemas que vienen por defecto en otros plugins (como la conexión, la tabla de 
     42nombres, etc), o para permitir que un plugin amplíe a otro plugin. 
     43 
     44Durante la construcción del modelo, el plugin buscará archivos YAML personalizados para cada 
     45esquema, partiendo de esta norma: 
     46 
     47|| '''Nombre del esquema original'''      || '''Nombre del esquema personalizado'''  || 
     48|| config/schema.yml                      || schema.custom.yml                       || 
     49|| config/foobar_schema.yml               || foobar_schema.custom.yml                || 
     50|| plugins/myPlugin/config/schema.yml     || myPlugin_schema.custom.yml              || 
     51|| plugins/myPlugin/config/foo_schema.yml || myPlugin_foo_schema.custom.yml          || 
     52 
     53Los esquemas personalizados se buscarán en el directorio config/ de la aplicación y del plugin, 
     54de forma que un esquema pueda redefinir a otro, pudiendo haber más de una personalización 
     55por esquema. 
     56 
     57El plugin combinará los dos esquemas de una manera inteligente, de la siguiente manera: 
     58 
     59{{{ 
     60# Esquema original 
     61################# 
     62propel: 
     63  article: 
     64    _attributes:    { phpName: Article } 
     65    title:          varchar(50) 
     66    user_id:        { type: integer } 
     67    created_at: 
     68 
     69# Personalización del esquema 
     70############### 
     71propel: 
     72  article: 
     73    _attributes:    { phpName: Article, package: foo.bar.lib.model } 
     74    stripped_title: varchar(50) 
     75 
     76# Esquema resultante 
     77################## 
     78propel: 
     79  article: 
     80    _attributes:    { phpName: Article, package: foo.bar.lib.model } 
     81    title:          varchar(50) 
     82    user_id:        { type: integer } 
     83    created_at: 
     84    stripped_title: varchar(50) 
     85}}} 
     86 
     87Al combinarse dos tablas, el plugin examinará el phpName de la tabla como una clave, lo que 
     88posibilita al usuario que pueda modificar el nombre de una tabla en la base de datos, siempre 
     89y cuando mantenga el mismo phpName en el esquema. Aquí presentamos un ejemplo más 
     90complejo: 
     91 
     92{{{ 
     93# Esquema original 
     94################# 
     95propel: 
     96  cd_user: 
     97    _attributes:    { phpName: User } 
     98    first_name:     { type: varchar, size: 255, default: "Anonymous" } 
     99    last_name:      varchar(50) 
     100    age:            { type: integer, required: true, index: true } 
     101    created_at: 
     102   
     103  ij_article: 
     104    _attributes:    { phpName: Article } 
     105    title:          varchar(50) 
     106    user_id:        { type: integer } 
     107    created_at: 
     108    _foreignKeys: 
     109      - 
     110        foreignTable: cd_user 
     111        onDelete:     cascade 
     112        references: 
     113          - { local: user_id, foreign: id } 
     114 
     115# Personalización del esquema 
     116############### 
     117myConnection: 
     118  ab_group: 
     119    _attributes:    { phpName: Group, package: foo.bar.lib.model } 
     120    id: 
     121    name:           varchar(50) 
     122   
     123  ef_user: 
     124    _attributes:    { phpName: User, isI18N: true, i18nTable: cd_user_i18n } 
     125    ab_group_id: 
     126   
     127  ij_article: 
     128    updated_at: 
     129 
     130# Esquema resultante 
     131################## 
     132myConnection: 
     133  ef_user: 
     134    _attributes:    { phpName: User, isI18N: true, i18nTable: cd_user_i18n } 
     135    first_name:     { type: varchar, size: 255, default: "Anonymous" } 
     136    last_name:      varchar(50) 
     137    age:            { type: integer, required: true, index: true } 
     138    created_at: 
     139    ab_group_id: 
     140   
     141  ij_article: 
     142    _attributes:    { phpName: Article } 
     143    title:          varchar(50) 
     144    user_id:        { type: integer } 
     145    created_at: 
     146    updated_at: 
     147    _foreignKeys: 
     148      - 
     149        foreignTable: cd_user 
     150        onDelete:     cascade 
     151        references: 
     152          - { local: user_id, foreign: id } 
     153 
     154  ab_group: 
     155    _attributes:    { phpName: Group, package: foo.bar.lib.model } 
     156    id: 
     157    name:           varchar(50) 
     158}}} 
     159 
     160== Nueva sintaxis del esquema == 
     161 
     162Como alternativa a la actual sintaxis de `schema.yml` (que aún funciona), este complemento se 
     163propone una nueva manera de definir un esquema de base de datos. 
     164 
     165Considere el siguiente esquema, utilizando la actual sintaxis: 
     166 
     167{{{ 
     168propel: 
     169  _attributes:      { noXsd: false, defaultIdMethod: none, package: lib.model } 
     170  ab_group: 
     171    _attributes:    { phpName: Group, package: foo.bar.lib.model } 
     172    id: 
     173    name:           varchar(50) 
     174     
     175  cd_user: 
     176    _attributes:    { phpName: User, isI18N: true, i18nTable: cd_user_i18n } 
     177    first_name:     { type: varchar, size: 255, default: "Anonymous" } 
     178    last_name:      varchar(50) 
     179    age:            { type: integer, required: true, index: true } 
     180    ab_group_id: 
     181    created_at: 
     182   
     183  cd_user_i18n: 
     184    description:    longvarchar 
     185     
     186  ef_article: 
     187    title:          { type: longvarchar, required: true, index: unique } 
     188    stripped_title: { type: longvarchar, required: true, primaryKey: true, sequence: my_custom_sequence_name } 
     189    user_id: 
     190    my_group:       { type: integer, foreignTable: ab_group, foreignReference: id, onDelete: setnull } 
     191    created_at:     timestamp 
     192    updated_at: 
     193 
     194  ij_article: 
     195    _attributes:    { phpName: Article } 
     196    title:          varchar(50) 
     197    user_id:        { type: integer } 
     198    _foreignKeys: 
     199      - 
     200        foreignTable: cd_user 
     201        onDelete:     cascade 
     202        references: 
     203          - { local: user_id, foreign: id } 
     204    created_at: 
     205    _indexes: 
     206      my_index:       [title, user_id] 
     207    _uniques: 
     208      my_other_index: [created_at] 
     209   
     210  ab_group_i18n: 
     211    motto:            longvarchar 
     212}}} 
     213 
     214Con la sintaxis alternativa que este plugin posibilita, y que se implementará en Symfony 1.1. 
     215usted puede escribir el mismo esquema de la siguiente manera: 
     216 
     217{{{ 
     218connection:           propel 
     219noXsd:                false 
     220defaultIdMethod:      none 
     221package:              lib.model 
     222 
     223classes: 
     224  Group: 
     225    tableName:        ab_group 
     226    package:          foo.bar.lib.model 
     227    columns: 
     228      id: 
     229      name:           varchar(50) 
     230   
     231  User: 
     232    tableName:        cd_user 
     233    isI18N:           true 
     234    i18nTable:        cd_user_i18n 
     235    columns: 
     236      first_name:     { type: varchar, size: 255, default: "Anonymous" } 
     237      last_name:      varchar(50) 
     238      age:            { type: integer, required: true, index: true } 
     239      ab_group_id: 
     240      created_at: 
     241   
     242  CdUserI18n: 
     243    columns: 
     244      description:    longvarchar 
     245   
     246  EfArticle: 
     247    columns: 
     248      title:          { type: longvarchar, required: true, index: unique } 
     249      stripped_title: { type: longvarchar, required: true, primaryKey: true, sequence: my_custom_sequence_name } 
     250      user_id: 
     251      my_group:       { type: integer, foreignClass: Group, foreignReference: id, onDelete: setnull } 
     252      created_at:     timestamp 
     253      updated_at: 
     254   
     255  Article: 
     256    tableName:        ij_article 
     257    columns: 
     258      title:          varchar(50) 
     259      user_id:        { type: integer } 
     260      created_at: 
     261    foreignKeys: 
     262      - 
     263        foreignTable: cd_user 
     264        onDelete:     cascade 
     265        references: 
     266          - { local: user_id, foreign: id } 
     267    indexes: 
     268      my_index:       [title, user_id] 
     269    uniques: 
     270      my_other_index: [created_at] 
     271   
     272  AbGroupI18n: 
     273    columns: 
     274      motto:          longvarchar 
     275}}} 
     276 
     277La principal diferencia es que usted declara clases, y no tablas, utilizando el `phpName` de la 
     278tabla como una clave. En caso de no definir un nombre de tabla (`tableName`), el plugin 
     279determinará uno automáticamente basado en el `phpName` utilizando 
     280`sfInflector::underscore()`. 
     281 
     282Esta sintaxis alternativa es también más explícita, ya que usted debe crear entradas para las 
     283clases y las columnas, deshaciéndose de la fea definición de atributos (`_attributes`) de la 
     284actual sintaxis. 
     285 
     286El parámetro de conexión es opcional. Si no se establece, se utilizará `propel` como valor por defecto. 
     287 
     288Tenga en cuenta que puede definir claves foráneas, ya sea con el habitual atributo 
     289`foreignTable` que espera un nombre de tabla, o por medio del nuevo atributo 
     290`foreignClass`, que espera un nombre de clase. 
     291 
     292Por último, pero no menos importante, todos los métodos mágicos de la sintaxis actual se 
     293mantienen (auto definición de claves primarias, claves foráneas, tablas i18n, etc.) 
     294 
     295Una vez que tenga definido su esquema, ejecute la reconstrucción del modelo, como se hace 
     296habitualmente: 
     297 
     298{{{ 
     299$ php symfony propel-build-model 
     300}}} 
     301 
     302El plugin reconocerá automáticamente la sintaxis alternativa. Tenga en cuenta que usted 
     303puede mantener en un proyecto esquemas que combinen la sintaxis actual con la alternativa. 
     304 
     305== Comportamientos (behaviors) == 
     306 
     307La sintaxis de esquemas alternativa le permite definir comportamientos directamente desde el 
     308propio esquema. Para que esto sea posible, hay que cambiar dos líneas en la sección 'Builder 
     309Settings' del archivo `propel.ini` del proyecto: 
     310 
     311{{{ 
     312// In config/propel.ini 
     313; builder settings 
     314propel.builder.peer.class              = plugins.sfPropelAlternativeSchemaPlugin.lib.SfAlternativePeerBuilder 
     315propel.builder.object.class            = plugins.sfPropelAlternativeSchemaPlugin.lib.SfAlternativeObjectBuilder 
     316}}} 
     317 
     318Ahora usted puede añadir una sección `behaviors` para cada clase que usted quiera definir 
     319en el esquema, del siguiente modo: 
     320 
     321{{{ 
     322classes: 
     323  Article: 
     324    columns: 
     325      title:          varchar(50) 
     326    behaviors: 
     327      paranoid:       { column: deleted_at } 
     328}}} 
     329 
     330Naturalmente, no olvide ejecutar una reconstrucción del modelo después de modificar su 
     331esquema. 
     332 
     333También es posible definir comportamientos si se habilita el constructor personalizado en el 
     334archivo `propel.ini`. Simplemente, agregue un guión bajo delantero antes de la clave de 
     335comportamientos (behaviors) y defina los mismos comportamientos que ya añadió antes: 
     336 
     337{{{ 
     338propel: 
     339  ij_article: 
     340    _attributes:    { phpName: Article } 
     341    title:          varchar(50) 
     342    _behaviors: 
     343      paranoid:     { column: deleted_at } 
     344}}} 
     345 
     346 
     347Nota: Los comportamientos introducidos de este modo son registrados en el modelo y en las 
     348clases Peer, lo que parece resolver algunos problemas que se estaban produciendo con los 
     349comportamientos. 
     350 
     351== Esquemas mixtos == 
     352 
     353La personalización de los esquemas se procesa sea cual sea la sintaxis del esquema original y la 
     354sintaxis empleada en el esquema de la personalización. Esto significa que se puede 
     355personalizar un esquema existente que emplea sintaxis antigua usando un esquema de 
     356personalización escrito con la nueva sintaxis, y viceversa. El plugin hará la conversión 
     357internamente de forma que la combinación de ambos esquemas es siempre posible. 
     358 
     359Considere que la fusión de los dos esquemas es más comprensible cuando ambos utilizan la 
     360sintaxis alternativa. De hecho, tal es el formato utilizado por el plugin para la combinación. La 
     361siguiente lista es el mismo ejemplo que el utilizado en la sección “Personalizando un esquema 
     362existente”, excepto porque utiliza la sintaxis alternativa… y comportamientos: 
     363 
     364{{{ 
     365# Esquema original 
     366################# 
     367classes: 
     368  User: 
     369    tableName:        cd_user 
     370    columns: 
     371      first_name:     { type: varchar, size: 255, default: "Anonymous" } 
     372      last_name:      varchar(50) 
     373      age:            { type: integer, required: true, index: true } 
     374      created_at: 
     375   
     376  Article: 
     377    tableName:        ij_article 
     378    columns: 
     379      title:          varchar(50) 
     380      user_id:        { type: integer } 
     381      created_at: 
     382    foreignKeys: 
     383      - 
     384        foreignTable: cd_user 
     385        onDelete:     cascade 
     386        references: 
     387          - { local: user_id, foreign: id } 
     388 
     389# Personalización del esquema 
     390############### 
     391connection: myConnection 
     392classes: 
     393  Group: 
     394    tableName:        ab_group 
     395    package:          foo.bar.lib.model 
     396    behaviors:        [paranoid] 
     397    columns: 
     398      id: 
     399      name:           varchar(50) 
     400 
     401  User: 
     402    tableName:        ef_user 
     403    isI18N:           true 
     404    i18nTable:        cd_user_i18n 
     405    columns: 
     406      ab_group_id: 
     407   
     408  Article: 
     409    columns: 
     410      updated_at: 
     411 
     412# Esquema resultante 
     413################## 
     414connection: myConnection 
     415classes: 
     416  Group: 
     417    tableName:        ab_group 
     418    package:          foo.bar.lib.model 
     419    behaviors:        [paranoid] 
     420    columns: 
     421      id: 
     422      name:           varchar(50) 
     423   
     424  User: 
     425    tableName:        cd_user 
     426    isI18N:           true 
     427    i18nTable:        cd_user_i18n 
     428    columns: 
     429      first_name:     { type: varchar, size: 255, default: "Anonymous" } 
     430      last_name:      varchar(50) 
     431      age:            { type: integer, required: true, index: true } 
     432      ab_group_id: 
     433      created_at: 
     434   
     435  Article: 
     436    tableName:        ij_article 
     437    columns: 
     438      title:          varchar(50) 
     439      user_id:        { type: integer } 
     440      created_at: 
     441      updated_at: 
     442    foreignKeys: 
     443      - 
     444        foreignTable: cd_user 
     445        onDelete:     cascade 
     446        references: 
     447          - { local: user_id, foreign: id } 
     448}}} 
     449 
     450Por claridad, recomendamos utillizar la sintaxis de esquemas alternativa siempre que sea 
     451posible. 
     452 
     453== Comprobando que el plugin está instalado == 
     454 
     455Los esquemas alternativos pueden parecer algunas veces esquemas YAML tradicionales. Si el 
     456plugin no está instalado, es posible que el intérprete del esquema tradicional trate de 
     457transformar un esquema con la sintaxis alternativa en un esquema XML, pero sobre la base de 
     458los esquemas tradicionales. Esto será, probablemente, causa de problemas. 
     459 
     460Para evitar esto, debería asegurarse de que el plugin está instalado antes de intentar 
     461interpretar un esquema YAML de sintaxis alternativa. Para ello, un buen truco es aprovechar el 
     462hecho de que los archivos YAML se ejecutan como archivos PHP, antes de ser convertidos a 
     463arrays. De esta forma, se puede añadir la siguiente línea en la parte superior de cada esquema 
     464YAML escrito con la sintaxis alternativa: 
     465 
     466{{{ 
     467<?php if(!is_callable(array('sfPropelDatabaseSchema', 'convertOldToNewYaml'))) throw new Exception('You must install the sfPropelAlternativeSchemaPlugin to use this schema') ?> 
     468}}}