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

org.apache.uima.ducc.database.DbUtil Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.apache.uima.ducc.database;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.uima.ducc.common.persistence.IDbProperty;
import org.apache.uima.ducc.common.persistence.IDbProperty.Type;

import com.datastax.driver.core.Row;

/**
 * Static common helper methods.
 *
 * Not public at this point, would prefer to encapsulate all this entirely in DB.
 */
class DbUtil
{
    static String mkSchema(IDbProperty[] props)
        throws Exception
    {
        List parts = new ArrayList();
        List primaries = new ArrayList();
        for (IDbProperty n : props ) {
            if ( n.isMeta() ) continue;
            String s = n.columnName() + " " + typeToString(n.type());
            if ( n.isPrimaryKey() ) {
                primaries.add(n.columnName());
            }
            parts.add(s);
        }
        if ( primaries.size() == 0 ) {
            throw new IllegalArgumentException("Schema properties must declare at least one primary key.");
        }
        StringBuffer buf = new StringBuffer();
        for ( String p : parts ) {
            buf.append(p);
            buf.append(",");
        }
        int ncommas = primaries.size() - 1;
        int c = 0;
        buf.append(" PRIMARY KEY(");
        for ( String s : primaries ) {
            buf.append(s);
            if ( c++ < ncommas ) {
                buf.append(",");
            }
        }

        buf.append(")");
        return buf.toString();
    }

    static List dropIndices(IDbProperty[] props, String tablename)
    {
        List ret = new ArrayList();
        for ( IDbProperty p : props ) {
            if ( p.isIndex() ) {
                StringBuffer buf = new StringBuffer("DROP INDEX IF EXISTS ");
                buf.append(tablename);
                buf.append("_");
                buf.append(p.pname());
                buf.append("_idx;");
                ret.add(buf.toString());
            }
        }
        return ret;
    }

    static List mkIndices(IDbProperty[] props, String tablename)
    {
        List ret = new ArrayList();
        for ( IDbProperty p : props ) {
            if ( p.isIndex() ) {
                StringBuffer buf = new StringBuffer("CREATE INDEX IF NOT EXISTS ");
                buf.append(tablename);
                buf.append("_");
                buf.append(p.pname());
                buf.append("_idx ON ");
                buf.append(tablename);
                buf.append("(");
                buf.append(p.pname());
                buf.append(")");
                ret.add(buf.toString());
            }
        }
        return ret;
    }

    static String mkFields(StringBuffer buf, String[] fields)
    {
        int max = fields.length - 1;
        int current = 0;
        buf.append("(");
        for (String s : fields) {
            buf.append(s);
            if ( current++ < max) buf.append(", ");
        }
        buf.append(")");
        return buf.toString();                   

    }

    /**
     * Generate a CREATE TABLE statement from the incoming fields.  The preparer of the
     * fields must qualify any fields in advance e.g. with types, key attributes, etc.
     *
     * @param tableName This is the name of the table to create.
     * @param fields This is a string array of fields to generate the statement from.
     * 
     * @return A string of valid SQL / CQL used to create the table.
     */
    static String mkTableCreate(String tableName, String[] fields)
    {
        int max = fields.length - 1;
        int current = 0;
        StringBuffer buf = new StringBuffer("CREATE TABLE IF NOT EXISTS ");
        buf.append(tableName);
        buf.append(" (");
        for (String s : fields) {
            buf.append(s);
            if ( current++ < max) buf.append(", ");
        }
        buf.append(")");
        return buf.toString();                   
    }

    static String mkInsert(String tableName, Map props)
    {
        int max = props.size() - 1;
        int current = 0;
        StringBuffer buf = new StringBuffer("INSERT INTO ");
        buf.append(tableName);
        buf.append("(");

        StringBuffer vals = new StringBuffer(") VALUES (");

        for ( IDbProperty ok : props.keySet() ) {

            String k = ok.columnName();
            buf.append(k);
            vals.append(rep(ok, props.get(ok)));

            if ( current++ < max ) {
                buf.append(",");
                vals.append(",");
            }
        }
        buf.append(vals.toString());
        buf.append(")");

        return buf.toString();
    }

    static String mkInsert(String tableName, Object key, Object keyval, Map props)
    {
        int max = props.size() + 1;
        int current = 0;
        StringBuffer buf = new StringBuffer("INSERT INTO ");
        buf.append(tableName);
        buf.append("(");

        StringBuffer vals = new StringBuffer(") VALUES (");

        buf.append(key.toString());
        buf.append(",");
        vals.append(keyval.toString());
        vals.append(",");

        for ( IDbProperty ok : props.keySet() ) {

            String k = ok.columnName();
            buf.append(k);
            vals.append(rep(ok, props.get(ok)));

            if ( current++ < max ) {
                buf.append(",");
                vals.append(",");
            }
        }
        buf.append(vals.toString());
        buf.append(")");

        return buf.toString();

    }

    /**
     * Imporant: do not pass key fields in the props or this will barf. 
     */
    static String mkUpdate(String table, String key, Object... props)
    {
        int len = props.length;
        StringBuffer buf = new StringBuffer("UPDATE ");
        buf.append(table);        
        buf.append(" SET ");
        
        // NOTE: The property set must NOT contain any key fields or this is likely to barf.  Caller
        //       must insure.
        for ( int i = 0; i < len; i+=2) {
            IDbProperty prop = (IDbProperty) props[i];

            if ( prop.isPrimaryKey() ) {
                throw new IllegalArgumentException("Primary key not allowed in UPDATE");
            }

            buf.append(prop.columnName());
            buf.append("=");
            buf.append(rep(prop, props[i+1]));
            if ( i + 2 < len ) {
                buf.append(",");
            }  
        }
        buf.append(" WHERE ");
        buf.append(key);
        return buf.toString();
    }

    /**
     * Return the correct representation for CQL update, of val, for the indicated type, for this database.
     */
    static String rep(IDbProperty p, Object val)
    {
        switch ( p.type() ) {
            case String:
                return "'" + val.toString() + "'";
            default:
                return val.toString();
        }
    }

    /**
     * Common code to pull things from a row according to the schema, into a map
     */
    static Map getProperties(IDbProperty[] props, Row r)
    {
        Map ret = new HashMap();
        for ( IDbProperty p : props ) {
            if ( p.isPrivate() ) continue;
            if ( p.isMeta()    ) continue;
            Object val = null;
            switch ( p.type() ) {

                case String: 
                    val = r.getString(p.columnName());
                    break;

                case Integer: 
                    val = r.getInt(p.columnName());
                    break;

                case Long: 
                    val = r.getLong(p.columnName());
                    break;

                case Double: 
                    val = r.getDouble(p.columnName());
                    break;

                case UUID: 
                    val = r.getUUID(p.columnName());
                    break;

                case Boolean: 
                    val = r.getBool(p.columnName());
                    break;

                case Blob: 
                    val = r.getBytes(p.columnName());
                    break;
            }
            if ( val != null ) ret.put(p.pname(), val);
        }
        return ret;
    }

    /**
     * Convert our generic "type" to the right name for this db implementation.
     * We could make Type a magic enum but I want to hide DB specifics, in particular,
     * how this database names various java types.
     */
    static String typeToString(Type t)
    {
        switch ( t ) {
            case Blob:
                return  "blob";
            case String:
                return  "varchar";
            case Boolean:
                return "boolean";
            case Integer:
                return "int";
            case Long:
                return "bigint";
            case Double:
                return "double";
            case UUID:
                return "uuid";
        }
        throw new IllegalArgumentException("Unrecognized type for schema: " + t);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy