0001: /*
0002: * Copyright (c) 1998 - 2005 Versant Corporation
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * Versant Corporation - initial API and implementation
0010: */
0011: package com.versant.core.jdbc.sql;
0012:
0013: import java.util.HashMap;
0014: import java.util.HashSet;
0015:
0016: import com.versant.core.common.BindingSupportImpl;
0017:
0018: /**
0019: * The standard name generator. This tries to make sure that generated names
0020: * will be valid for all databases. This ensures that applications deployed
0021: * against different databases maintain the same schema.
0022: */
0023: public class DefaultJdbcNameGenerator implements JdbcNameGenerator {
0024:
0025: protected String databaseType;
0026:
0027: protected int maxTableNameLength = 18;
0028: protected int maxColumnNameLength = 18;
0029: protected int maxConstraintNameLength = 18;
0030: protected int maxIndexNameLength = 18;
0031: protected String pkSuffix = "_id";
0032: protected String pkConstraintPrefix = "pk_";
0033: protected String refConstraintPrefix = "ref_";
0034: protected String wordBreak = "_";
0035: protected String sequenceColumnName = "seq";
0036: protected String valueColumnName = "val";
0037: protected String keyColumnName = "mapkey";
0038:
0039: protected String classIdColumnName = "jdo_class";
0040:
0041: protected String polyRefClassIdSuffix = "_class";
0042: protected String indexNamePrefix = "idx_";
0043:
0044: private boolean nameCanStartWithUnderscore = true;
0045:
0046: protected HashMap reservedWords = new HashMap();
0047:
0048: /**
0049: * This maps a table name to a HashSet of its column names.
0050: */
0051: protected HashMap tableMap = new HashMap();
0052: /**
0053: * All the constraint names we know about.
0054: */
0055: protected HashSet constraintNames = new HashSet();
0056: /**
0057: * All the index names we know about.
0058: */
0059: protected HashSet indexNames = new HashSet();
0060:
0061: public DefaultJdbcNameGenerator() {
0062: populateReservedWords(reservedWords);
0063: }
0064:
0065: /**
0066: * This is called immediately after the name generator has been constructed
0067: * to indicate which database is in use.
0068: */
0069: public void setDatabaseType(String db) {
0070: databaseType = db;
0071: if (db.equals("daffodil")) {
0072: reservedWords.put("connection", "connectn");
0073: reservedWords.put("recursive", "recursve");
0074: reservedWords.put("timestamp", "timestmp");
0075: reservedWords.put("interval", "intervl");
0076: reservedWords.put("email", "eml");
0077: reservedWords.put("action", "actn");
0078: } else if (db.equals("mckoi")) {
0079: reservedWords.put("sequence", "seqnce");
0080: } else if (db.equals("mssql")) {
0081: reservedWords.put("system_user", "sys_user");
0082: reservedWords.put("identity", "ident");
0083: } else if (db.equals("sapdb")) {
0084: reservedWords.put("timestamp", "timestmp");
0085: } else if (db.equals("firebird") || db.equals("interbase")) {
0086: reservedWords.put("position", "positn");
0087: reservedWords.put("admin", "admn");
0088: reservedWords.put("timestamp", "timestmp");
0089: reservedWords.put("action", "actn");
0090: } else if (db.equals("informix") || db.equals("informixse")) {
0091: reservedWords.put("interval", "intervl");
0092: } else if (db.equals("mysql")) {
0093: reservedWords.put("interval", "intervl");
0094: reservedWords.put("change", "chnge");
0095: reservedWords.put("keys", "kys");
0096: reservedWords.put("xor", "xr");
0097: } else if (db.equals("cache")) {
0098: reservedWords.put("connection", "connectn");
0099: reservedWords.put("timestamp", "timestmp");
0100: reservedWords.put("interval", "intrval");
0101: reservedWords.put("action", "actn");
0102: } else if (db.equals("hypersonic")) {
0103: reservedWords.put("position", "pos");
0104: } else if (db.equals("oracle")) {
0105: nameCanStartWithUnderscore = false;
0106: }
0107: }
0108:
0109: /**
0110: * Populate rw with all reserved words and their replacements.
0111: * Any identifiers that match a reserved word will be replaced.
0112: * All keys must be lower case.
0113: */
0114: protected void populateReservedWords(HashMap rw) {
0115: rw.put("abort", "abrt");
0116: rw.put("abs", "ab");
0117: rw.put("absolute", "abslute");
0118: rw.put("accept", "accpt");
0119: rw.put("acces", "accs");
0120: rw.put("access", "accss");
0121: rw.put("activate", "actvate");
0122: rw.put("add", "ad");
0123: rw.put("addform", "addfrm");
0124: rw.put("after", "aftr");
0125: rw.put("all", "al");
0126: rw.put("alter", "altr");
0127: rw.put("and", "nd");
0128: rw.put("andfilename", "andflename");
0129: rw.put("any", "ny");
0130: rw.put("anyfinish", "anyfnish");
0131: rw.put("append", "appnd");
0132: rw.put("archive", "archve");
0133: rw.put("array", "arry");
0134: rw.put("as", "asx");
0135: rw.put("asc", "sc");
0136: rw.put("ascending", "ascnding");
0137: rw.put("ascii", "asci");
0138: rw.put("assert", "assrt");
0139: rw.put("assign", "assgn");
0140: rw.put("at", "atx");
0141: rw.put("attribute", "attrbute");
0142: rw.put("attributes", "attrbutes");
0143: rw.put("audit", "audt");
0144: rw.put("authorization", "athorization");
0145: rw.put("autonext", "atonext");
0146: rw.put("average", "avrage");
0147: rw.put("avg", "av");
0148: rw.put("avgu", "avgup");
0149: rw.put("backout", "bckout");
0150: rw.put("before", "bfore");
0151: rw.put("begin", "bgin");
0152: rw.put("beginload", "bginload");
0153: rw.put("beginmodify", "bginmodify");
0154: rw.put("beginning", "bginning");
0155: rw.put("begwork", "bgwork");
0156: rw.put("between", "btween");
0157: rw.put("betweenby", "btweenby");
0158: rw.put("border", "brder");
0159: rw.put("bottom", "bttom");
0160: rw.put("break", "brak");
0161: rw.put("breakdisplay", "brakdisplay");
0162: rw.put("browse", "brwse");
0163: rw.put("bufered", "bfered");
0164: rw.put("buffer", "bffer");
0165: rw.put("buffered", "bffered");
0166: rw.put("bulk", "blk");
0167: rw.put("by", "byx");
0168: rw.put("byte", "byt");
0169: rw.put("call", "cll");
0170: rw.put("cancel", "cncel");
0171: rw.put("cascade", "cscade");
0172: rw.put("case", "cse");
0173: rw.put("change", "chnge");
0174: rw.put("char", "chr");
0175: rw.put("char_convert", "chr_convert");
0176: rw.put("character", "chracter");
0177: rw.put("check", "chck");
0178: rw.put("checkpoint", "chckpoint");
0179: rw.put("chr2fl", "chr2f");
0180: rw.put("chr2flo", "chr2flt");
0181: rw.put("chr2floa", "chr2fla");
0182: rw.put("chr2float", "chr2flat");
0183: rw.put("chr2int", "chr2nt");
0184: rw.put("clear", "clar");
0185: rw.put("clearrow", "clarrow");
0186: rw.put("clipped", "clpped");
0187: rw.put("close", "clse");
0188: rw.put("cluster", "clustr");
0189: rw.put("clustered", "clstered");
0190: rw.put("clustering", "clstering");
0191: rw.put("cobol", "cbol");
0192: rw.put("cold", "cld");
0193: rw.put("column", "colmn");
0194: rw.put("columns", "clumns");
0195: rw.put("command", "cmmand");
0196: rw.put("comment", "commnt");
0197: rw.put("commit", "cmmit");
0198: rw.put("committed", "cmmitted");
0199: rw.put("compress", "comprss");
0200: rw.put("compute", "cmpute");
0201: rw.put("concat", "cncat");
0202: rw.put("cond", "cnd");
0203: rw.put("config", "cnfig");
0204: rw.put("confirm", "cnfirm");
0205: rw.put("connect", "connct");
0206: rw.put("constraint", "cnstraint");
0207: rw.put("construct", "cnstruct");
0208: rw.put("contain", "cntain");
0209: rw.put("contains", "cntains");
0210: rw.put("continue", "cntinue");
0211: rw.put("controlrow", "cntrolrow");
0212: rw.put("convert", "cnvert");
0213: rw.put("copy", "cpy");
0214: rw.put("count", "cnt");
0215: rw.put("countu", "cntu");
0216: rw.put("countucreate", "cuntucreate");
0217: rw.put("crash", "crsh");
0218: rw.put("create", "creat");
0219: rw.put("current", "currnt");
0220: rw.put("cursor", "crsor");
0221: rw.put("data", "dta");
0222: rw.put("data_pgs", "dta_pgs");
0223: rw.put("database", "dtabase");
0224: rw.put("datapages", "dtapages");
0225: rw.put("date", "dte");
0226: rw.put("day", "dy");
0227: rw.put("daynum", "dynum");
0228: rw.put("dba", "dbax");
0229: rw.put("dbcc", "dbc");
0230: rw.put("dbe", "dbex");
0231: rw.put("dbefile", "dbfile");
0232: rw.put("dbefileo", "dbfileo");
0233: rw.put("dbefileset", "dbfileset");
0234: rw.put("dbspace", "dbspce");
0235: rw.put("dbyte", "dbyt");
0236: rw.put("dec", "dc");
0237: rw.put("decending", "dcending");
0238: rw.put("decimal", "deciml");
0239: rw.put("declare", "dclare");
0240: rw.put("default", "deflt");
0241: rw.put("defaults", "dfaults");
0242: rw.put("defer", "dfer");
0243: rw.put("define", "dfine");
0244: rw.put("definition", "dfinition");
0245: rw.put("delete", "delte");
0246: rw.put("deleterow", "dleterow");
0247: rw.put("desc", "dsc");
0248: rw.put("descending", "dscending");
0249: rw.put("descendng", "dscendng");
0250: rw.put("describe", "dscribe");
0251: rw.put("descriptor", "dscriptor");
0252: rw.put("destpos", "dstpos");
0253: rw.put("destroy", "dstroy");
0254: rw.put("device", "dvice");
0255: rw.put("devspace", "dvspace");
0256: rw.put("direct", "drect");
0257: rw.put("dirty", "drty");
0258: rw.put("disconnect", "dsconnect");
0259: rw.put("disk", "dsk");
0260: rw.put("displace", "dsplace");
0261: rw.put("display", "dsplay");
0262: rw.put("distinct", "distnct");
0263: rw.put("distribution", "dstribution");
0264: rw.put("div", "dv");
0265: rw.put("do", "d");
0266: rw.put("does", "des");
0267: rw.put("domain", "dmain");
0268: rw.put("double", "duble");
0269: rw.put("down", "dwn");
0270: rw.put("drop", "drp");
0271: rw.put("dual", "dal");
0272: rw.put("dummy", "dmmy");
0273: rw.put("dump", "dmp");
0274: rw.put("duplicates", "dplicates");
0275: rw.put("each", "ech");
0276: rw.put("ebcdic", "ebcdc");
0277: rw.put("ed_string", "ed_strng");
0278: rw.put("editadd", "edtadd");
0279: rw.put("editupdate", "edtupdate");
0280: rw.put("else", "els");
0281: rw.put("elseif", "elsif");
0282: rw.put("end", "en");
0283: rw.put("end_error", "end_rror");
0284: rw.put("end_fetch", "end_ftch");
0285: rw.put("end_for", "end_fr");
0286: rw.put("end_get", "end_gt");
0287: rw.put("end_modify", "end_mdify");
0288: rw.put("end_place", "end_plce");
0289: rw.put("end_segment_s", "end_sgment_s");
0290: rw.put("end_segment_string", "end_sgment_string");
0291: rw.put("end_store", "end_stre");
0292: rw.put("end_stream", "end_stram");
0293: rw.put("enddata", "enddta");
0294: rw.put("enddisplay", "enddsplay");
0295: rw.put("endforms", "endfrms");
0296: rw.put("endif", "endf");
0297: rw.put("ending", "endng");
0298: rw.put("endload", "endlad");
0299: rw.put("endloop", "endlop");
0300: rw.put("endmodify", "endmdify");
0301: rw.put("endpos", "endps");
0302: rw.put("endretrieve", "endrtrieve");
0303: rw.put("endselect", "endslect");
0304: rw.put("endwhile", "endwhle");
0305: rw.put("eq", "e");
0306: rw.put("erase", "erse");
0307: rw.put("errlvl", "errlv");
0308: rw.put("error", "errr");
0309: rw.put("errorexit", "errrexit");
0310: rw.put("evaluate", "evluate");
0311: rw.put("evaluating", "evluating");
0312: rw.put("every", "evry");
0313: rw.put("except", "excpt");
0314: rw.put("exclusive", "exclusve");
0315: rw.put("exec", "exc");
0316: rw.put("execute", "excute");
0317: rw.put("exists", "exsts");
0318: rw.put("exit", "ext");
0319: rw.put("explicit", "explcit");
0320: rw.put("extent", "extnt");
0321: rw.put("external", "extrnal");
0322: rw.put("false", "flse");
0323: rw.put("fetch", "ftch");
0324: rw.put("field", "feld");
0325: rw.put("file", "fle");
0326: rw.put("filename", "flename");
0327: rw.put("fillfactor", "fllfactor");
0328: rw.put("finalise", "fnalise");
0329: rw.put("finalize", "fnalize");
0330: rw.put("findstr", "fndstr");
0331: rw.put("finish", "fnish");
0332: rw.put("first", "frst");
0333: rw.put("firstpos", "frstpos");
0334: rw.put("fixed", "fxed");
0335: rw.put("fl", "flx");
0336: rw.put("float", "flt");
0337: rw.put("flush", "flsh");
0338: rw.put("for", "fr");
0339: rw.put("foreach", "freach");
0340: rw.put("format", "frmat");
0341: rw.put("formdata", "frmdata");
0342: rw.put("forminit", "frminit");
0343: rw.put("forms", "frms");
0344: rw.put("fortran", "frtran");
0345: rw.put("found", "foundx");
0346: rw.put("frant", "frnt");
0347: rw.put("fraphic", "frphic");
0348: rw.put("free", "fre");
0349: rw.put("from", "frm");
0350: rw.put("frs", "frss");
0351: rw.put("function", "fnction");
0352: rw.put("get", "gett");
0353: rw.put("getform", "gtform");
0354: rw.put("getoper", "gtoper");
0355: rw.put("getrow", "gtrow");
0356: rw.put("global", "glbal");
0357: rw.put("globals", "glbals");
0358: rw.put("go", "gox");
0359: rw.put("goto", "gotox");
0360: rw.put("grant", "grnt");
0361: rw.put("graphic", "grphic");
0362: rw.put("group", "grp");
0363: rw.put("gt", "gtx");
0364: rw.put("having", "havng");
0365: rw.put("header", "hader");
0366: rw.put("help", "hlp");
0367: rw.put("help_frs", "hlp_frs");
0368: rw.put("helpfile", "hlpfile");
0369: rw.put("hold", "hld");
0370: rw.put("holdlock", "hldlock");
0371: rw.put("identified", "identifd");
0372: rw.put("identifield", "idntifield");
0373: rw.put("if", "ifx");
0374: rw.put("ifdef", "ifdf");
0375: rw.put("ignore", "ignre");
0376: rw.put("image", "imge");
0377: rw.put("immediate", "immediat");
0378: rw.put("immidiate", "immidiat");
0379: rw.put("implicit", "implcit");
0380: rw.put("in", "inx");
0381: rw.put("include", "inclde");
0382: rw.put("increment", "incremnt");
0383: rw.put("index", "indx");
0384: rw.put("indexed", "indxed");
0385: rw.put("indexname", "indxname");
0386: rw.put("indexpages", "indxpages");
0387: rw.put("indicator", "indcator");
0388: rw.put("infield", "infeld");
0389: rw.put("info", "inf");
0390: rw.put("ingres", "ingrs");
0391: rw.put("init", "initt");
0392: rw.put("initial", "initl");
0393: rw.put("initialise", "intialise");
0394: rw.put("initialize", "intialize");
0395: rw.put("inittable", "inttable");
0396: rw.put("input", "inpt");
0397: rw.put("inquir_frs", "inqir_frs");
0398: rw.put("inquire_equel", "inqire_equel");
0399: rw.put("inquire_frs", "inqire_frs");
0400: rw.put("inquire_ingres", "inqire_ingres");
0401: rw.put("insert", "insrt");
0402: rw.put("insertrow", "insrtrow");
0403: rw.put("instructions", "instrctions");
0404: rw.put("int", "inte");
0405: rw.put("int2chr", "int2ch");
0406: rw.put("integer", "integr");
0407: rw.put("integrity", "intgrity");
0408: rw.put("interesect", "intresect");
0409: rw.put("interrupt", "intrrupt");
0410: rw.put("intersect", "intersct");
0411: rw.put("into", "intox");
0412: rw.put("intschr", "intsch");
0413: rw.put("invoke", "invke");
0414: rw.put("is", "isx");
0415: rw.put("isam", "ism");
0416: rw.put("isolation", "islation");
0417: rw.put("journaling", "jurnaling");
0418: rw.put("key", "ky");
0419: rw.put("kill", "kll");
0420: rw.put("label", "lbel");
0421: rw.put("language", "lnguage");
0422: rw.put("last", "lastx");
0423: rw.put("lastpos", "lstpos");
0424: rw.put("le", "lex");
0425: rw.put("left", "lft");
0426: rw.put("length", "lngth");
0427: rw.put("lenstr", "lnstr");
0428: rw.put("let", "lett");
0429: rw.put("level", "lvl");
0430: rw.put("like", "lke");
0431: rw.put("likeproceduretp", "lkeproceduretp");
0432: rw.put("line", "lne");
0433: rw.put("lineno", "lneno");
0434: rw.put("lines", "lnes");
0435: rw.put("link", "lnk");
0436: rw.put("list", "lst");
0437: rw.put("load", "ld");
0438: rw.put("loadtable", "ldtable");
0439: rw.put("loadtableresume", "ldtableresume");
0440: rw.put("local", "lcal");
0441: rw.put("location", "lcation");
0442: rw.put("lock", "lck");
0443: rw.put("locking", "lcking");
0444: rw.put("log", "lg");
0445: rw.put("long", "lng");
0446: rw.put("lower", "lwer");
0447: rw.put("lpad", "lpd");
0448: rw.put("lt", "ltx");
0449: rw.put("main", "mainx");
0450: rw.put("manual", "mnual");
0451: rw.put("manuitem", "manitem");
0452: rw.put("margin", "mrgin");
0453: rw.put("matches", "mtches");
0454: rw.put("matching", "mtching");
0455: rw.put("max", "mx");
0456: rw.put("maxextents", "maxextnts");
0457: rw.put("maxpublicunion", "mxpublicunion");
0458: rw.put("maxreclen", "mxreclen");
0459: rw.put("mdy", "mdyy");
0460: rw.put("menu", "mnu");
0461: rw.put("menuitem", "mnuitem");
0462: rw.put("menuitemscreen", "mnuitemscreen");
0463: rw.put("message", "msg");
0464: rw.put("messagerelocate", "msgrelocate");
0465: rw.put("messagescroll", "msgscroll");
0466: rw.put("mfetch", "mftch");
0467: rw.put("min", "minx");
0468: rw.put("minreclen", "mnreclen");
0469: rw.put("minreturnuntil", "mnreturnuntil");
0470: rw.put("minus", "mnus");
0471: rw.put("mirrorexit", "mrrorexit");
0472: rw.put("missing", "mssing");
0473: rw.put("mixed", "mxed");
0474: rw.put("mlslabel", "mlslabl");
0475: rw.put("mod", "modd");
0476: rw.put("mode", "mde");
0477: rw.put("modify", "modfy");
0478: rw.put("modifyrevokeupdat", "mdifyrevokeupdat");
0479: rw.put("module", "mdule");
0480: rw.put("money", "mney");
0481: rw.put("monitor", "mnitor");
0482: rw.put("month", "mnth");
0483: rw.put("move", "mve");
0484: rw.put("multi", "mlti");
0485: rw.put("name", "nme");
0486: rw.put("ne", "nex");
0487: rw.put("need", "ned");
0488: rw.put("new", "nw");
0489: rw.put("newlog", "nwlog");
0490: rw.put("next", "nxt");
0491: rw.put("nextscrolldown", "nxtscrolldown");
0492: rw.put("no", "nox");
0493: rw.put("noaudit", "noaudt");
0494: rw.put("nocompress", "nocomprss");
0495: rw.put("nocr", "ncr");
0496: rw.put("nojournaling", "njournaling");
0497: rw.put("nolist", "nlist");
0498: rw.put("nolog", "nlog");
0499: rw.put("nonclustered", "nnclustered");
0500: rw.put("normal", "nrmal");
0501: rw.put("nosyssort", "nsyssort");
0502: rw.put("not", "nt");
0503: rw.put("notffound", "ntffound");
0504: rw.put("notfound", "ntfound");
0505: rw.put("notrans", "ntrans");
0506: rw.put("notrim", "ntrim");
0507: rw.put("notrimscrollup", "ntrimscrollup");
0508: rw.put("notrollbackuser", "ntrollbackuser");
0509: rw.put("nowait", "nowt");
0510: rw.put("null", "nll");
0511: rw.put("nullify", "nllify");
0512: rw.put("nullsaveusing", "nllsaveusing");
0513: rw.put("nullval", "nllval");
0514: rw.put("num", "numbr");
0515: rw.put("number", "numbr");
0516: rw.put("numeric", "numerc");
0517: rw.put("nxfield", "nxfeld");
0518: rw.put("of", "ofx");
0519: rw.put("off", "offx");
0520: rw.put("offline", "offln");
0521: rw.put("offsets", "offsts");
0522: rw.put("ofsavepointvalues", "ofsvepointvalues");
0523: rw.put("old", "oldd");
0524: rw.put("on", "onx");
0525: rw.put("once", "onc");
0526: rw.put("online", "onln");
0527: rw.put("onselectwhere", "onslectwhere");
0528: rw.put("onto", "ont");
0529: rw.put("open", "opn");
0530: rw.put("opensetwhile", "opnsetwhile");
0531: rw.put("opensleep", "opnsleep");
0532: rw.put("optimize", "optmize");
0533: rw.put("option", "optn");
0534: rw.put("options", "optons");
0535: rw.put("or", "orx");
0536: rw.put("order", "ordr");
0537: rw.put("ordersqlwork", "ordrsqlwork");
0538: rw.put("orsomewith", "orsmewith");
0539: rw.put("orsort", "orsrt");
0540: rw.put("otherwise", "othrwise");
0541: rw.put("out", "ot");
0542: rw.put("outer", "outerx");
0543: rw.put("output", "outputx");
0544: rw.put("output page", "otput page");
0545: rw.put("outstop", "otstop");
0546: rw.put("over", "ovr");
0547: rw.put("owner", "ownr");
0548: rw.put("ownership", "ownrship");
0549: rw.put("page", "pge");
0550: rw.put("pageno", "pgeno");
0551: rw.put("pages", "pges");
0552: rw.put("param", "parm");
0553: rw.put("partition", "prtition");
0554: rw.put("pascal", "pscal");
0555: rw.put("password", "passwd");
0556: rw.put("pathname", "pthname");
0557: rw.put("pattern", "pttern");
0558: rw.put("pause", "puse");
0559: rw.put("pctfree", "pctfr");
0560: rw.put("percent", "prcent");
0561: rw.put("perm", "prm");
0562: rw.put("permanent", "prmanent");
0563: rw.put("permit", "prmit");
0564: rw.put("permitsum", "prmitsum");
0565: rw.put("pipe", "ppe");
0566: rw.put("place", "plce");
0567: rw.put("plan", "pln");
0568: rw.put("pli", "pl");
0569: rw.put("pos", "ps");
0570: rw.put("power", "pwer");
0571: rw.put("precision", "prcision");
0572: rw.put("prepare", "prpare");
0573: rw.put("preparetable", "prparetable");
0574: rw.put("preserve", "prserve");
0575: rw.put("prev", "prv");
0576: rw.put("previous", "prvious");
0577: rw.put("prevision", "prvision");
0578: rw.put("print", "prnt");
0579: rw.put("printer", "prnter");
0580: rw.put("printscreen", "prntscreen");
0581: rw.put("printscreenscroll", "prntscreenscroll");
0582: rw.put("printsubmenu", "prntsubmenu");
0583: rw.put("printsumu", "prntsumu");
0584: rw.put("prior", "prr");
0585: rw.put("priv", "privx");
0586: rw.put("private", "prvate");
0587: rw.put("privilages", "prvilages");
0588: rw.put("privilagesthen", "prvilagesthen");
0589: rw.put("privileges", "privilgs");
0590: rw.put("proc", "prc");
0591: rw.put("procedure", "prcedure");
0592: rw.put("processexit", "prcessexit");
0593: rw.put("program", "prgram");
0594: rw.put("progusage", "prgusage");
0595: rw.put("prompt", "prmpt");
0596: rw.put("promptscrolldown", "prmptscrolldown");
0597: rw.put("prompttabledata", "prmpttabledata");
0598: rw.put("protect", "prtect");
0599: rw.put("psect", "psct");
0600: rw.put("public", "publc");
0601: rw.put("publicread", "pblicread");
0602: rw.put("put", "pt");
0603: rw.put("putform", "ptform");
0604: rw.put("putformscrollup", "ptformscrollup");
0605: rw.put("putformunloadtab", "ptformunloadtab");
0606: rw.put("putoper", "ptoper");
0607: rw.put("putopersleep", "ptopersleep");
0608: rw.put("putrow", "ptrow");
0609: rw.put("putrowsubmenu", "ptrowsubmenu");
0610: rw.put("putrowup", "ptrowup");
0611: rw.put("query", "qery");
0612: rw.put("quick", "qick");
0613: rw.put("quit", "qit");
0614: rw.put("raiserror", "riserror");
0615: rw.put("range", "rnge");
0616: rw.put("rangeto", "rngeto");
0617: rw.put("raw", "rawx");
0618: rw.put("rdb$db_key", "rdb$db_ky");
0619: rw.put("rdb$length", "rdb$lngth");
0620: rw.put("rdb$missing", "rdb$mssing");
0621: rw.put("rdb$value", "rdb$vlue");
0622: rw.put("rdb4db_key", "rdb4db_ky");
0623: rw.put("rdb4length", "rdb4lngth");
0624: rw.put("rdb4missing", "rdb4mssing");
0625: rw.put("rdb4value", "rdb4vlue");
0626: rw.put("read", "rad");
0627: rw.put("read_only", "rd_only");
0628: rw.put("read_write", "rd_write");
0629: rw.put("readonly", "rdonly");
0630: rw.put("readpass", "rdpass");
0631: rw.put("readtext", "rdtext");
0632: rw.put("readwrite", "rdwrite");
0633: rw.put("ready", "rdy");
0634: rw.put("real", "rl");
0635: rw.put("reconfigure", "rconfigure");
0636: rw.put("reconnect", "rconnect");
0637: rw.put("record", "rcord");
0638: rw.put("recover", "rcover");
0639: rw.put("redisplay", "rdisplay");
0640: rw.put("redisplaytabledata", "rdisplaytabledata");
0641: rw.put("redisplayvalidate", "rdisplayvalidate");
0642: rw.put("reduced", "rduced");
0643: rw.put("register", "rgister");
0644: rw.put("registerunloaddata", "rgisterunloaddata");
0645: rw.put("registervalidrow", "rgistervalidrow");
0646: rw.put("reject", "rject");
0647: rw.put("relative", "rlative");
0648: rw.put("release", "rlease");
0649: rw.put("reload", "rload");
0650: rw.put("relocate", "rlocate");
0651: rw.put("relocateunique", "rlocateunique");
0652: rw.put("remove", "rmove");
0653: rw.put("removeuprelocatev", "rmoveuprelocatev");
0654: rw.put("removevalidate", "rmovevalidate");
0655: rw.put("removewhenever", "rmovewhenever");
0656: rw.put("rename", "renme");
0657: rw.put("repeat", "rpeat");
0658: rw.put("repeatable", "rpeatable");
0659: rw.put("repeated", "rpeated");
0660: rw.put("repeatvalidrow", "rpeatvalidrow");
0661: rw.put("replace", "rplace");
0662: rw.put("replaceuntil", "rplaceuntil");
0663: rw.put("replstr", "rplstr");
0664: rw.put("report", "rport");
0665: rw.put("request_handle", "rquest_handle");
0666: rw.put("reserved_pgs", "rserved_pgs");
0667: rw.put("reserving", "rserving");
0668: rw.put("reset", "rset");
0669: rw.put("resource", "resrce");
0670: rw.put("rest", "rst");
0671: rw.put("restart", "rstart");
0672: rw.put("restore", "rstore");
0673: rw.put("restrict", "rstrict");
0674: rw.put("resume", "rsume");
0675: rw.put("retrieve", "rtrieve");
0676: rw.put("retrieveupdate", "rtrieveupdate");
0677: rw.put("return", "rturn");
0678: rw.put("returning", "rturning");
0679: rw.put("revoke", "revke");
0680: rw.put("right", "rght");
0681: rw.put("role", "rle");
0682: rw.put("rollback", "rllback");
0683: rw.put("rollforward", "rllforward");
0684: rw.put("rololback", "rlolback");
0685: rw.put("round", "rund");
0686: rw.put("row", "rowx");
0687: rw.put("rowcnt", "rwcnt");
0688: rw.put("rowcount", "rwcount");
0689: rw.put("rowid", "rwid");
0690: rw.put("rownum", "rwnum");
0691: rw.put("rows", "rws");
0692: rw.put("rpad", "rpd");
0693: rw.put("rule", "rle");
0694: rw.put("run", "rn");
0695: rw.put("runtime", "rntime");
0696: rw.put("samplstdev", "smplstdev");
0697: rw.put("save", "sve");
0698: rw.put("savepoint", "svepoint");
0699: rw.put("savepointwhere", "svepointwhere");
0700: rw.put("saveview", "sveview");
0701: rw.put("schema", "schma");
0702: rw.put("scope", "scpe");
0703: rw.put("screen", "scren");
0704: rw.put("scroll", "scrll");
0705: rw.put("scrolldown", "scrlldown");
0706: rw.put("scrollup", "scrllup");
0707: rw.put("search", "sarch");
0708: rw.put("segment", "sgment");
0709: rw.put("sel", "sl");
0710: rw.put("sele", "sle");
0711: rw.put("selec", "slec");
0712: rw.put("select", "selct");
0713: rw.put("selupd", "slupd");
0714: rw.put("serial", "srial");
0715: rw.put("session", "sessn");
0716: rw.put("set", "st");
0717: rw.put("set_equel", "st_equel");
0718: rw.put("set_frs", "st_frs");
0719: rw.put("set_ingres", "st_ingres");
0720: rw.put("setuser", "stuser");
0721: rw.put("setwith", "stwith");
0722: rw.put("share", "shre");
0723: rw.put("shared", "shred");
0724: rw.put("short", "shrt");
0725: rw.put("show", "shw");
0726: rw.put("shutdown", "shtdown");
0727: rw.put("size", "sze");
0728: rw.put("skip", "skp");
0729: rw.put("sleep", "slep");
0730: rw.put("smallfloat", "smllfloat");
0731: rw.put("smallint", "smallnt");
0732: rw.put("some", "sme");
0733: rw.put("sort", "srt");
0734: rw.put("sorterd", "srterd");
0735: rw.put("sounds", "sunds");
0736: rw.put("sourcepos", "surcepos");
0737: rw.put("space", "spce");
0738: rw.put("spaces", "spces");
0739: rw.put("sql", "sq");
0740: rw.put("sqlcode", "sqlcde");
0741: rw.put("sqlda", "sqld");
0742: rw.put("sqlerror", "sqlrror");
0743: rw.put("sqlexeption", "sqlxeption");
0744: rw.put("sqlexplain", "sqlxplain");
0745: rw.put("sqlnotfound", "sqlntfound");
0746: rw.put("sqrt", "sqr");
0747: rw.put("stability", "stbility");
0748: rw.put("start", "strt");
0749: rw.put("start_segment", "strt_segment");
0750: rw.put("start_segmented_?", "strt_segmented");
0751: rw.put("start_stream", "strt_stream");
0752: rw.put("start_transaction", "strt_transaction");
0753: rw.put("starting", "strting");
0754: rw.put("startpos", "strtpos");
0755: rw.put("state", "stte");
0756: rw.put("statistics", "sttistics");
0757: rw.put("stdev", "stdv");
0758: rw.put("step", "stepx");
0759: rw.put("stop", "stopx");
0760: rw.put("store", "stre");
0761: rw.put("string", "strng");
0762: rw.put("submenu", "sbmenu");
0763: rw.put("substr", "sbstr");
0764: rw.put("succesfull", "sccesfull");
0765: rw.put("successful", "successfl");
0766: rw.put("successfull", "sccessfull");
0767: rw.put("sum", "sm");
0768: rw.put("sumu", "smu");
0769: rw.put("superdba", "sperdba");
0770: rw.put("syb_terminate", "syb_trminate");
0771: rw.put("synonym", "synonm");
0772: rw.put("sysdate", "sysdte");
0773: rw.put("syssort", "syssrt");
0774: rw.put("table", "tble");
0775: rw.put("tabledata", "tbledata");
0776: rw.put("temp", "tmp");
0777: rw.put("temporary", "tmporary");
0778: rw.put("terminate", "trminate");
0779: rw.put("text", "txt");
0780: rw.put("textsize", "txtsize");
0781: rw.put("then", "thn");
0782: rw.put("through", "thrugh");
0783: rw.put("thru", "thr");
0784: rw.put("tid", "td");
0785: rw.put("time", "tme");
0786: rw.put("to", "tox");
0787: rw.put("today", "tday");
0788: rw.put("tolower", "tlower");
0789: rw.put("top", "topp");
0790: rw.put("total", "ttal");
0791: rw.put("toupper", "tupper");
0792: rw.put("tp", "tpx");
0793: rw.put("trailer", "triler");
0794: rw.put("tran", "trn");
0795: rw.put("trans", "trns");
0796: rw.put("transaction", "trnsaction");
0797: rw.put("transaction_handle", "trnsaction_handle");
0798: rw.put("transfer", "trnsfer");
0799: rw.put("trigger", "triggr");
0800: rw.put("tring", "trng");
0801: rw.put("true", "tre");
0802: rw.put("trunc", "trnc");
0803: rw.put("truncate", "trncate");
0804: rw.put("tsequal", "tsqual");
0805: rw.put("type", "typ");
0806: rw.put("uid", "uidx");
0807: rw.put("unbuffered", "unbffered");
0808: rw.put("union", "unn");
0809: rw.put("unique", "unque");
0810: rw.put("unload", "unlad");
0811: rw.put("unloaddata", "unladdata");
0812: rw.put("unloadtable", "unladtable");
0813: rw.put("unlock", "unlck");
0814: rw.put("until", "untl");
0815: rw.put("up", "u");
0816: rw.put("update", "updte");
0817: rw.put("upper", "uppr");
0818: rw.put("usage", "usge");
0819: rw.put("use", "us");
0820: rw.put("used_pgs", "usd_pgs");
0821: rw.put("user", "usr");
0822: rw.put("using", "usng");
0823: rw.put("validate", "validte");
0824: rw.put("validrow", "vlidrow");
0825: rw.put("value", "val");
0826: rw.put("values", "vals");
0827: rw.put("varc", "vrc");
0828: rw.put("varch", "vrch");
0829: rw.put("varcha", "vrcha");
0830: rw.put("varchar", "varchr");
0831: rw.put("varchar2", "varch2r");
0832: rw.put("vargraphic", "vrgraphic");
0833: rw.put("verb_time", "vrb_time");
0834: rw.put("verify", "vrify");
0835: rw.put("version", "vrsion");
0836: rw.put("view", "vw");
0837: rw.put("wait", "wit");
0838: rw.put("waitfor", "witfor");
0839: rw.put("waiting", "witing");
0840: rw.put("warning", "wrning");
0841: rw.put("weekday", "wekday");
0842: rw.put("when", "whn");
0843: rw.put("whenever", "whenevr");
0844: rw.put("where", "whre");
0845: rw.put("while", "whle");
0846: rw.put("window", "wndow");
0847: rw.put("with", "wth");
0848: rw.put("without", "wthout");
0849: rw.put("work", "wrk");
0850: rw.put("wrap", "wrp");
0851: rw.put("write", "wrte");
0852: rw.put("writepass", "wrtepass");
0853: rw.put("writetext", "wrtetext");
0854: rw.put("year", "yr");
0855: }
0856:
0857: public int getMaxTableNameLength() {
0858: return maxTableNameLength;
0859: }
0860:
0861: /**
0862: * Set the max length in characters for a table name.
0863: */
0864: public void setMaxTableNameLength(int maxTableNameLength) {
0865: this .maxTableNameLength = maxTableNameLength;
0866: }
0867:
0868: public int getMaxColumnNameLength() {
0869: return maxColumnNameLength;
0870: }
0871:
0872: /**
0873: * Set the max length in characters for a column name.
0874: */
0875: public void setMaxColumnNameLength(int maxColumnNameLength) {
0876: this .maxColumnNameLength = maxColumnNameLength;
0877: }
0878:
0879: public String getPkSuffix() {
0880: return pkSuffix;
0881: }
0882:
0883: /**
0884: * Set the max length in characters for a constraint name.
0885: */
0886: public void setMaxConstraintNameLength(int maxConstraintNameLength) {
0887: this .maxConstraintNameLength = maxConstraintNameLength;
0888: }
0889:
0890: public int getMaxConstraintNameLength() {
0891: return maxConstraintNameLength;
0892: }
0893:
0894: /**
0895: * Set the max length in characters for an index name.
0896: */
0897: public void setMaxIndexNameLength(int maxIndexNameLength) {
0898: this .maxIndexNameLength = maxIndexNameLength;
0899: }
0900:
0901: public int getMaxIndexNameLength() {
0902: return maxIndexNameLength;
0903: }
0904:
0905: /**
0906: * Set the suffix added to table or field names to name primary key
0907: * columns. The default is _id so the pk for the employee table will
0908: * be employee_id.
0909: */
0910: public void setPkSuffix(String pkSuffix) {
0911: this .pkSuffix = pkSuffix;
0912: }
0913:
0914: public String getPkConstraintPrefix() {
0915: return pkConstraintPrefix;
0916: }
0917:
0918: /**
0919: * Set the prefix added to a table name to generate its primary key
0920: * constraint name.
0921: */
0922: public void setPkConstraintPrefix(String pkConstraintPrefix) {
0923: this .pkConstraintPrefix = pkConstraintPrefix;
0924: }
0925:
0926: /**
0927: * Set the string used to break 'words' when generating names from
0928: * field and class names and so on.
0929: */
0930: public void setWordBreak(String wordBreak) {
0931: this .wordBreak = wordBreak;
0932: }
0933:
0934: public String getWordBreak() {
0935: return wordBreak;
0936: }
0937:
0938: /**
0939: * Set the name used for sequence columns in link tables. These are used
0940: * to preserve the order of elements in ordered collections (lists and
0941: * arrays).
0942: */
0943: public void setSequenceColumnName(String sequenceColumnName) {
0944: this .sequenceColumnName = sequenceColumnName;
0945: }
0946:
0947: public String getSequenceColumnName() {
0948: return sequenceColumnName;
0949: }
0950:
0951: /**
0952: * Set the name used for value columns in link tables where the values
0953: * are not references to PC instances.
0954: */
0955: public void setValueColumnName(String valueColumnName) {
0956: this .valueColumnName = valueColumnName;
0957: }
0958:
0959: public String getValueColumnName() {
0960: return valueColumnName;
0961: }
0962:
0963: /**
0964: * Set the name used for keys columns in link tables for maps where the
0965: * keys are not references to PC instances.
0966: */
0967: public void setKeyColumnName(String keyColumnName) {
0968: this .keyColumnName = keyColumnName;
0969: }
0970:
0971: public String getKeyColumnName() {
0972: return keyColumnName;
0973: }
0974:
0975: /**
0976: * Set the name used for classId columns. These are added to the table for
0977: * the base class in an inheritance heirachy.
0978: */
0979: public void setClassIdColumnName(String classIdColumnName) {
0980: this .classIdColumnName = classIdColumnName;
0981: }
0982:
0983: public String getClassIdColumnName() {
0984: return classIdColumnName;
0985: }
0986:
0987: public String getIndexNamePrefix() {
0988: return indexNamePrefix;
0989: }
0990:
0991: /**
0992: * Set the prefix used to generate index names.
0993: */
0994: public void setIndexNamePrefix(String indexNamePrefix) {
0995: this .indexNamePrefix = indexNamePrefix;
0996: }
0997:
0998: /**
0999: * Generate a JDBC name from a java class or field name. This breaks
1000: * the name at each capital inserting underscores and converts to
1001: * lower case. If the name turns out to be a reserved word it is replaced.
1002: * Any leading underscores are removed.
1003: * '$' are also removed.
1004: */
1005: protected String getJdbcName(String name) {
1006: int n = name.length();
1007: StringBuffer ans = new StringBuffer(n + 4);
1008: int i = 0;
1009: for (; i < n && name.charAt(i) == '_'; i++)
1010: ;
1011: for (; i < n; i++) {
1012: char c = name.charAt(i);
1013: if (Character.isUpperCase(c)) {
1014: c = Character.toLowerCase(c);
1015: if (i > 0)
1016: ans.append(wordBreak);
1017: }
1018: if (c == '/') {
1019: ans.append(wordBreak);
1020: } else if (c != '$' && c != '.') {
1021: ans.append(c);
1022: }
1023: }
1024: name = ans.toString();
1025: String rep = (String) reservedWords.get(name);
1026: if (rep != null)
1027: name = rep;
1028: return name;
1029: }
1030:
1031: /**
1032: * Shrink the supplied name to maxlen chars if it is longer than maxlen.
1033: * This implementation removes vowels first and then truncates if it has
1034: * to.
1035: */
1036: protected String shrinkName(String name, int maxlen) {
1037: if (!nameCanStartWithUnderscore) {
1038: int n = name.length();
1039: int j = 0;
1040: for (; j < n && name.charAt(j) == '_'; j++)
1041: ;
1042: name = name.substring(j, n);
1043: }
1044: int len = name.length();
1045: if (len <= maxlen)
1046: return name;
1047: int todo = len - maxlen;
1048: StringBuffer s = new StringBuffer();
1049: s.append(name.charAt(0));
1050: int i;
1051: for (i = 1; todo > 0 && i < len;) {
1052: char c = name.charAt(i++);
1053: if (c == 'e' || c == 'a' || c == 'i' || c == 'o'
1054: || c == 'u') {
1055: --todo;
1056: } else {
1057: s.append(c);
1058: }
1059: }
1060: if (todo == 0) {
1061: s.append(name.substring(i));
1062: }
1063: if (s.length() > maxlen)
1064: s.setLength(maxlen);
1065: return s.toString();
1066: }
1067:
1068: /**
1069: * Generate a new name comprised of name with i appended. Characters are
1070: * stripped from the end of name to make space for i if maxLen would
1071: * be exceeded. This is used to resolve generated name clashes.
1072: */
1073: protected String appendInt(String name, int i, int maxLen) {
1074: String is = Integer.toString(i);
1075: int cut = name.length() + is.length() - maxLen;
1076: if (cut > 0) {
1077: int len = maxLen - cut;
1078: if (len < 1)
1079: len = 1;
1080: return name.substring(0, len) + is;
1081: } else {
1082: return name + is;
1083: }
1084: }
1085:
1086: /**
1087: * Add a table name specified in jdo meta data.
1088: *
1089: * @throws IllegalArgumentException if the name is invalid
1090: * (e.g. 'duplicate table name' or 'invalid character XXX in name'
1091: * etc.)
1092: */
1093: public void addTableName(String name)
1094: throws IllegalArgumentException {
1095: if (tableMap.containsKey(name)) {
1096: throw BindingSupportImpl.getInstance().illegalArgument(
1097: "Duplicate table name '" + name + "'");
1098: }
1099: tableMap.put(name, new HashSet());
1100: }
1101:
1102: /**
1103: * Remove all information about table.
1104: */
1105: public void removeTableName(String name) {
1106: tableMap.remove(name);
1107: }
1108:
1109: /**
1110: * Generate a table name for a persistent class. The name generator must
1111: * 'add' it.
1112: *
1113: * @see #addTableName
1114: */
1115: public String generateClassTableName(String className) {
1116: int dot = className.lastIndexOf('.');
1117: if (dot >= 0)
1118: className = className.substring(dot + 1);
1119:
1120: String name = shrinkName(getJdbcName(className),
1121: maxTableNameLength);
1122: String n = name;
1123: for (int i = 2; tableMap.containsKey(n); i++) {
1124: n = appendInt(name, i, maxTableNameLength);
1125: }
1126: addTableName(n);
1127: return n;
1128: }
1129:
1130: /**
1131: * Generate a table name for a link table (normally used to hold the values
1132: * of a collection or array). The name generator must 'add' it.
1133: *
1134: * @param tableName The table on the 1 side of the the link
1135: * @param fieldName The field the link table is for
1136: * @param elementTableName The table on the n side of the link or null if
1137: * none (e.g. a link table for a collection of String's)
1138: * @see #addTableName
1139: */
1140: public String generateLinkTableName(String tableName,
1141: String fieldName, String elementTableName) {
1142: String name;
1143: if (elementTableName == null) {
1144: name = tableName + wordBreak + getJdbcName(fieldName);
1145: } else {
1146: name = tableName + wordBreak + elementTableName;
1147: }
1148: name = shrinkName(name, maxTableNameLength);
1149: String n = name;
1150: for (int i = 2; tableMap.containsKey(n); i++) {
1151: n = appendInt(name, i, maxTableNameLength);
1152: }
1153: addTableName(n);
1154: return n;
1155: }
1156:
1157: /**
1158: * Add the primary key constaint name specified in jdo meta data.
1159: *
1160: * @throws IllegalArgumentException if it is invalid
1161: */
1162: public void addPkConstraintName(String tableName,
1163: String pkConstraintName) throws IllegalArgumentException {
1164: if (constraintNames.contains(pkConstraintName)) {
1165: throw BindingSupportImpl.getInstance().illegalArgument(
1166: "Duplicate constraint name: " + pkConstraintName);
1167: }
1168: constraintNames.add(pkConstraintName);
1169: }
1170:
1171: /**
1172: * Generate a name for the primary key constaint for tableName.
1173: */
1174: public String generatePkConstraintName(String tableName) {
1175: int maxlen = maxConstraintNameLength
1176: - pkConstraintPrefix.length();
1177: String name = pkConstraintPrefix
1178: + shrinkName(tableName, maxlen);
1179: String n = name;
1180: for (int i = 2; constraintNames.contains(n); i++) {
1181: n = appendInt(name, i, maxConstraintNameLength);
1182: }
1183: addPkConstraintName(tableName, n);
1184: return n;
1185: }
1186:
1187: /**
1188: * Add the referential integrity constaint name specified in jdo meta data.
1189: *
1190: * @throws IllegalArgumentException if it is invalid
1191: */
1192: public void addRefConstraintName(String tableName,
1193: String refConstraintName) throws IllegalArgumentException {
1194: if (constraintNames.contains(refConstraintName)) {
1195: throw BindingSupportImpl.getInstance().illegalArgument(
1196: "Duplicate constraint name: " + refConstraintName);
1197: }
1198: constraintNames.add(refConstraintName);
1199: }
1200:
1201: /**
1202: * Generate a name for a referential integrity constaint for tableName.
1203: * The name generator must add it.
1204: *
1205: * @param tableName The table with the constraint
1206: * @param refTableName The table being referenced
1207: * @param fkNames The names of the foreign keys in tableName
1208: * @param refPkNames The names of the primary key of refTableName
1209: * @see #addRefConstraintName
1210: */
1211: public String generateRefConstraintName(String tableName,
1212: String refTableName, String[] fkNames, String[] refPkNames) {
1213: int maxlen = maxConstraintNameLength
1214: - refConstraintPrefix.length();
1215: String name = refConstraintPrefix
1216: + shrinkName(tableName + wordBreak + refTableName,
1217: maxlen);
1218: String n = name;
1219: for (int i = 2; constraintNames.contains(n); i++) {
1220: n = appendInt(name, i, maxConstraintNameLength);
1221: }
1222: addRefConstraintName(tableName, n);
1223: return n;
1224: }
1225:
1226: /**
1227: * Add a column name. The tableName will have already been added.
1228: *
1229: * @throws IllegalArgumentException if the name is invalid
1230: * (e.g. 'duplicate column name' or 'invalid character XXX in name'
1231: * etc.)
1232: */
1233: public void addColumnName(String tableName, String columnName)
1234: throws IllegalArgumentException {
1235: String err = addColumnNameImp(tableName, columnName);
1236: if (err != null)
1237: throw BindingSupportImpl.getInstance().illegalArgument(err);
1238: }
1239:
1240: /**
1241: * Does the table contain the column?
1242: */
1243: public boolean isColumnInTable(String tableName, String columnName) {
1244: HashSet cols = (HashSet) tableMap.get(tableName);
1245: if (cols == null) {
1246: throw BindingSupportImpl.getInstance().internal(
1247: "isColumnInTable called with unknown table: '"
1248: + tableName + "'");
1249: }
1250: return cols.contains(columnName);
1251: }
1252:
1253: /**
1254: * Add a column name. The tableName will have already been added.
1255: *
1256: * @return null if ok or error message
1257: */
1258: protected String addColumnNameImp(String tableName,
1259: String columnName) {
1260: HashSet cols = (HashSet) tableMap.get(tableName);
1261: if (cols == null) {
1262: throw BindingSupportImpl.getInstance().internal(
1263: "addColumnName called with unknown table: '"
1264: + tableName + "'");
1265: }
1266: if (cols.contains(columnName)) {
1267: return "Duplicate column name '" + columnName
1268: + "' in table '" + tableName + "'";
1269: }
1270: cols.add(columnName);
1271: return null;
1272: }
1273:
1274: /**
1275: * Generate and add a name for the primary key column for a PC class using
1276: * datastore identity.
1277: */
1278: public String generateDatastorePKName(String tableName) {
1279: String name = getPKNameForTableName(tableName, 0);
1280: for (int j = 2; addColumnNameImp(tableName, name) != null; j++) {
1281: name = getPKNameForTableName(tableName, j);
1282: }
1283: return name;
1284: }
1285:
1286: /**
1287: * Generate a primary key column name from a table name and an index.
1288: * If the index is less then 2 it must be ignored. Otherwise it must
1289: * be used in the generated name. This is used to resolve name clashes.
1290: * The returned name must not exceed maxColumnNameLength.
1291: */
1292: protected String getPKNameForTableName(String tableName, int i) {
1293: int maxlen = maxColumnNameLength - pkSuffix.length();
1294: if (i < 2) {
1295: return shrinkName(tableName, maxlen) + pkSuffix;
1296: } else {
1297: return appendInt(tableName, i, maxlen) + pkSuffix;
1298: }
1299: }
1300:
1301: /**
1302: * Generate and add the name for a classId column.
1303: *
1304: * @see #addColumnNameImp
1305: */
1306: public String generateClassIdColumnName(String tableName) {
1307: String name = shrinkName(classIdColumnName, maxColumnNameLength);
1308: for (int j = 2; addColumnNameImp(tableName, name) != null; j++) {
1309: name = appendInt(classIdColumnName, j, maxColumnNameLength);
1310: }
1311: return name;
1312: }
1313:
1314: /**
1315: * Generate and add the name for a field column.
1316: */
1317: public String generateFieldColumnName(String tableName,
1318: String fieldName, boolean primaryKey) {
1319: fieldName = fieldName.substring(fieldName.lastIndexOf('.') + 1);
1320: String name = getColumnNameForFieldName(fieldName, 0);
1321: for (int j = 2; addColumnNameImp(tableName, name) != null; j++) {
1322: name = getColumnNameForFieldName(fieldName, j);
1323: }
1324: return name;
1325: }
1326:
1327: /**
1328: * Generate a column name from a field name and an index. If the index
1329: * is less then 2 it must be ignored. Otherwise it must be used in the
1330: * generated name. This is used to resolve name clashes. The returned
1331: * name must not exceed maxColumnNameLength.
1332: */
1333: protected String getColumnNameForFieldName(String fieldName, int i) {
1334: fieldName = getJdbcName(fieldName);
1335: if (i < 2) {
1336: return shrinkName(fieldName, maxColumnNameLength);
1337: } else {
1338: return appendInt(fieldName, i, maxColumnNameLength);
1339: }
1340: }
1341:
1342: /**
1343: * Generate a column name from a field name, a column number and an index.
1344: * If the index is less then 2 it must be ignored. Otherwise it must be
1345: * used in the generated name. This is used to resolve name clashes. The
1346: * columnNumber must also be used in the name. The returned name must not
1347: * exceed maxColumnNameLength. This is used for fields comprising of
1348: * multiple columns.
1349: */
1350: protected String getColumnNameForFieldName(String fieldName,
1351: int col, int i) {
1352: fieldName = getJdbcName(fieldName);
1353: String suffix = Integer.toString(col);
1354: int maxlen = maxColumnNameLength - suffix.length();
1355: if (i < 2) {
1356: return appendInt(fieldName, col, maxlen) + suffix;
1357: } else {
1358: return shrinkName(fieldName, maxlen) + suffix;
1359: }
1360: }
1361:
1362: /**
1363: * Generate and add names for one or more columns for a field that is
1364: * a reference to another PC class. Some of the columns may already have
1365: * names.
1366: *
1367: * @param columnNames Store the column names here (some may already have
1368: * names if specified in the .jdo meta data)
1369: * @param refTableName The table being referenced (null if not a JDBC class)
1370: * @param refPkNames The names of the primary key columns of refTableName
1371: * @param otherRefs Are there other field referencing the same class here?
1372: * @throws IllegalArgumentException if any existing names are invalid
1373: */
1374: public void generateRefFieldColumnNames(String tableName,
1375: String fieldName, String[] columnNames,
1376: String refTableName, String[] refPkNames, boolean otherRefs) {
1377: if (refTableName == null) {
1378: columnNames[0] = generateFieldColumnName(tableName,
1379: fieldName, false);
1380: return;
1381: }
1382: String prefix;
1383: if (otherRefs || tableName.equals(refTableName)) {
1384: int maxlen = 0;
1385: for (int i = refPkNames.length - 1; i >= 0; i--) {
1386: int n = refPkNames[i].length();
1387: if (n > maxlen)
1388: maxlen = n;
1389: }
1390: int n2 = maxColumnNameLength / 2 - 1;
1391: maxlen = n2 - maxlen;
1392: if (maxlen < n2)
1393: maxlen = n2;
1394: prefix = shrinkName(getJdbcName(fieldName), maxlen) + "_";
1395: } else {
1396: prefix = "";
1397: }
1398: int n = columnNames.length;
1399: for (int i = 0; i < n; i++) {
1400: String name = columnNames[i];
1401: if (name != null) {
1402: if (!isColumnInTable(tableName, name)) {
1403: addColumnNameImp(tableName, name);
1404: }
1405: continue;
1406: }
1407: String base = prefix + refPkNames[i];
1408: name = getColumnNameForRefColumn(base, 0);
1409: for (int j = 2; addColumnNameImp(tableName, name) != null; j++) {
1410: name = getColumnNameForRefColumn(base, j);
1411: }
1412: columnNames[i] = name;
1413: }
1414: }
1415:
1416: /**
1417: * Generate a column name from a ref column name and an index. If the
1418: * index is less then 2 it must be ignored. Otherwise it must be used in
1419: * the generated name. This is used to resolve name clashes. The returned
1420: * name must not exceed maxColumnNameLength.
1421: */
1422: protected String getColumnNameForRefColumn(String base, int i) {
1423: if (i < 2) {
1424: return shrinkName(base, maxColumnNameLength);
1425: } else {
1426: return appendInt(base, i, maxColumnNameLength);
1427: }
1428: }
1429:
1430: /**
1431: * Generate and add names for one or more columns for a field that is
1432: * a polymorphic reference to any other PC class. Some of the columns may
1433: * already have names.
1434: *
1435: * @param columnNames Store the column names here (some may already have
1436: * names if specified in the .jdo meta data). The class-id column
1437: * is at index 0.
1438: * @throws IllegalArgumentException if any existing names are invalid
1439: */
1440: public void generatePolyRefFieldColumnNames(String tableName,
1441: String fieldName, String[] columnNames)
1442: throws IllegalArgumentException {
1443: String fieldJdbc = getJdbcName(fieldName);
1444: if (columnNames[0] == null) {
1445: String name = fieldJdbc + polyRefClassIdSuffix;
1446: String n = name;
1447: for (int j = 2; addColumnNameImp(tableName, n) != null; j++) {
1448: n = appendInt(name, j, maxColumnNameLength);
1449: }
1450: columnNames[0] = n;
1451: }
1452: int nc = columnNames.length;
1453: boolean onePk = nc == 2;
1454: for (int i = 1; i < nc; i++) {
1455: String name;
1456: if (onePk) {
1457: name = fieldJdbc + pkSuffix;
1458: } else {
1459: name = fieldJdbc + pkSuffix + (char) ('a' + i - 1);
1460: }
1461: String n = name;
1462: for (int j = 2; addColumnNameImp(tableName, n) != null; j++) {
1463: n = appendInt(name, j, maxColumnNameLength);
1464: }
1465: columnNames[i] = n;
1466: }
1467: }
1468:
1469: /**
1470: * Generate and add names for the column(s) in a link table that reference
1471: * the primary key of the main table. Some of the columns may already
1472: * have names which must be kept (no need to add them).
1473: *
1474: * @param tableName The link table
1475: * @param mainTablePkNames The names of the main table primary key
1476: * @param linkMainRefNames The corresponding column names in the link table
1477: */
1478: public void generateLinkTableMainRefNames(String tableName,
1479: String[] mainTablePkNames, String[] linkMainRefNames) {
1480: int len = linkMainRefNames.length;
1481: for (int i = 0; i < len; i++) {
1482: String name = linkMainRefNames[i];
1483: if (name != null)
1484: continue;
1485: name = mainTablePkNames[i];
1486: String n = name;
1487: for (int j = 2; addColumnNameImp(tableName, n) != null; j++) {
1488: n = appendInt(name, j, maxColumnNameLength);
1489: }
1490: linkMainRefNames[i] = n;
1491: }
1492: }
1493:
1494: /**
1495: * Generate and add the name for a the column in a link table that stores
1496: * the element sequence number.
1497: */
1498: public String generateLinkTableSequenceName(String tableName) {
1499: String n = sequenceColumnName;
1500: for (int j = 2; addColumnNameImp(tableName, n) != null; j++) {
1501: n = appendInt(sequenceColumnName, j, maxColumnNameLength);
1502: }
1503: return n;
1504: }
1505:
1506: /**
1507: * Generate and add names for the column(s) in a link table that reference
1508: * the primary key of the value table. This is called for collections of
1509: * PC classes. Some of the columns may already have names which must be
1510: * kept (no need to add them).
1511: *
1512: * @param tableName The link table
1513: * @param valuePkNames The names of the value table primary key (may be
1514: * null if the value class is not stored in JDBC)
1515: * @param valueClassName The name of the value class
1516: * @param linkValueRefNames The corresponding column names in the link table
1517: */
1518: public void generateLinkTableValueRefNames(String tableName,
1519: String[] valuePkNames, String valueClassName,
1520: String[] linkValueRefNames, boolean key) {
1521: String valueBaseName = null;
1522: if (valuePkNames == null) {
1523: int dot = valueClassName.lastIndexOf('.');
1524: if (dot >= 0)
1525: valueClassName = valueClassName.substring(dot + 1);
1526: valueBaseName = shrinkName(getJdbcName(valueClassName),
1527: maxColumnNameLength);
1528: }
1529: int len = linkValueRefNames.length;
1530: for (int i = 0; i < len; i++) {
1531: String name = linkValueRefNames[i];
1532: if (name != null)
1533: continue;
1534: if (valuePkNames == null) {
1535: name = valueBaseName;
1536: } else {
1537: name = valuePkNames[i];
1538: }
1539: String n = name;
1540: for (int j = 2; addColumnNameImp(tableName, n) != null; j++) {
1541: n = appendInt(name, j, maxColumnNameLength);
1542: }
1543: linkValueRefNames[i] = n;
1544: }
1545: }
1546:
1547: /**
1548: * Generate and add the name for a the column in a link table that stores
1549: * the value where the value is not a PC class (int, String etc).
1550: *
1551: * @param tableName The link table
1552: * @param valueCls The value class
1553: * @param key Is this a key in a link table for a map?
1554: */
1555: public String generateLinkTableValueName(String tableName,
1556: Class valueCls, boolean key) {
1557: String name = key ? keyColumnName : valueColumnName;
1558: String n = name;
1559: for (int j = 2; addColumnNameImp(tableName, n) != null; j++) {
1560: n = appendInt(name, j, maxColumnNameLength);
1561: }
1562: return n;
1563: }
1564:
1565: /**
1566: * Add an index name. The tableName will have already been added.
1567: */
1568: public void addIndexName(String tableName, String indexName) {
1569: // we do not throw a exception if there are duplicates, because some DB's
1570: // do it on DB level and some on Table level.
1571: // If openaccess generates a Index name then we always do it on DB level.
1572: indexNames.add(indexName);
1573: }
1574:
1575: /**
1576: * Generate and add an index name.
1577: *
1578: * @see #addIndexName
1579: */
1580: public String generateIndexName(String tableName,
1581: String[] columnNames) {
1582: StringBuffer s = new StringBuffer();
1583: s.append(indexNamePrefix);
1584: s.append(tableName);
1585: s.append(wordBreak);
1586: int nc = columnNames.length;
1587: for (int i = 0; i < nc; i++) {
1588: if (i > 0)
1589: s.append(wordBreak);
1590: s.append(columnNames[i]);
1591: }
1592: String name = shrinkName(s.toString(), maxIndexNameLength);
1593: String n = name;
1594: for (int i = 2; indexNames.contains(n); i++) {
1595: n = appendInt(name, i, maxIndexNameLength);
1596: }
1597: addIndexName(tableName, n);
1598: return n;
1599: }
1600:
1601: public String getPolyRefClassIdSuffix() {
1602: return polyRefClassIdSuffix;
1603: }
1604:
1605: public void setPolyRefClassIdSuffix(String polyRefClassIdSuffix) {
1606: this.polyRefClassIdSuffix = polyRefClassIdSuffix;
1607: }
1608: }
|