All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.icymint.libra.jdbc.xml.SqlXml Maven / Gradle / Ivy

package me.icymint.libra.jdbc.xml;

import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;

import me.icymint.libra.jdbc.JdbcAccessException;
import me.icymint.libra.jdbc.model.Column;
import me.icymint.libra.jdbc.model.Database;
import me.icymint.libra.jdbc.model.ForeignKey;
import me.icymint.libra.jdbc.model.Index;
import me.icymint.libra.jdbc.model.SqlFactory;
import me.icymint.libra.jdbc.model.SqlInfo;
import me.icymint.libra.jdbc.model.Table;
import me.icymint.libra.jdbc.model.Unique;
import me.icymint.libra.jdbc.query.TypeTransfer;
import me.icymint.libra.xml.AbstractDTDParser;
import me.icymint.libra.xml.XmlParser;
import me.icymint.libra.xml.XmlParserException;

import org.dom4j.Element;

/**
 * DTD文件
 * 

* Apache DB项目所用的通用数据库ORM对象模型解析器。 *

* Libra-Jdbc项目的ORM模型采用了该方案。 * * @author Daniel Yu * @since 2013-3-12 * */ public class SqlXml extends AbstractDTDParser { private class ColumnHolder { private final boolean iskey; private final Column c; private ColumnHolder(Column c, boolean iskey) { this.c = c; this.iskey = iskey; } } private static class SqlXmlHolder { private final static SqlXml INSTANCE = new SqlXml(); } private class TableHolder { private final Collection fks; private final Table t; private TableHolder(Table t, Collection fks) { this.t = t; this.fks = fks; } } public static XmlParser getInstance() { return SqlXmlHolder.INSTANCE; } private SqlXml() { super(SqlXml.class.getResource("database.dtd"), "http://db.apache.org/torque/dtd/database.dtd", "database"); } private boolean choseBoolean(boolean def, String src) { String match = String.valueOf(!def); if (src != null && match.equals(src)) { return !def; } return def; } @Override protected Database parser(Element root, SqlInfo info) throws XmlParserException { SqlFactory sf = SqlFactory.newInstance(info); sf.getDatabase().setSchema(root.attributeValue("name")); @SuppressWarnings("unchecked") Iterator it = root.elementIterator("table"); Set fks = new LinkedHashSet(); while (it.hasNext()) { fks.add(parserTable(it.next(), sf)); } try { for (TableHolder th : fks) { for (ForeignKey fk : th.fks) { th.t.addForeignKey(fk); } } } catch (Exception e) { throw new XmlParserException(e); } return sf.getDatabase(); } private ColumnHolder parserColumn(Element next, SqlFactory sf) throws XmlParserException { String name = next.attributeValue("name"); String type = next.attributeValue("type").toUpperCase(); String size = next.attributeValue("size"); int length = -1; if (size != null && !size.equals("")) length = Integer.valueOf(size); boolean notnull = choseBoolean(false, next.attributeValue("required")); boolean primaryKey = choseBoolean(false, next.attributeValue("primaryKey")); boolean autoIncrement = choseBoolean(false, next.attributeValue("autoIncrement")); String defaultValue = next.attributeValue("default"); try { return new ColumnHolder(sf.createColumn(name, TypeTransfer .getInstance().reverse(type), length, notnull, autoIncrement, defaultValue), primaryKey); } catch (SQLException e) { throw new XmlParserException(e); } } private ForeignKey parserForeignKey(Element next, SqlFactory sf) throws XmlParserException { String ftable = next.attributeValue("foreignTable"); String local = null; String foreign = null; @SuppressWarnings("unchecked") Iterator it = next.elementIterator("reference"); while (it.hasNext()) { Element ie = it.next(); local = ie.attributeValue("local"); foreign = ie.attributeValue("foreign"); break; } if (local == null || foreign == null) throw new XmlParserException("主外键未设置!"); return new ForeignKey(ftable, local, foreign); } private Index parserIndex(Element next, SqlFactory sf) { String name = next.attributeValue("name"); @SuppressWarnings("unchecked") Iterator it = next.elementIterator("index-column"); Set key = new LinkedHashSet(); while (it.hasNext()) { key.add(it.next().attributeValue("name")); } return new Index(name, key.toArray(new String[] {})); } @SuppressWarnings("unchecked") private TableHolder parserTable(Element next, SqlFactory sf) throws XmlParserException { Iterator it = next.elementIterator("column"); Set set = new LinkedHashSet(); Set key = new LinkedHashSet(); while (it.hasNext()) { ColumnHolder ch = parserColumn(it.next(), sf); set.add(ch.c); if (ch.iskey) key.add(ch.c.getName()); } String name = next.attributeValue("name"); Table t; try { t = sf.createTable(name, key.toArray(new String[] {}), set.toArray(new Column[] {})); sf.getDatabase().addTable(t); } catch (SQLException e) { throw new XmlParserException(e); } it = next.elementIterator("index"); try { while (it.hasNext()) { t.addIndex(parserIndex(it.next(), sf)); } } catch (SQLException e) { throw new XmlParserException(e); } it = next.elementIterator("unique"); try { while (it.hasNext()) { t.addUnique(parserUnique(it.next(), sf)); } } catch (SQLException e) { throw new XmlParserException(e); } it = next.elementIterator("foreign-key"); Set fks = new LinkedHashSet(); while (it.hasNext()) { fks.add(parserForeignKey(it.next(), sf)); } return new TableHolder(t, fks); } private Unique parserUnique(Element next, SqlFactory sf) { String name = next.attributeValue("name"); @SuppressWarnings("unchecked") Iterator it = next.elementIterator("unique-column"); Set key = new LinkedHashSet(); while (it.hasNext()) { key.add(it.next().attributeValue("name")); } return new Unique(name, key.toArray(new String[] {})); } @Override protected void transfer(Element root, Database db) throws XmlParserException { if (db.getSchema() != null) root.addAttribute("name", db.getSchema()); try { for (Table t : db.getTables()) { Element te = root.addElement("table"); te.addAttribute("name", t.getName()); for (Column c : t.getColumns()) { Element ce = te.addElement("column"); ce.addAttribute("name", c.getName()); ce.addAttribute("type", TypeTransfer.getInstance().query(c.getTypes())); int length = c.getLength(); if (length > 0) ce.addAttribute("size", String.valueOf(length)); Object o = c.getDefaultValue(); if (o != null) ce.addAttribute("default", String.valueOf(o)); if (c.isAutoIncrement()) ce.addAttribute("autoIncrement", "true"); if (c.isNotNull()) ce.addAttribute("required", "true"); if (t.getKeys().contains(c)) ce.addAttribute("primaryKey", "true"); } for (Index i : t.getIndexes()) { Element ie = te.addElement("index"); ie.addAttribute("name", i.getName()); for (String v : i.getColumns()) { ie.addElement("index-column").addAttribute("name", v); } } for (Unique i : t.getUniques()) { Element ie = te.addElement("unique"); ie.addAttribute("name", i.getName()); for (String v : i.getColumns()) { ie.addElement("unique-column").addAttribute("name", v); } } for (ForeignKey fk : t.getForeignKeys()) { Element ie = te.addElement("foreign-key"); ie.addAttribute("foreignTable", fk.foreignTable()); Element xx = ie.addElement("reference"); xx.addAttribute("local", fk.getLocalColumn()); xx.addAttribute("foreign", fk.getForeignColumn()); } } } catch (JdbcAccessException e) { throw new XmlParserException(e); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy