Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add support for table options, table behaviors

  • Loading branch information...
commit b83088c2b5bf3a0fa7d03c999d9f521e80255bee 1 parent a861403
@jphpsf authored
View
2  README.markdown
@@ -11,11 +11,9 @@ Tired of hand writing your schema.yml to describe your database schema in Symfon
* Save database schema to schema.yml and sfSqlDesigner.xml
* Load database schema from sfSqlDesigner.xml
* TODO: Load database schema from schema.yml (issues to resolve: restore x/y position and comments)
- * TODO: Proper support for behaviors and table options (ie: not using a datatype hack)
* TODO: Import schema from database as configured in databases.yml
* TODO: Support all options of Doctrine syntax for schema.yml
* Not supported yet: actAsI18n, actAsGeographical, actAsSluggable, actAsSearchable, actAsNestedSet
- * Not supported yet: nested behaviors
* Not supported yet: inheritance
* Not supported yet: indexes
* Not supported yet: one to many and many to many relationships, delete cascade
View
2  modules/sfSqlDesignerPlugin/templates/designerSuccess.php
@@ -61,7 +61,7 @@
<div id="background"></div>
<div id="window">
- <div id="windowtitle"><img id="throbber" src="<?php echo javascript_path('../sfSqlDesignerPlugin/images/throbber.gif'); ?>" alt="" title=""/></div>
+ <div id="windowtitle"><img id="throbber" src="<?php echo image_path('../sfSqlDesignerPlugin/images/throbber.gif'); ?>" alt="" title=""/></div>
<div id="windowcontent"></div>
<input type="button" id="windowok" />
<input type="button" id="windowcancel" />
View
7 web/db/symfony-doctrine/datatypes.xml
@@ -26,11 +26,4 @@
<type label="Gzip" length="1" sql="gzip" quote="'"/>
</group>
- <group label="Table properties" color="rgb(221,221,221)">
- <type label="Class name" length="0" sql="tableClassName" quote="" note="The generated class name"/>
- <type label="Table name" length="0" sql="tableName" quote="" note="The sql table name" />
- <type label="Behaviors" length="0" sql="tableActAs" quote="" note="The behaviors on the table" />
- <type label="Options" length="0" sql="tableOptions" quote="" note="The options for the table" />
- </group>
-
</datatypes>
View
229 web/db/symfony-doctrine/output.xsl
@@ -25,126 +25,157 @@
<xsl:text>:
</xsl:text>
- <!-- get table propertie "rows" -->
- <xsl:for-each select="row">
- <xsl:if test="default">
- <xsl:choose>
- <xsl:when test="datatype='tableName'">
- <xsl:text> tableName: </xsl:text>
- <xsl:value-of select="default"/>
- <xsl:text> ]
+ <!-- tableName in db -->
+ <xsl:if test="tableName">
+ <xsl:text> tableName: </xsl:text>
+ <xsl:value-of select="tableName" />
+ <xsl:text>
</xsl:text>
- </xsl:when>
- <xsl:when test="datatype='tableClassName'">
- <xsl:text> className: </xsl:text>
- <xsl:value-of select="default"/>
- <xsl:text> ]
+ </xsl:if>
+
+ <!-- className in model -->
+ <xsl:if test="className">
+ <xsl:text> className: </xsl:text>
+ <xsl:value-of select="className" />
+ <xsl:text>
</xsl:text>
- </xsl:when>
- <xsl:when test="datatype='tableOptions'">
- <xsl:text> options: [ </xsl:text>
- <xsl:value-of select="default"/>
- <xsl:text> ]
+ </xsl:if>
+
+ <!-- behaviors -->
+ <xsl:text> actAs:
</xsl:text>
- </xsl:when>
- <xsl:when test="datatype='tableActAs'">
- <xsl:text> actAs: [ </xsl:text>
- <xsl:value-of select="default"/>
- <xsl:text> ]
+ <xsl:if test="actAsTimestampable">
+ <xsl:text> Timestampable: ~
</xsl:text>
- </xsl:when>
- </xsl:choose>
- </xsl:if>
- </xsl:for-each>
+ </xsl:if>
+ <xsl:if test="actAsSoftDelete">
+ <xsl:text> SoftDelete: ~
+</xsl:text>
+ </xsl:if>
+ <xsl:if test="actAsVersionable">
+ <xsl:text> Versionable: ~
+</xsl:text>
+ </xsl:if>
+ <xsl:if test="actAsTaggable">
+ <xsl:text> Taggable: ~
+</xsl:text>
+ </xsl:if>
+ <xsl:if test="behaviors">
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="behaviors" />
+ <xsl:text>
+</xsl:text>
+ </xsl:if>
+
+ <!-- options -->
+ <xsl:text> options:
+</xsl:text>
+ <xsl:if test="tableType">
+ <xsl:text> type: </xsl:text>
+ <xsl:value-of select="tableType" />
+ <xsl:text>
+</xsl:text>
+ </xsl:if>
+ <xsl:if test="charset">
+ <xsl:text> charset: </xsl:text>
+ <xsl:value-of select="charset" />
+ <xsl:text>
+</xsl:text>
+ </xsl:if>
+ <xsl:if test="collate">
+ <xsl:text> collate: </xsl:text>
+ <xsl:value-of select="collate" />
+ <xsl:text>
+</xsl:text>
+ </xsl:if>
+
+ <xsl:if test="connection">
+ <xsl:text> connection: </xsl:text>
+ <xsl:value-of select="connection" />
+ <xsl:text>
+</xsl:text>
+ </xsl:if>
<xsl:text> columns:
</xsl:text>
<xsl:for-each select="row">
- <!-- skip table propertie "rows" -->
- <xsl:if test="not(datatype='tableActAs') and not(datatype='tableName') and not(datatype='tableClassName') and not(datatype='tableOptions')">
-
- <!-- if there is a comment, let's display it on its own line starting with # -->
- <xsl:if test="comment">
- <xsl:text> # </xsl:text>
- <xsl:value-of select="comment" />
- <xsl:text>
+ <!-- if there is a comment, let's display it on its own line starting with # -->
+ <xsl:if test="comment">
+ <xsl:text> # </xsl:text>
+ <xsl:value-of select="comment" />
+ <xsl:text>
</xsl:text>
+ </xsl:if>
+
+ <!-- first the name -->
+ <xsl:text> </xsl:text>
+ <xsl:value-of select="@name" />
+ <xsl:text>: { type: </xsl:text>
+
+ <!-- then the datatype -->
+ <xsl:choose>
+ <xsl:when test="contains(datatype,'decimal')">
+ <xsl:value-of select="substring-before(datatype,',')"/>
+ <xsl:text>), scale: </xsl:text>
+ <xsl:value-of select="substring-before(substring-after(datatype,','),')')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="datatype" />
+ </xsl:otherwise>
+ </xsl:choose>
+
+ <!-- is it a primary key? -->
+ <xsl:variable name="rowname" select="@name" />
+ <xsl:for-each select="../key">
+ <xsl:if test="@type = 'PRIMARY'">
+ <xsl:for-each select="part">
+ <xsl:if test=".=$rowname">
+ <xsl:text>, primary: true</xsl:text>
+ </xsl:if>
+ </xsl:for-each>
</xsl:if>
+ </xsl:for-each>
+
+ <!-- can it be null? -->
+ <xsl:if test="@null = 0">
+ <xsl:text>, notnull: true</xsl:text>
+ </xsl:if>
- <!-- first the name -->
- <xsl:text> </xsl:text>
- <xsl:value-of select="@name" />
- <xsl:text>: { type: </xsl:text>
+ <!-- is an autoincrement? -->
+ <xsl:if test="@autoincrement = 1">
+ <xsl:text>, autoincrement: true</xsl:text>
+ </xsl:if>
- <!-- then the datatype -->
+ <!-- default value. for enum list of values, the first will be default -->
+ <xsl:if test="default">
<xsl:choose>
- <xsl:when test="contains(datatype,'decimal')">
- <xsl:value-of select="substring-before(datatype,',')"/>
- <xsl:text>), scale: </xsl:text>
- <xsl:value-of select="substring-before(substring-after(datatype,','),')')"/>
+ <xsl:when test="contains(datatype,'enum')">
+ <xsl:text>, values: [ </xsl:text>
+ <xsl:value-of select="default" />
+ <xsl:text> ]</xsl:text>
+ <xsl:text>, default: </xsl:text>
+ <xsl:choose>
+ <xsl:when test="contains(default,',')">
+ <xsl:value-of select="substring-before(default,',')"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="default" />
+ </xsl:otherwise>
+ </xsl:choose>
</xsl:when>
<xsl:otherwise>
- <xsl:value-of select="datatype" />
+ <xsl:text>, values: [ </xsl:text>
+ <xsl:value-of select="default" />
+ <xsl:text> ]</xsl:text>
</xsl:otherwise>
</xsl:choose>
-
- <!-- is it a primary key? -->
- <xsl:variable name="rowname" select="@name" />
- <xsl:for-each select="../key">
- <xsl:if test="@type = 'PRIMARY'">
- <xsl:for-each select="part">
- <xsl:if test=".=$rowname">
- <xsl:text>, primary: true</xsl:text>
- </xsl:if>
- </xsl:for-each>
- </xsl:if>
- </xsl:for-each>
-
- <!-- can it be null? -->
- <xsl:if test="@null = 0">
- <xsl:text>, notnull: true</xsl:text>
- </xsl:if>
-
- <!-- is an autoincrement? -->
- <xsl:if test="@autoincrement = 1">
- <xsl:text>, autoincrement: true</xsl:text>
- </xsl:if>
-
- <!-- default value. for enum list of values, the first will be default -->
- <xsl:if test="default">
- <xsl:choose>
- <xsl:when test="contains(datatype,'enum')">
- <xsl:text>, values: [ </xsl:text>
- <xsl:value-of select="default" />
- <xsl:text> ]</xsl:text>
- <xsl:text>, default: </xsl:text>
- <xsl:choose>
- <xsl:when test="contains(default,',')">
- <xsl:value-of select="substring-before(default,',')"/>
- </xsl:when>
- <xsl:otherwise>
- <xsl:value-of select="default" />
- </xsl:otherwise>
- </xsl:choose>
- </xsl:when>
- <xsl:otherwise>
- <xsl:text>, values: [ </xsl:text>
- <xsl:value-of select="default" />
- <xsl:text> ]</xsl:text>
- </xsl:otherwise>
- </xsl:choose>
- </xsl:if>
-
-
- <!-- jump to next field -->
- <xsl:text> }
-</xsl:text>
-
- <!-- end if to skip table properties -->
</xsl:if>
+ <!-- jump to next field -->
+ <xsl:text> }
+</xsl:text>
<!-- end loop on rows -->
</xsl:for-each>
View
214 web/js/sfsqldesigner.js
@@ -29,7 +29,17 @@ SQL.Table.prototype.init = function(owner, name, x, y, z) {
this.selected = false;
SQL.Visual.prototype.init.apply(this);
this.data.comment = "";
+ this.data.actAsTimestampable = "";
+ this.data.actActAsSoftDelete = "";
+ this.data.actAsVersionable = "";
+ this.data.actAsTaggable = "";
this.data.behaviors = "";
+ this.data.connection = "";
+ this.data.tableType = "";
+ this.data.collate = "";
+ this.data.charset = "";
+ this.data.className = "";
+ this.data.tableName = "";
this.dom.container.className = "table";
this.setTitle(name);
@@ -54,18 +64,79 @@ SQL.Table.prototype.toXML = function() {
c = c.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
xml += "<comment>"+c+"</comment>\n";
}
+
+ /* add 4 checkbox behaviors */
+ var ats = this.getActAsTimestampable();
+ if (ats==1) {
+ xml += "<actAsTimestampable>1</actAsTimestampable>\n";
+ }
+ var asd = this.getActAsSoftDelete();
+ if (asd==1) {
+ xml += "<actAsSoftDelete>1</actAsSoftDelete>\n";
+ }
+ var avs = this.getActAsVersionable();
+ if (avs==1) {
+ xml += "<actAsVersionable>1</actAsVersionable>\n";
+ }
+ var atg = this.getActAsTaggable();
+ if (atg==1) {
+ xml += "<actAsTaggable>1</actAsTaggable>\n";
+ }
+ /* add behaviors textarea */
var b = this.getBehaviors();
if (b) {
b = b.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
xml += "<behaviors>"+b+"</behaviors>\n";
}
+
+ /* add connection */
+ var conn = this.getConnection();
+ if (conn) {
+ conn = conn.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
+ xml += "<connection>"+conn+"</connection>\n";
+ }
+
+ /* add type */
+ var type = this.getTableType();
+ if (type) {
+ type = type.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
+ xml += "<tableType>"+type+"</tableType>\n";
+ }
+
+ /* add collate */
+ var col = this.getCollate();
+ if (col) {
+ col = col.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
+ xml += "<collate>"+col+"</collate>\n";
+ }
+
+ /* add charset */
+ var charset = this.getCharset();
+ if (charset) {
+ charset = charset.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
+ xml += "<charset>"+charset+"</charset>\n";
+ }
+
+ /* add object class name */
+ var className = this.getClassName();
+ if (className) {
+ className = className.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
+ xml += "<className>"+className+"</className>\n";
+ }
+
+ /* add table name */
+ var tableName = this.getTableName();
+ if (tableName) {
+ tableName = tableName.replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
+ xml += "<tableName>"+tableName+"</tableName>\n";
+ }
+
xml += "</table>\n";
return xml;
}
// override table xml to html code in order to support behaviors and table options
SQL.Table.prototype.fromXML = function(node) {
-//console.log('test');
var name = node.getAttribute("name");
this.setTitle(name);
var x = parseInt(node.getAttribute("x")) || 0;
@@ -86,18 +157,43 @@ SQL.Table.prototype.fromXML = function(node) {
for (var i=0;i<node.childNodes.length;i++) {
var ch = node.childNodes[i];
- console.info(ch);
- if (ch.tagName ) console.log(ch.tagName)
if (ch.tagName && ch.tagName.toLowerCase() == "comment" && ch.firstChild) {
this.setComment(ch.firstChild.nodeValue);
}
- /*if (ch.tagName && ch.tagName.toLowerCase() == "actastimestampable" && ch.firstChild) {
- this.setActAsTimestampable(ch.firstChild.nodeValue);
- }*/
+ if (ch.tagName && ch.tagName.toLowerCase() == "actastimestampable" && ch.firstChild && ch.firstChild.nodeValue==1) {
+ this.setActAsTimestampable(1);
+ }
+ if (ch.tagName && ch.tagName.toLowerCase() == "actassoftdelete" && ch.firstChild && ch.firstChild.nodeValue==1) {
+ this.setActAsSoftDelete(1);
+ }
+ if (ch.tagName && ch.tagName.toLowerCase() == "actasversionable" && ch.firstChild && ch.firstChild.nodeValue==1) {
+ this.setActAsVersionable(1);
+ }
+ if (ch.tagName && ch.tagName.toLowerCase() == "actastaggable" && ch.firstChild && ch.firstChild.nodeValue==1) {
+ this.setActAsTaggable(1);
+ }
if (ch.tagName && ch.tagName.toLowerCase() == "behaviors" && ch.firstChild) {
this.setBehaviors(ch.firstChild.nodeValue);
}
+ if (ch.tagName && ch.tagName.toLowerCase() == "connection" && ch.firstChild) {
+ this.setConnection(ch.firstChild.nodeValue);
+ }
+ if (ch.tagName && ch.tagName.toLowerCase() == "tabletype" && ch.firstChild) {
+ this.setTableType(ch.firstChild.nodeValue);
+ }
+ if (ch.tagName && ch.tagName.toLowerCase() == "collate" && ch.firstChild) {
+ this.setCollate(ch.firstChild.nodeValue);
+ }
+ if (ch.tagName && ch.tagName.toLowerCase() == "charset" && ch.firstChild) {
+ this.setCharset(ch.firstChild.nodeValue);
+ }
+ if (ch.tagName && ch.tagName.toLowerCase() == "classname" && ch.firstChild) {
+ this.setClassName(ch.firstChild.nodeValue);
+ }
+ if (ch.tagName && ch.tagName.toLowerCase() == "tablename" && ch.firstChild) {
+ this.setTableName(ch.firstChild.nodeValue);
+ }
}
}
@@ -108,8 +204,19 @@ SQL.TableManager.prototype.init = function(owner) {
container:OZ.$("table"),
name:OZ.$("tablename"),
comment:OZ.$("tablecomment"),
- behaviors:OZ.$("tablebehaviors")
+ actAsTimestampable:OZ.$("tableacttimestampable"),
+ actActAsSoftDelete:OZ.$("tableactsoftdelete"),
+ actAsVersionable:OZ.$("tableactversionable"),
+ actAsTaggable:OZ.$("tableacttaggable"),
+ behaviors:OZ.$("tablebehaviors"),
+ connection:OZ.$("tableconnection"),
+ tableType:OZ.$("tabletype"),
+ collate:OZ.$("tablecollate"),
+ charset:OZ.$("tablecharset"),
+ className:OZ.$("tableclassname"),
+ tableName:OZ.$("tabletablename")
};
+
this.selected = null;
this.adding = false;
@@ -152,7 +259,17 @@ SQL.TableManager.prototype.edit = function(e) {
this.dom.name.value = title;
try { /* throws in ie6 */
this.dom.comment.value = this.selected.getComment();
+ if (this.selected.getActAsTimestampable()==1) this.dom.actAsTimestampable.checked="checked";
+ if (this.selected.getActAsSoftDelete()==1) this.dom.actActAsSoftDelete.checked="checked";
+ if (this.selected.getActAsVersionable()==1) this.dom.actAsVersionable.checked="checked";
+ if (this.selected.getActAsTaggable()==1) this.dom.actAsTaggable.checked="checked";
this.dom.behaviors.value = this.selected.getBehaviors();
+ this.dom.connection.value = this.selected.getConnection();
+ this.dom.tableType.value = this.selected.getTableType();
+ this.dom.collate.value = this.selected.getCollate();
+ this.dom.charset.value = this.selected.getCharset();
+ this.dom.className.value = this.selected.getClassName();
+ this.dom.tableName.value = this.selected.getTableName();
} catch(e) {}
/* pre-select table name */
@@ -174,6 +291,30 @@ SQL.Table.prototype.getActAsTimestampable = function() {
return this.data.actAsTimestampable;
}
+SQL.Table.prototype.setActAsSoftDelete = function(actAs) {
+ this.data.actAsSoftDelete = actAs;
+}
+
+SQL.Table.prototype.getActAsSoftDelete = function() {
+ return this.data.actAsSoftDelete;
+}
+
+SQL.Table.prototype.setActAsVersionable = function(actAs) {
+ this.data.actAsVersionable = actAs;
+}
+
+SQL.Table.prototype.getActAsVersionable = function() {
+ return this.data.actAsVersionable;
+}
+
+SQL.Table.prototype.setActAsTaggable = function(actAs) {
+ this.data.actAsTaggable = actAs;
+}
+
+SQL.Table.prototype.getActAsTaggable = function() {
+ return this.data.actAsTaggable;
+}
+
SQL.Table.prototype.setBehaviors = function(b){
this.data.behaviors = b;
}
@@ -182,9 +323,66 @@ SQL.Table.prototype.getBehaviors = function() {
return this.data.behaviors;
}
+SQL.Table.prototype.setConnection = function(c){
+ this.data.connection = c;
+}
+
+SQL.Table.prototype.getConnection = function() {
+ return this.data.connection;
+}
+
+SQL.Table.prototype.setTableType = function(t){
+ this.data.tableType = t;
+}
+
+SQL.Table.prototype.getTableType = function() {
+ return this.data.tableType;
+}
+
+SQL.Table.prototype.setCollate = function(c){
+ this.data.collate = c;
+}
+
+SQL.Table.prototype.getCollate = function() {
+ return this.data.collate;
+}
+
+SQL.Table.prototype.setCharset = function(c){
+ this.data.charset = c;
+}
+
+SQL.Table.prototype.getCharset = function() {
+ return this.data.charset;
+}
+
+SQL.Table.prototype.setClassName = function(c){
+ this.data.className = c;
+}
+
+SQL.Table.prototype.getClassName = function() {
+ return this.data.className;
+}
+
+SQL.Table.prototype.setTableName = function(t){
+ this.data.tableName = t;
+}
+
+SQL.Table.prototype.getTableName = function() {
+ return this.data.tableName;
+}
+
SQL.TableManager.prototype.save = function() {
this.selected.setTitle(this.dom.name.value);
this.selected.setComment(this.dom.comment.value);
- //this.selected.setActAsTimestampable(this.dom.actAsTimestampable.value);
+ this.selected.setActAsTimestampable(this.dom.actAsTimestampable.value);
+ this.selected.setActAsSoftDelete(this.dom.actActAsSoftDelete.value);
+ this.selected.setActAsVersionable(this.dom.actAsVersionable.value);
+ this.selected.setActAsTaggable(this.dom.actAsTaggable.value);
this.selected.setBehaviors(this.dom.behaviors.value);
+ this.selected.setConnection(this.dom.connection.value);
+ this.selected.setTableType(this.dom.tableType.value);
+ this.selected.setCollate(this.dom.collate.value);
+ this.selected.setCharset(this.dom.charset.value);
+ this.selected.setClassName(this.dom.className.value);
+ this.selected.setTableName(this.dom.tableName.value);
}
Please sign in to comment.
Something went wrong with that request. Please try again.