You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ibatis.apache.org by cb...@apache.org on 2006/01/22 04:13:47 UTC
svn commit: r371173 - in /ibatis/trunk/java/mapper/mapper2:
src/com/ibatis/sqlmap/engine/mapper/
src/com/ibatis/sqlmap/engine/mapper/metadata/ test/com/ibatis/sqlmap/mapper/
Author: cbegin
Date: Sat Jan 21 19:13:39 2006
New Revision: 371173
URL: http://svn.apache.org/viewcvs?rev=371173&view=rev
Log:
Implemented stats based name matcher for use with auto crud ops generation
Added:
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/Canonicalizer.java
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/Match.java
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/MatchCalculator.java
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/NameMatcher.java
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Column.java
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Database.java
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/DatabaseFactory.java
ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Table.java
ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/
ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/CanonicalizerTest.java
ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/DatabaseMetadataTest.java
ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/MatchCalculatorTest.java
ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/NameMatcherTest.java
Added: ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/Canonicalizer.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/Canonicalizer.java?rev=371173&view=auto
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/Canonicalizer.java (added)
+++ ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/Canonicalizer.java Sat Jan 21 19:13:39 2006
@@ -0,0 +1,177 @@
+package com.ibatis.sqlmap.engine.mapper;
+
+import java.util.StringTokenizer;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+public class Canonicalizer {
+
+ public Map buildCanonicalMap(String[] originals) {
+ return buildCanonicalMap(originals, null);
+ }
+ public Map buildCanonicalMap(String[] originals, String parentName) {
+ Map map = new HashMap();
+ for (int i=0; i < originals.length; i++) {
+ map.put(originals[i], originals[i]);
+ }
+ upperCase(map);
+ removeUnderscores(map);
+ removePKFK(map);
+ removePrefixes(map);
+ removeSuffixes(map);
+ removePluralization(map);
+ removeParentName(map, parentName);
+ return map;
+ }
+
+ private void removeParentName(Map map, String parentName) {
+ if (parentName != null) {
+ parentName = parentName.toUpperCase();
+ Iterator i = map.keySet().iterator();
+ while (i.hasNext()) {
+ String original = (String) i.next();
+ String canonical = (String) map.get(original);
+ if (canonical.startsWith(parentName)) {
+ map.put(original, canonical.substring(parentName.length()));
+ }
+ if (canonical.endsWith(parentName)) {
+ map.put(original, canonical.substring(0, canonical.length() - parentName.length()));
+ }
+ }
+ }
+ }
+
+ private void upperCase(Map map) {
+ Iterator i = map.keySet().iterator();
+ while (i.hasNext()) {
+ String original = (String) i.next();
+ String canonical = (String) map.get(original);
+ map.put(original, canonical.toUpperCase());
+ }
+ }
+
+ private void removePKFK(Map map) {
+ Iterator i = map.keySet().iterator();
+ while (i.hasNext()) {
+ String original = (String) i.next();
+ String canonical = (String) map.get(original);
+ if (canonical.startsWith("PK")) {
+ map.put(original, canonical.substring(2));
+ } else if (canonical.startsWith("FK")) {
+ map.put(original, canonical.substring(2));
+ }
+ if (canonical.endsWith("PK")) {
+ map.put(original, canonical.substring(0, canonical.length() - 2));
+ } else if (canonical.endsWith("FK")) {
+ map.put(original, canonical.substring(0, canonical.length() - 2));
+ }
+ }
+ }
+
+ private void removePrefixes(Map map) {
+ int prefix = findPrefixLength(map);
+
+ if (prefix > 1) {
+ Iterator i = map.keySet().iterator();
+ while (i.hasNext()) {
+ String original = (String) i.next();
+ String canonical = (String) map.get(original);
+ map.put(original, canonical.substring(prefix));
+ }
+ }
+ }
+
+ private void removeSuffixes(Map map) {
+ int suffix = findSuffixLength(map);
+
+ if (suffix > 1) {
+ Iterator i = map.keySet().iterator();
+ while (i.hasNext()) {
+ String original = (String) i.next();
+ String canonical = (String) map.get(original);
+ map.put(original, canonical.substring(0, canonical.length() - suffix));
+ }
+ }
+ }
+
+ private int findPrefixLength(Map map) {
+ String[] originals = (String[])map.keySet().toArray(new String[map.keySet().size()]);
+ char[] samples = ((String) map.get(findShortestString(originals))).toCharArray();
+ int prefix = 0;
+ for (int i=0; i < samples.length; i++) {
+ for (int j=0; j < originals.length; j++) {
+ String original = originals[j];
+ String canonical = (String) map.get(original);
+ if (canonical.charAt(prefix) != samples[i]) {
+ return prefix;
+ }
+ }
+ prefix++;
+ }
+ if (prefix == samples.length) {
+ prefix = 0;
+ }
+ return prefix;
+ }
+
+ private int findSuffixLength(Map map) {
+ String[] originals = (String[])map.keySet().toArray(new String[map.keySet().size()]);
+ char[] samples = ((String) map.get(findShortestString(originals))).toCharArray();
+ int suffix = 0;
+ for (int i=0; i < samples.length; i++) {
+ for (int j=0; j < originals.length; j++) {
+ String original = originals[j];
+ String canonical = (String) map.get(original);
+ if (canonical.charAt(canonical.length() - suffix - 1) != samples[samples.length - i - 1]) {
+ return suffix;
+ }
+ }
+ suffix++;
+ }
+ if (suffix == samples.length) {
+ suffix = 0;
+ }
+ return suffix;
+ }
+
+ private String findShortestString(String[] originals) {
+ String shortest = originals[0];
+ for (int i=0; i < originals.length; i++) {
+ if (originals[i].length() < shortest.length()) {
+ shortest = originals[i];
+ }
+ }
+ return shortest;
+ }
+
+ private void removeUnderscores (Map map) {
+ Iterator i = map.keySet().iterator();
+ while (i.hasNext()) {
+ String original = (String) i.next();
+ String canonical = (String) map.get(original);
+ map.put(original, removeUnderscoresFromString(canonical));
+ }
+ }
+
+ private void removePluralization (Map map) {
+ Iterator i = map.keySet().iterator();
+ while (i.hasNext()) {
+ String original = (String) i.next();
+ String canonical = (String) map.get(original);
+ if (canonical.endsWith("S") || canonical.endsWith("s")) {
+ map.put(original, canonical.substring(0, canonical.length() - 1));
+ }
+ }
+ }
+
+ private String removeUnderscoresFromString (String original) {
+ StringBuffer canonical = new StringBuffer();
+ StringTokenizer parser = new StringTokenizer (original, "_", false);
+ while(parser.hasMoreTokens()) {
+ canonical.append(parser.nextToken());
+ }
+ return canonical.toString();
+ }
+
+}
Added: ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/Match.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/Match.java?rev=371173&view=auto
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/Match.java (added)
+++ ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/Match.java Sat Jan 21 19:13:39 2006
@@ -0,0 +1,32 @@
+package com.ibatis.sqlmap.engine.mapper;
+
+public class Match {
+
+ private String property;
+ private String field;
+ private double matchScore;
+
+ public Match(String property, String field, double matchScore) {
+ this.property = property;
+ this.field = field;
+ this.matchScore = matchScore;
+ }
+
+ public String getProperty() {
+ return property;
+ }
+
+ public String getField() {
+ return field;
+ }
+
+ public double getMatchScore() {
+ return matchScore;
+ }
+
+
+ public String toString() {
+ return property + " => " + field + " ("+matchScore+")";
+ }
+
+}
Added: ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/MatchCalculator.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/MatchCalculator.java?rev=371173&view=auto
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/MatchCalculator.java (added)
+++ ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/MatchCalculator.java Sat Jan 21 19:13:39 2006
@@ -0,0 +1,69 @@
+package com.ibatis.sqlmap.engine.mapper;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Iterator;
+
+public class MatchCalculator {
+
+ private static final int SET_BEGIN = 2;
+ private static final int SET_END = 5;
+ private static final double MAX_VALUE = 1;
+
+ public MatchCalculator() {
+ }
+
+ public double calculateMatch (String first, String second) {
+
+ Set firstSet = buildSets(first);
+ Set secondSet = buildSets(second);
+
+ double value1 = compareSets(firstSet, secondSet);
+ double value2 = compareSets(secondSet, firstSet);
+ return (value1 + value2) / 2;
+ }
+
+ private Set buildSets(String string) {
+ Set set = new HashSet();
+ char[] chars = string.toUpperCase().toCharArray();
+ for (int i = SET_BEGIN; i <= SET_END; i++) {
+ setsOf(i, chars, set);
+ }
+ return set;
+ }
+
+ private void setsOf(int size, char[] chars, Set set) {
+ for (int i=0; i < chars.length - size + 1; i++) {
+ char[] group = new char[size];
+ for (int j=0; j < group.length; j++) {
+ group[j] = chars[i+j];
+ }
+ set.add(new String(group));
+ }
+ }
+
+ private double compareSets(Set firstSet, Set secondSet) {
+ double value = MAX_VALUE;
+ double interval = calculateInterval(firstSet, secondSet);
+ Iterator i = firstSet.iterator();
+ while (i.hasNext()) {
+ String group = (String)i.next();
+ if (!secondSet.contains(group)) {
+ value -= interval;
+ }
+ }
+ return value;
+ }
+
+ private double calculateInterval(Set firstSet, Set secondSet) {
+ double interval;
+ if (firstSet.size() > secondSet.size()) {
+ interval = MAX_VALUE / firstSet.size();
+ } else {
+ interval = MAX_VALUE / secondSet.size();
+ }
+ return interval;
+ }
+
+
+}
Added: ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/NameMatcher.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/NameMatcher.java?rev=371173&view=auto
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/NameMatcher.java (added)
+++ ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/NameMatcher.java Sat Jan 21 19:13:39 2006
@@ -0,0 +1,90 @@
+package com.ibatis.sqlmap.engine.mapper;
+
+import java.util.*;
+
+public class NameMatcher {
+
+ public Map matchNames(String[] properties, String[] fields) {
+ Map propertyMap = invertMap(buildCanonicalMap(properties));
+ Map fieldMap = invertMap(buildCanonicalMap(fields));
+
+ String[] canonicalProperties = setToStringArray(propertyMap.keySet());
+ String[] canonicalFields = setToStringArray(fieldMap.keySet());
+
+ // consider building in both directions
+ // consider tracking which fields have already been mapped to avoid duplicate mappings
+ List matchList = buildMatchList(canonicalProperties, canonicalFields);
+
+ Map matchedNames = new HashMap();
+ Iterator matches = matchList.iterator();
+ while(matches.hasNext()) {
+ Match match = (Match)matches.next();
+ String property = (String) propertyMap.get(match.getProperty());
+ String field = (String) fieldMap.get(match.getField());
+ matchedNames.put(property, field);
+ }
+ return matchedNames;
+ }
+
+ private Map buildCanonicalMap(String[] properties) {
+ return new Canonicalizer().buildCanonicalMap(properties);
+ }
+
+ private String[] setToStringArray(Set set) {
+ return (String[]) set.toArray(new String[set.size()]);
+ }
+
+ private List buildMatchList(String[] canonicalProperties, String[] canonicalFields) {
+ List matchList = new LinkedList();
+ MatchCalculator calc = new MatchCalculator();
+ for (int i = 0; i < canonicalProperties.length; i++) {
+ for (int j = 0; j < canonicalFields.length; j++) {
+ String prop = canonicalProperties[i];
+ String field = canonicalFields[j];
+ double score = calc.calculateMatch(prop, field);
+ Match match = new Match(prop, field, score);
+ matchList.add(match);
+ }
+ }
+ sortMatches(matchList);
+ removeDuplicatesAndLowScores (matchList);
+ return matchList;
+ }
+
+ private void removeDuplicatesAndLowScores(List matchList) {
+ Set usedProperties = new HashSet();
+ Set usedFields = new HashSet();
+ Iterator i = matchList.iterator();
+ while (i.hasNext()) {
+ Match m = (Match)i.next();
+ if (usedProperties.contains(m.getProperty()) || usedFields.contains(m.getField()) || m.getMatchScore() < 0.40) {
+ i.remove();
+ } else {
+ usedProperties.add(m.getProperty());
+ usedFields.add(m.getField());
+ }
+ }
+
+ }
+
+ private void sortMatches(List matchList) {
+ Collections.sort(matchList, new Comparator () {
+ public int compare(Object o1, Object o2) {
+ Match m1 = (Match) o1;
+ Match m2 = (Match) o2;
+ return m1.getMatchScore() < m2.getMatchScore() ? 1 : m1.getMatchScore() > m2.getMatchScore() ? -1 : 0;
+ }
+ });
+ }
+
+ private Map invertMap(Map original) {
+ Map inverse = new HashMap();
+ Iterator keys = original.keySet().iterator();
+ while (keys.hasNext()) {
+ Object key = keys.next();
+ Object value = original.get(key);
+ inverse.put(value, key);
+ }
+ return inverse;
+ }
+}
Added: ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Column.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Column.java?rev=371173&view=auto
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Column.java (added)
+++ ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Column.java Sat Jan 21 19:13:39 2006
@@ -0,0 +1,40 @@
+package com.ibatis.sqlmap.engine.mapper.metadata;
+
+public class Column {
+
+ private String name;
+ private int type;
+
+ public Column(String name, int type) {
+ this.name = name;
+ this.type = type;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final Column column = (Column) o;
+
+ if (type != column.type) return false;
+ if (name != null ? !name.equals(column.name) : column.name != null) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (name != null ? name.hashCode() : 0);
+ result = 29 * result + type;
+ return result;
+ }
+
+}
Added: ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Database.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Database.java?rev=371173&view=auto
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Database.java (added)
+++ ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Database.java Sat Jan 21 19:13:39 2006
@@ -0,0 +1,57 @@
+package com.ibatis.sqlmap.engine.mapper.metadata;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Database {
+
+ private String catalog;
+ private String schema;
+
+ private Map tables = new HashMap();
+
+ public Database(String catalog, String schema) {
+ this.catalog = catalog;
+ this.schema = schema;
+ }
+
+ public String getCatalog() {
+ return catalog;
+ }
+
+ public String getSchema() {
+ return schema;
+ }
+
+ public void addTable(Table table) {
+ tables.put(table.getName(), table);
+ }
+
+ public Table getTable(String name) {
+ return (Table)tables.get(name);
+ }
+
+ public String[] getTableNames() {
+ return (String[])tables.keySet().toArray(new String[tables.size()]);
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final Database database = (Database) o;
+
+ if (catalog != null ? !catalog.equals(database.catalog) : database.catalog != null) return false;
+ if (schema != null ? !schema.equals(database.schema) : database.schema != null) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (catalog != null ? catalog.hashCode() : 0);
+ result = 29 * result + (schema != null ? schema.hashCode() : 0);
+ return result;
+ }
+
+}
Added: ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/DatabaseFactory.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/DatabaseFactory.java?rev=371173&view=auto
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/DatabaseFactory.java (added)
+++ ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/DatabaseFactory.java Sat Jan 21 19:13:39 2006
@@ -0,0 +1,42 @@
+package com.ibatis.sqlmap.engine.mapper.metadata;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.DatabaseMetaData;
+
+public class DatabaseFactory {
+
+ private DatabaseFactory() {
+ }
+
+ public static Database newDatabase (DataSource dataSource, String catalog, String schema) throws SQLException {
+ Database database = new Database (catalog, schema);
+ Connection conn = dataSource.getConnection();
+ ResultSet rs = null;
+ try {
+ DatabaseMetaData dbmd = conn.getMetaData();
+ rs = dbmd.getColumns(catalog, schema, null, null);
+ while (rs.next()) {
+ String tableName = rs.getString ("TABLE_NAME");
+ String columnName = rs.getString ("COLUMN_NAME");
+ int dataType = Integer.parseInt(rs.getString ("DATA_TYPE"));
+ Table table = database.getTable(tableName);
+ if (table == null) {
+ table = new Table(tableName);
+ database.addTable(table);
+ }
+ table.addColumn(new Column(columnName, dataType));
+ }
+ } finally {
+ try {
+ if (rs != null) rs.close();
+ } finally {
+ conn.close();
+ }
+ }
+ return database;
+ }
+
+}
Added: ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Table.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Table.java?rev=371173&view=auto
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Table.java (added)
+++ ibatis/trunk/java/mapper/mapper2/src/com/ibatis/sqlmap/engine/mapper/metadata/Table.java Sat Jan 21 19:13:39 2006
@@ -0,0 +1,47 @@
+package com.ibatis.sqlmap.engine.mapper.metadata;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Table {
+
+ private String name;
+
+ private Map columns = new HashMap();
+
+ public Table(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void addColumn (Column col) {
+ columns.put(col.getName(), col);
+ }
+
+ public Column getColumn (String name) {
+ return (Column) columns.get(name);
+ }
+
+ public String[] getColumnNames () {
+ return (String[])columns.keySet().toArray(new String[columns.size()]);
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final Table table = (Table) o;
+
+ if (name != null ? !name.equals(table.name) : table.name != null) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ return (name != null ? name.hashCode() : 0);
+ }
+
+}
Added: ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/CanonicalizerTest.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/CanonicalizerTest.java?rev=371173&view=auto
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/CanonicalizerTest.java (added)
+++ ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/CanonicalizerTest.java Sat Jan 21 19:13:39 2006
@@ -0,0 +1,104 @@
+package com.ibatis.sqlmap.mapper;
+
+import junit.framework.TestCase;
+import com.ibatis.sqlmap.engine.mapper.Canonicalizer;
+
+import java.util.Map;
+
+public class CanonicalizerTest extends TestCase {
+
+ public void testShouldRemoveUnderscoresFromName () {
+ Canonicalizer matcher = new Canonicalizer();
+ String original = "ACC_FIRST_NAME";
+ String expected = "ACCFIRSTNAME";
+ Map map = matcher.buildCanonicalMap (new String[]{original});
+ String canonical = (String) map.get(original);
+ assertEquals(expected, canonical);
+ }
+
+ public void testShouldUppercase () {
+ Canonicalizer matcher = new Canonicalizer();
+ String original = "AccFirstName";
+ String expected = "ACCFIRSTNAME";
+ Map map = matcher.buildCanonicalMap (new String[]{original});
+ String canonical = (String) map.get(original);
+ assertEquals(expected, canonical);
+ }
+
+ public void testShouldRemovePluralization () {
+ Canonicalizer matcher = new Canonicalizer();
+ String original = "ACCFIRSTNAMES";
+ String expected = "ACCFIRSTNAME";
+ Map map = matcher.buildCanonicalMap (new String[]{original});
+ String canonical = (String) map.get(original);
+ assertEquals(expected, canonical);
+ }
+
+ public void testShouldRemovePrefix () {
+ Canonicalizer matcher = new Canonicalizer();
+ String[] originals = new String[]{"ACC_FIRSTNAME", "ACC_LASTNAME", "ACC_BIRTHDATE", "ACC_LEVEL"};
+ String[] expected = new String[]{"FIRSTNAME", "LASTNAME", "BIRTHDATE", "LEVEL"};
+ Map map = matcher.buildCanonicalMap (originals);
+ for (int i=0; i < originals.length; i++) {
+ String canonical = (String) map.get(originals[i]);
+ assertEquals(expected[i], canonical);
+ }
+ }
+
+ public void testShouldRemoveSuffix () {
+ Canonicalizer matcher = new Canonicalizer();
+ String[] originals = new String[]{"FIRSTNAME_ACC", "LASTNAME_ACC", "BIRTHDATE_ACC", "LEVEL_ACC"};
+ String[] expected = new String[]{"FIRSTNAME", "LASTNAME", "BIRTHDATE", "LEVEL"};
+ Map map = matcher.buildCanonicalMap (originals);
+ for (int i=0; i < originals.length; i++) {
+ String canonical = (String) map.get(originals[i]);
+ assertEquals(expected[i], canonical);
+ }
+ }
+
+ public void testShouldRemovePKFK () {
+ Canonicalizer matcher = new Canonicalizer();
+ String[] originals = new String[]{"PK_FIRSTNAME", "LASTNAME_PK", "BIRTHDATE_FK", "FK_LEVEL"};
+ String[] expected = new String[]{"FIRSTNAME", "LASTNAME", "BIRTHDATE", "LEVEL"};
+ Map map = matcher.buildCanonicalMap (originals);
+ for (int i=0; i < originals.length; i++) {
+ String canonical = (String) map.get(originals[i]);
+ assertEquals(expected[i], canonical);
+ }
+ }
+
+ public void testShouldRemoveParentName () {
+ Canonicalizer matcher = new Canonicalizer();
+ String parentName = "Person";
+ String[] originals = new String[]{"Person_ID, FIRSTNAME", "LASTNAME", "BIRTHDATE", "LEVEL_Person"};
+ String[] expected = new String[]{"ID, FIRSTNAME", "LASTNAME", "BIRTHDATE", "LEVEL"};
+ Map map = matcher.buildCanonicalMap (originals, parentName);
+ for (int i=0; i < originals.length; i++) {
+ String canonical = (String) map.get(originals[i]);
+ assertEquals(expected[i], canonical);
+ }
+ }
+
+ public void testShouldNotRemovePrefixWhenOnlyColumn () {
+ Canonicalizer matcher = new Canonicalizer();
+ String[] originals = new String[]{"ACCFIRSTNAME"};
+ String[] expected = new String[]{"ACCFIRSTNAME"};
+ Map map = matcher.buildCanonicalMap (originals);
+ for (int i=0; i < originals.length; i++) {
+ String canonical = (String) map.get(originals[i]);
+ assertEquals(expected[i], canonical);
+ }
+ }
+
+ public void testShouldNotRemovePrefixWhenSomePrefixesDoNotMatch () {
+ Canonicalizer matcher = new Canonicalizer();
+ String[] originals = new String[]{"ACCFIRSTNAME", "ACCLASTNAME", "ACCBIRTHDATE", "XACCLEVEL"};
+ String[] expected = new String[]{"ACCFIRSTNAME", "ACCLASTNAME", "ACCBIRTHDATE", "XACCLEVEL"};
+ Map map = matcher.buildCanonicalMap (originals);
+ for (int i=0; i < originals.length; i++) {
+ String canonical = (String) map.get(originals[i]);
+ assertEquals(expected[i], canonical);
+ }
+ }
+
+}
Added: ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/DatabaseMetadataTest.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/DatabaseMetadataTest.java?rev=371173&view=auto
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/DatabaseMetadataTest.java (added)
+++ ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/DatabaseMetadataTest.java Sat Jan 21 19:13:39 2006
@@ -0,0 +1,37 @@
+package com.ibatis.sqlmap.mapper;
+
+import com.ibatis.sqlmap.engine.mapper.metadata.Database;
+import com.ibatis.sqlmap.engine.mapper.metadata.DatabaseFactory;
+import com.ibatis.sqlmap.engine.mapper.metadata.Table;
+import com.ibatis.sqlmap.BaseSqlMapTest;
+
+public class DatabaseMetadataTest extends BaseSqlMapTest {
+
+ protected void setUp() throws Exception {
+ initSqlMap("com/ibatis/sqlmap/maps/SqlMapConfig.xml", null);
+ initScript("scripts/account-init.sql");
+ }
+
+ public void testDatabaseMetaData() throws Exception {
+ Database db = DatabaseFactory.newDatabase(sqlMap.getDataSource(), null, null);
+
+ Table table = db.getTable("ACCOUNT");
+
+ assertNotNull(table);
+ assertEquals("ACCOUNT", table.getName());
+
+ String[] columnNames = table.getColumnNames();
+
+ assertEquals(8, columnNames.length);
+
+ assertNotNull(table.getColumn("ACC_BANNER_OPTION"));
+ assertNotNull(table.getColumn("ACC_EMAIL"));
+ assertNotNull(table.getColumn("ACC_FIRST_NAME"));
+ assertNotNull(table.getColumn("ACC_LAST_NAME"));
+ assertNotNull(table.getColumn("ACC_ID"));
+ assertNotNull(table.getColumn("ACC_DATE_ADDED"));
+ assertNotNull(table.getColumn("ACC_AGE"));
+ assertNotNull(table.getColumn("ACC_CART_OPTION"));
+ }
+
+}
Added: ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/MatchCalculatorTest.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/MatchCalculatorTest.java?rev=371173&view=auto
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/MatchCalculatorTest.java (added)
+++ ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/MatchCalculatorTest.java Sat Jan 21 19:13:39 2006
@@ -0,0 +1,36 @@
+package com.ibatis.sqlmap.mapper;
+
+import junit.framework.TestCase;
+import com.ibatis.sqlmap.engine.mapper.MatchCalculator;
+
+public class MatchCalculatorTest extends TestCase {
+
+ public void testWillNotFindMatchesCorrectlyWithoutMoreContext() {
+ assertTrue(isMatch("firstName", "LASTNAME"));
+ assertFalse(isMatch("lastName", "ACC_LAST_NAME"));
+ assertFalse(isMatch("lastName", "ACC_LAST_NAME_FK"));
+ }
+
+ public void testShouldFindMatchesWithinAGivenThreshold() {
+ assertTrue(isMatch("firstName", "FIRSTNAME"));
+ assertTrue(isMatch("firstName", "ACC_FIRSTNAME"));
+ assertTrue(isMatch("firstName", "ACC_FIRST_NAME"));
+ assertTrue(isMatch("firstName", "ACC_FIRST_NAME_FK"));
+ assertTrue(isMatch("id", "id"));
+
+ assertTrue(isMatch("lastName", "LASTNAME"));
+ assertTrue(isMatch("lastName", "ACC_LASTNAME"));
+
+ assertFalse(isMatch("firstName", "ACC_LASTNAME"));
+ assertFalse(isMatch("firstName", "ACC_LAST_NAME"));
+ assertFalse(isMatch("firstName", "ACC_LAST_NAME_FK"));
+ assertFalse(isMatch("id", "PersonId"));
+ }
+
+ private boolean isMatch(String first, String second) {
+ double matchBar = 0.55;
+ return new MatchCalculator().calculateMatch(first, second) >= matchBar;
+ }
+
+
+}
Added: ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/NameMatcherTest.java
URL: http://svn.apache.org/viewcvs/ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/NameMatcherTest.java?rev=371173&view=auto
==============================================================================
--- ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/NameMatcherTest.java (added)
+++ ibatis/trunk/java/mapper/mapper2/test/com/ibatis/sqlmap/mapper/NameMatcherTest.java Sat Jan 21 19:13:39 2006
@@ -0,0 +1,52 @@
+package com.ibatis.sqlmap.mapper;
+
+import com.ibatis.sqlmap.engine.mapper.NameMatcher;
+import junit.framework.TestCase;
+
+import java.util.Map;
+
+public class NameMatcherTest extends TestCase {
+
+ public void testShouldCorrectlyMatchMostOfTheseFairlyComplexNamePairs() {
+ String[] properties = new String[]{"id", "username", "orderDate", "shipAddress1", "shipAddress2", "shipCity", "shipState", "shipZip", "shipCountry", "billAddress1", "billAddress2", "billCity", "billState", "billZip", "billCountry", "courier", "totalPrice", "billToFirstName", "billToLastName", "shipToFirstName", "shipToLastName", "creditCard", "expiryDate", "cardType", "locale", "status"};
+ String[] fields = new String[]{"orderid", "userid", "orderdate", "shipaddr1", "shipaddr2", "shipcity", "shipstate", "shipzip", "shipcountry", "billaddr1", "billaddr2", "billcity", "billstate", "billzip", "billcountry", "courier", "totalprice", "billtofirstname", "billtolastname", "shiptofirstname", "shiptolastname", "creditcard", "exprdate", "cardtype", "locale"};
+ Map map = new NameMatcher().matchNames(fields, properties);
+
+ // unmatched
+ assertNull(map.get("orderid"));
+
+ // match collision, userid matches id better than orderid
+ assertEquals("id", map.get("userid"));
+
+ // good matches
+ assertEquals("cardType", map.get("cardtype"));
+ assertEquals("creditCard", map.get("creditcard"));
+ assertEquals("expiryDate", map.get("exprdate"));
+
+ assertEquals("totalPrice", map.get("totalprice"));
+ assertEquals("courier", map.get("courier"));
+ assertEquals("orderDate", map.get("orderdate"));
+ assertEquals("locale", map.get("locale"));
+
+ assertEquals("billToFirstName", map.get("billtofirstname"));
+ assertEquals("billToLastName", map.get("billtolastname"));
+ assertEquals("billAddress1", map.get("billaddr1"));
+ assertEquals("billAddress2", map.get("billaddr2"));
+ assertEquals("billCity", map.get("billcity"));
+ assertEquals("billState", map.get("billstate"));
+ assertEquals("billCountry", map.get("billcountry"));
+ assertEquals("billZip", map.get("billzip"));
+
+ assertEquals("shipToFirstName", map.get("shiptofirstname"));
+ assertEquals("shipToLastName", map.get("shiptolastname"));
+ assertEquals("shipAddress1", map.get("shipaddr1"));
+ assertEquals("shipAddress2", map.get("shipaddr2"));
+ assertEquals("shipCountry", map.get("shipcountry"));
+ assertEquals("shipZip", map.get("shipzip"));
+ assertEquals("shipCity", map.get("shipcity"));
+ assertEquals("shipState", map.get("shipstate"));
+ }
+
+}
+
+