/*
 * Copyright 2004-2006 the Seasar Foundation and the Others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.seasar.dao.dbms;

import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

import org.seasar.dao.BeanMetaData;
import org.seasar.dao.Dbms;
import org.seasar.dao.RelationPropertyType;

/**
 * @author higa
 *  
 */
public class Standard implements Dbms {

	private Map autoSelectFromClauseCache_ = new HashMap();
	
	/**
	 * @see org.seasar.dao.Dbms#getSuffix()
	 */
	public String getSuffix() {
		return "";
	}

	/**
	 * @see org.seasar.dao.Dbms#getAutoSelectSql(org.seasar.dao.BeanMetaData)
	 */
	public String getAutoSelectSql(BeanMetaData beanMetaData) {
		StringBuffer buf = new StringBuffer(100);
		buf.append(beanMetaData.getAutoSelectList());
		buf.append(" ");
		String beanName = beanMetaData.getBeanClass().getName();
		synchronized (autoSelectFromClauseCache_) {
			String fromClause = (String) autoSelectFromClauseCache_.get(beanName);
			if (fromClause == null) {
				fromClause = createAutoSelectFromClause(beanMetaData);
				autoSelectFromClauseCache_.put(beanName, fromClause);
			}
			buf.append(fromClause);
		}
		return buf.toString();
	}

	protected String createAutoSelectFromClause(BeanMetaData beanMetaData) {
		StringBuffer buf = new StringBuffer(100);
		buf.append("FROM ");
		String myTableName = beanMetaData.getTableName();
		buf.append(myTableName);
		for (int i = 0; i < beanMetaData.getRelationPropertyTypeSize(); ++i) {
			RelationPropertyType rpt = beanMetaData.getRelationPropertyType(i);
			BeanMetaData bmd = rpt.getBeanMetaData();
			buf.append(" LEFT OUTER JOIN ");
			buf.append(bmd.getTableName());
			buf.append(" ");
			String yourAliasName = rpt.getPropertyName();
			buf.append(yourAliasName);
			buf.append(" ON ");
			for (int j = 0; j < rpt.getKeySize(); ++j) {
				buf.append(myTableName);
				buf.append(".");
				buf.append(rpt.getMyKey(j));
				buf.append(" = ");
				buf.append(yourAliasName);
				buf.append(".");
				buf.append(rpt.getYourKey(j));
				buf.append(" AND ");
			}
			buf.setLength(buf.length() - 5);

		}
		return buf.toString();
	}
	
	public String getIdentitySelectString() {
		return null;
	}
	
	public String getSequenceNextValString(String sequenceName) {
		return null;
	}
    
    public boolean isSelfGenerate() {
        return true;
    }

	public String getBaseSql(Statement st) {
		String nativeSql = st.toString();
		return nativeSql.replaceFirst("^.*SELECT", "SELECT");
	}
}
@@ -744,16 +744,82 @@
 il.Map;%0D
+%0Aimport java.util.regex.Matcher;%0D%0Aimport java.util.regex.Pattern;%0D
 %0A%0D%0Aimpor
@@ -1002,16 +1002,142 @@
 ms %7B%0D%0A%0D%0A
+    private static final Pattern baseSqlPattern = Pattern.compile(%22%5E.*?(select)%22,%0D%0A            Pattern.CASE_INSENSITIVE);%0D%0A%09%0D%0A
 %09private
@@ -3158,18 +3158,22 @@
 %0A    %7D%0D%0A
+    
 %0D%0A
-
 %09public 
@@ -3211,24 +3211,24 @@
  %7B%0D%0A
-%09%09String nativeS
+        String s
 ql =
@@ -3248,63 +3248,207 @@
 );%0D%0A
-%09%09return nativeSql.replaceFirst(%22%5E.*SELECT%22, %22SELECT%22);
+        Matcher matcher = baseSqlPattern.matcher(sql);%0D%0A        if (matcher.find()) %7B%0D%0A            return matcher.replaceFirst(matcher.group(1));%0D%0A        %7D else %7B%0D%0A            return sql;%0D%0A        %7D
 %0D%0A%09%7D

change getBaseSql