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

com.mysql.cj.xdevapi.CreateIndexParams Maven / Gradle / Ivy

There is a newer version: 8.0.33
Show newest version
/*
 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, version 2.0, as published by the
 * Free Software Foundation.
 *
 * This program is also distributed with certain software (including but not
 * limited to OpenSSL) that is licensed under separate terms, as designated in a
 * particular file or component or in included license documentation. The
 * authors of MySQL hereby grant you an additional permission to link the
 * program and your derivative works with the separately licensed software that
 * they have included with MySQL.
 *
 * Without limiting anything contained in the foregoing, this file, which is
 * part of MySQL Connector/J, is also subject to the Universal FOSS Exception,
 * version 1.0, a copy of which can be found at
 * http://oss.oracle.com/licenses/universal-foss-exception.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
 */

package com.mysql.cj.xdevapi;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import com.mysql.cj.Messages;
import com.mysql.cj.exceptions.AssertionFailedException;

public class CreateIndexParams {
    private String indexName;
    /** One of INDEX or SPATIAL. Default is INDEX and may be omitted. **/
    private String indexType = "INDEX";
    private List fields = new ArrayList<>();

    public CreateIndexParams(String indexName, DbDoc indexDefinition) {
        init(indexName, indexDefinition);
    }

    public CreateIndexParams(String indexName, String jsonIndexDefinition) {
        if (jsonIndexDefinition == null || jsonIndexDefinition.trim().length() == 0) {
            throw new XDevAPIError(Messages.getString("CreateIndexParams.0", new String[] { "jsonIndexDefinition" }));
        }
        try {
            init(indexName, JsonParser.parseDoc(new StringReader(jsonIndexDefinition)));
        } catch (IOException ex) {
            throw AssertionFailedException.shouldNotHappen(ex);
        }
    }

    private void init(String idxName, DbDoc indexDefinition) {
        if (idxName == null || idxName.trim().length() == 0) {
            throw new XDevAPIError(Messages.getString("CreateIndexParams.0", new String[] { "indexName" }));
        }
        if (indexDefinition == null) {
            throw new XDevAPIError(Messages.getString("CreateIndexParams.0", new String[] { "indexDefinition" }));
        }

        this.indexName = idxName;

        for (String key : indexDefinition.keySet()) {
            if (!"type".equals(key) && !"fields".equals(key)) {
                throw new XDevAPIError("The '" + key + "' field is not allowed in indexDefinition.");
            }
        }

        JsonValue val = indexDefinition.get("type");
        if (val != null) {
            if (val instanceof JsonString) {
                String type = ((JsonString) val).getString();
                if ("INDEX".equalsIgnoreCase(type) || "SPATIAL".equalsIgnoreCase(type)) {
                    this.indexType = type;
                } else {
                    throw new XDevAPIError("Wrong index type '" + type + "'. Must be 'INDEX' or 'SPATIAL'.");
                }
            } else {
                throw new XDevAPIError("Index type must be a string.");
            }
        }

        val = indexDefinition.get("fields");
        if (val != null) {
            if (val instanceof JsonArray) {
                for (JsonValue field : (JsonArray) val) {
                    if (field instanceof DbDoc) {
                        this.fields.add(new IndexField((DbDoc) field));
                    } else {
                        throw new XDevAPIError("Index field definition must be a JSON document.");
                    }
                }

            } else {
                throw new XDevAPIError("Index definition 'fields' member must be an array of index fields.");
            }
        } else {
            throw new XDevAPIError("Index definition does not contain fields.");
        }
    }

    public String getIndexName() {
        return this.indexName;
    }

    public String getIndexType() {
        return this.indexType;
    }

    public List getFields() {
        return this.fields;
    }

    public static class IndexField {

        /** The full document path to the document member or field to be indexed **/
        private String field;

        /**
         * One of the supported SQL column types to map the field into.
         * For numeric types, the optional UNSIGNED keyword may follow. For
         * the TEXT type, the length to consider for indexing may be added.
         **/
        private String type;

        /** (optional) true if the field is required to exist in the document. defaults to false, except for GEOJSON where it defaults to true **/
        private boolean required = false;

        /** (optional) special option flags for use when decoding GEOJSON data **/
        private Integer options = null;

        /** (optional) srid value for use when decoding GEOJSON data **/
        private Integer srid = null;

        public IndexField(DbDoc indexField) {
            for (String key : indexField.keySet()) {
                if (!"type".equals(key) && !"field".equals(key) && !"required".equals(key) && !"options".equals(key) && !"srid".equals(key)) {
                    throw new XDevAPIError("The '" + key + "' field is not allowed in indexField.");
                }
            }

            JsonValue val = indexField.get("field");
            if (val != null) {
                if (val instanceof JsonString) {
                    this.field = ((JsonString) val).getString();
                } else {
                    throw new XDevAPIError("Index field 'field' member must be a string.");
                }
            } else {
                throw new XDevAPIError("Index field definition has no document path.");
            }

            val = indexField.get("type");
            if (val != null) {
                if (val instanceof JsonString) {
                    this.type = ((JsonString) val).getString();
                    // TODO pure "TEXT" is not allowed as a type, server requires the length specification
                    // we're waiting for clarification about whether we set some default on client side in that case, eg.:
                    //    if ("TEXT".equals(this.type)) {this.type = "TEXT(64)";}
                    // or we do nothing and user has to specify TEXT(n) always
                } else {
                    throw new XDevAPIError("Index type must be a string.");
                }
            } else {
                throw new XDevAPIError("Index field definition has no field type.");
            }

            val = indexField.get("required");
            if (val != null) {
                if (val instanceof JsonLiteral && !JsonLiteral.NULL.equals(val)) {
                    this.required = Boolean.valueOf(((JsonLiteral) val).value);
                } else {
                    throw new XDevAPIError("Index field 'required' member must be boolean.");
                }
            } else if (this.type.equalsIgnoreCase("GEOJSON")) {
                this.required = true;
            }

            val = indexField.get("options");
            if (val != null) {
                if (this.type.equalsIgnoreCase("GEOJSON")) {
                    if (val instanceof JsonNumber) {
                        this.options = ((JsonNumber) val).getInteger();
                    } else {
                        throw new XDevAPIError("Index field 'options' member must be integer.");
                    }
                } else {
                    throw new XDevAPIError("Index field 'options' member should not be used for field types other than GEOJSON.");
                }
            }

            val = indexField.get("srid");
            if (val != null) {
                if (this.type.equalsIgnoreCase("GEOJSON")) {
                    if (val instanceof JsonNumber) {
                        this.srid = ((JsonNumber) val).getInteger();
                    } else {
                        throw new XDevAPIError("Index field 'srid' member must be integer.");
                    }
                } else {
                    throw new XDevAPIError("Index field 'srid' member should not be used for field types other than GEOJSON.");
                }
            }
        }

        public String getField() {
            return this.field;
        }

        public String getType() {
            return this.type;
        }

        public boolean isRequired() {
            return this.required;
        }

        public Integer getOptions() {
            return this.options;
        }

        public Integer getSrid() {
            return this.srid;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy