1 28 29 package com.caucho.amber.expr; 30 31 import com.caucho.amber.query.FromItem; 32 import com.caucho.amber.query.QueryParser; 33 import com.caucho.amber.table.Column; 34 import com.caucho.amber.table.ForeignColumn; 35 import com.caucho.amber.table.LinkColumns; 36 import com.caucho.amber.table.Table; 37 import com.caucho.util.CharBuffer; 38 39 import java.util.ArrayList ; 40 41 44 public class MemberExpr extends AbstractAmberExpr { 45 private boolean _isNot; 46 47 private AmberExpr _itemExpr; 49 50 private AmberExpr _collectionExpr; 51 52 private MemberExpr(AmberExpr itemExpr, 53 AmberExpr collectionExpr, boolean isNot) 54 { 55 _itemExpr = itemExpr; 56 _collectionExpr = collectionExpr; 57 _isNot = isNot; 58 } 59 60 public static AmberExpr create(QueryParser parser, 61 AmberExpr itemExpr, 62 AmberExpr collectionExpr, 63 boolean isNot) 64 { 65 if (collectionExpr instanceof IdExpr) 66 collectionExpr = ((CollectionIdExpr) collectionExpr).getPath(); 67 68 89 90 return new MemberExpr(itemExpr, collectionExpr, isNot); 91 } 92 93 96 public AmberExpr bindSelect(QueryParser parser) 97 { 98 return this; 99 } 100 101 104 public boolean isBoolean() 105 { 106 return true; 107 } 108 109 112 public boolean usesFrom(FromItem from, int type, boolean isNot) 113 { 114 if (! (_itemExpr instanceof PathExpr)) 115 return false; 116 117 return (_collectionExpr.usesFrom(from, type) || 118 ((PathExpr) _itemExpr).usesFrom(from, type)); 119 } 120 121 124 public AmberExpr replaceJoin(JoinExpr join) 125 { 126 if (_itemExpr instanceof PathExpr) { 127 _collectionExpr = _collectionExpr.replaceJoin(join); 128 _itemExpr = (PathExpr) _itemExpr.replaceJoin(join); 129 } 130 131 return this; 132 } 133 134 137 public void generateWhere(CharBuffer cb) 138 { 139 generateInternalWhere(cb, true); 140 } 141 142 145 public void generateUpdateWhere(CharBuffer cb) 146 { 147 generateInternalWhere(cb, false); 148 } 149 150 153 public void generateHaving(CharBuffer cb) 154 { 155 generateWhere(cb); 156 } 157 158 161 private void generateInternalWhere(CharBuffer cb, 162 boolean select) 163 { 164 OneToManyExpr oneToMany = null; 165 166 if (_collectionExpr instanceof ManyToOneExpr) { 169 PathExpr expr = ((ManyToOneExpr) _collectionExpr).getParent(); 170 if (expr instanceof OneToManyExpr) 171 oneToMany = (OneToManyExpr) expr; 172 173 } else if (_collectionExpr instanceof OneToManyExpr) { 174 oneToMany = (OneToManyExpr) _collectionExpr; 175 } 176 else 177 throw new UnsupportedOperationException (); 178 179 LinkColumns join = oneToMany.getLinkColumns(); 180 181 if (_isNot) 182 cb.append("NOT "); 183 184 ForeignColumn fk = (ForeignColumn) join.getColumns().get(0); 187 cb.append(oneToMany.getParent().getChildFromItem().getName()); 188 cb.append('.'); 189 cb.append(fk.getTargetColumn().getName()); 190 191 cb.append(" IN (SELECT "); cb.append(fk.getName()); 194 Table table = join.getSourceTable(); 195 cb.append(" FROM " + table.getName() + " caucho"); 196 cb.append(" WHERE "); 197 198 String targetTable = oneToMany.getParent().getChildFromItem().getName(); 199 200 cb.append(join.generateJoin("caucho", targetTable)); 201 202 if (_itemExpr instanceof ArgExpr) { 203 204 cb.append(" AND caucho."); 205 206 if (_collectionExpr instanceof ManyToOneExpr) { 207 join = ((ManyToOneExpr) _collectionExpr).getLinkColumns(); 208 209 String name = join.getColumns().get(0).getName(); 210 211 cb.append(name); 212 } 213 else { 214 ArrayList <Column> idColumns = 216 join.getSourceTable().getIdColumns(); 217 218 cb.append(idColumns.get(0).getName()); 219 } 220 221 cb.append(" = ?"); 222 } 223 else if (_collectionExpr instanceof ManyToOneExpr) { 224 join = ((ManyToOneExpr) _collectionExpr).getLinkColumns(); 225 226 String itemWhere; 227 boolean isArg = false; 228 229 String where; 230 231 if (_itemExpr instanceof ManyToOneExpr) { 232 LinkColumns manyToOneJoin = ((ManyToOneExpr) _itemExpr).getLinkColumns(); 233 234 itemWhere = ((ManyToOneExpr) _itemExpr).getParent().getChildFromItem().getName(); 235 236 where = join.generateJoin(manyToOneJoin, "caucho", itemWhere); 237 } 238 else { 239 240 if (_itemExpr instanceof PathExpr) { 241 itemWhere = ((PathExpr) _itemExpr).getChildFromItem().getName(); 242 } 243 else { 244 isArg = true; 245 itemWhere = "?"; 246 } 247 248 where = join.generateJoin("caucho", itemWhere, isArg); 249 } 250 251 cb.append(" AND " + where); 252 } 253 else if (_collectionExpr instanceof OneToManyExpr) { 254 if (_itemExpr instanceof ManyToOneExpr) { 255 256 join = ((ManyToOneExpr) _itemExpr).getLinkColumns(); 257 258 String itemWhere = ((ManyToOneExpr) _itemExpr).getParent().getChildFromItem().getName(); 259 260 String where = join.generateJoin(itemWhere, "caucho"); 261 262 cb.append(" AND " + where); 263 } 264 else { 265 ArrayList <Column> idColumns = 267 join.getSourceTable().getIdColumns(); 268 269 String id = idColumns.get(0).getName(); 270 271 cb.append(" AND (caucho." + id + " = "); 272 273 FromItem childFromItem = ((PathExpr) _itemExpr).getChildFromItem(); 274 275 if (childFromItem != null) { 276 cb.append(childFromItem.getName() + "."); 277 278 idColumns = childFromItem.getTable().getIdColumns(); 280 281 cb.append(idColumns.get(0).getName() + ")"); 282 } 283 } 284 } 285 286 cb.append(')'); 287 } 288 } 289 | Popular Tags |