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

io.cloudboost.CloudQuery Maven / Gradle / Ivy

There is a newer version: 1.0.7
Show newest version
package io.cloudboost;

import io.cloudboost.beans.CBResponse;
import io.cloudboost.json.JSONArray;
import io.cloudboost.json.JSONException;
import io.cloudboost.json.JSONObject;
import io.cloudboost.util.CBParser;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 
 * @author cloudboost
 * 
 */
public class CloudQuery {

	private String tableName;
	private JSONObject query;
	private JSONObject select;
	ArrayList includeList;
	ArrayList include;
	private JSONObject sort;
	private int skip;
	private int limit;
	private ArrayList $include;
	private ArrayList $includeList;
	public JSONObject body=new JSONObject();

	/**
	 * 
	 * Constructor
	 * 
	 * @param tableName
	 */
	public CloudQuery(String tableName) {

		this.tableName = tableName;
		query = new JSONObject();
		select = new JSONObject();
		include = new ArrayList();
		includeList = new ArrayList();
		$include = new ArrayList();
		$includeList = new ArrayList();
		try {
			this.query.put("$include", $include);
			this.query.put("$includeList", $includeList);

		} catch (JSONException e) {
			
			e.printStackTrace();
		}
		sort = new JSONObject();

		this.skip = 0;
		this.limit = 10;

	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public JSONObject getSelect() {
		return select;
	}

	public void setSelect(JSONObject select) {
		this.select = select;
	}

	public ArrayList getIncludeList() {
		return includeList;
	}

	public void setIncludeList(ArrayList includeList) {
		this.includeList = includeList;
	}

	public ArrayList getInclude() {
		return include;
	}

	public void setInclude(ArrayList include) {
		this.include = include;
	}

	public JSONObject getSort() {
		return sort;
	}

	public void setSort(JSONObject sort) {
		this.sort = sort;
	}

	public ArrayList get$include() {
		return $include;
	}

	public void set$include(ArrayList $include) {
		this.$include = $include;
	}

	public ArrayList get$includeList() {
		return $includeList;
	}

	public void set$includeList(ArrayList $includeList) {
		this.$includeList = $includeList;
	}

	public int getSkip() {
		return skip;
	}

	public int getLimit() {
		return limit;
	}

	public JSONObject getQuery() {
		return query;
	}

	public void setQuery(JSONObject query) {
		this.query = query;
	}
	public boolean hasQuery(){
		return query!=null;
	}

	/**
	 * 
	 * CloudQuery Or
	 * 
	 * 
	 * @param object1
	 * @param object2
	 * @throws CloudException
	 */
	public static CloudQuery or(CloudQuery object1, CloudQuery object2)
			throws CloudException {
		String tableName1 = object1.tableName;
		String tableName2 = object2.tableName;

		if (tableName1.toLowerCase().equals(tableName2.toLowerCase()) == false) {
			throw new CloudException("Table names are not same");
		}

		JSONArray array = new JSONArray();
		array.put(object1.query);
		array.put(object2.query);

		CloudQuery object = new CloudQuery(tableName1);
		try {
			object.query.put("$or", array);
		} catch (JSONException e) {
			
			e.printStackTrace();
		}

		return object;
	}
	public static boolean validateQuery(CloudObject co,JSONObject query) throws JSONException{
		String[] names=JSONObject.getNames(query);
		if(names==null)
			return false;
		for(String key:names){
			if(key.equals("$include")||key.equals("$includeList"))
				continue;
			Object val=query.get(key);
			if(val instanceof JSONObject||val instanceof JSONArray){
				if(key.equals("$or")){
					JSONArray arr=query.getJSONArray(key);
					boolean valid=false;
					if(arr.length()>0){
						
						for(int i=0;i subk=	Arrays.asList(subkeys);

					for(String subkey:subkeys){
						if(subkey.equals("$regex")){
							if(co.hasKey(key)){
							if(subk.contains("$options"))
							{
								String options=((JSONObject)val).getString("$options");
								if(options.equals("im")){
									String reg=((JSONObject)val).getString("$regex");
									reg=reg.replace("^", "");
									if(co.hasKey(key)){
									String value=co.getString(key);
									if(!(String.valueOf(value.charAt(0)).equals(reg))){
										return false;
									}}
								}
							}}
						}
						if(subkey.equals("$ne"))
							{
							
							Object subval=((JSONObject) val).get(subkey);
							if(co.hasKey(key)){
							if(subval instanceof Double ){
								if(co.getDouble(key)==((JSONObject)val).getDouble(subkey))
									return false;}
							else if(subval instanceof Integer){
								if(co.getInteger(key)==((JSONObject)val).getInt(subkey))
									return false;}
							else if(subval instanceof String)
								if(co.getString(key).equals(((JSONObject)val).getString(subkey)))
									return false;}
							}
						if(subkey.equals("$gt")){
							if(co.hasKey(key)){
							Object subval=((JSONObject) val).get(subkey);
							if(subval instanceof Double ){
								if(co.getDouble(key)<=((JSONObject)val).getDouble(subkey))
									return false;}
							else if(subval instanceof Integer){
								if(co.getInteger(key)<=((JSONObject)val).getInt(subkey))
									return false;}}
						}
						if(subkey.equals("$gte")){
							Object subval=((JSONObject) val).get(subkey);
							if(co.hasKey(key)){
							if(subval instanceof Double ){
								if(co.getDouble(key)<((JSONObject)val).getDouble(subkey))
									return false;}
							else if(subval instanceof Integer){
								if(co.getInteger(key)<((JSONObject)val).getInt(subkey))
									return false;
								
							}}
						}
						if(subkey.equals("$lt")){
							if(co.hasKey(key)){
							Object subval=((JSONObject) val).get(subkey);
							if(subval instanceof Double ){
								if(co.getDouble(key)>=((JSONObject)val).getDouble(subkey))
									return false;
								}
							else if(subval instanceof Integer){
								if(co.getInteger(key)>=((JSONObject)val).getInt(subkey))
									return false;}}
						}
						if(subkey.equals("$lte")){
							Object subval=((JSONObject) val).get(subkey);
							if(co.hasKey(key)){
							if(subval instanceof Double )
								if(co.getDouble(key)>((JSONObject)val).getDouble(subkey))
									return false;
							else if(subval instanceof Integer)
								if(co.getInteger(key)>((JSONObject)val).getInt(subkey))
									return false;}
						}
						if(subkey.equals("$exists")){
							boolean exists=((JSONObject) val).getBoolean(subkey);
							if(co.hasKey(key))
							if(exists&&!co.hasKey(key)||!exists&&co.hasKey(key)){
								return false;
								}
						}
						if(subkey.equals("$in")){
							JSONArray arr=((JSONObject) val).getJSONArray(subkey);
							Object value=null;
							if(key.indexOf(".")!=-1&&!co.hasKey(key)){
								if(co.hasKey(key.substring(0, key.indexOf("."))))
								value=co.get(key.substring(0, key.indexOf(".")));
								}
							else {
								if(co.hasKey(key))
								value=co.get(key);}
							boolean vali=false;
							for(int i=0;i $in=new ArrayList();
		ArrayList $nin=new ArrayList();

		if (data instanceof CloudObject[] || data instanceof Integer[]
				|| data instanceof String[] || data instanceof Double[]) {

			CloudObject[] object = new CloudObject[data.length];
			if(data instanceof CloudObject[])
			columnName =columnName.equals("_id")?columnName:columnName +"._id";
			

			try {
				this.query.put("$include", $include);
				this.query.put("$includeList", $includeList);
				if (data instanceof CloudObject[]) {
					Object[] dataz=new Object[data.length];
					for (int i = 0; i < data.length; i++) {
						object[i] = (CloudObject) data[i];
						if (object[i].getId() == null) {
							throw new CloudException(
									"CloudObject passed should be saved and should have an id before being passed to containedIn");
						}
						dataz[i] = object[i].getId();
					}
					data=dataz;
					if(!column.has("$in"))
						column.put("$in", new ArrayList());
						if(column.get("$in") == null){
							$in = new ArrayList();
							column.put("$in", $in);
						}

					if(!column.has("$nin"))
						column.put("$nin", new ArrayList());
					if (column.get("$nin") == null) {
						$nin = new ArrayList();
						column.put("$nin", $nin);
					}
					JSONArray in=(JSONArray) column.get("$in");
					JSONArray nin= (JSONArray) column.get("$nin");
					
					for(int i=0;i();
					column.put("$in", $in);
					$nin = new ArrayList();
					column.put("$nin", $nin);

					for (int i = 0; i < data.length; i++) {

						$in.add(data[i].toString());
						if ($nin.contains(data[i].toString())) {
							$nin.remove(data[i].toString());
						}
					}
					column.put("$in", $in);
					column.put("$nin", $nin);

					this.query.put(columnName, column);

				}
			} catch (JSONException e) {
				
				e.printStackTrace();
			}
		} else {
			throw new CloudException(
					"Pass only Integer, Double, String or CloudObject as an argument");
		}

		return this;
	}

	/**
	 * 
	 * CloudQuery Not Contained In
	 * 
	 * @param columnName
	 * @param data
	 * @return CloudQuery
	 * @throws CloudException
	 */
	@SuppressWarnings("unchecked")
	public CloudQuery notContainedIn(String columnName, Object[] data)
			throws CloudException {

		if (columnName.equals("id") || columnName.equals("expires"))
			columnName = "_" + columnName;

		JSONObject column = new JSONObject();
		try {
			this.query.put("$include", $include);
			this.query.put("$includeList", $includeList);
			if (this.query.has(columnName)) {
				column = this.query.getJSONObject(columnName);
			}

			ArrayList $in = new ArrayList();
			ArrayList $nin = new ArrayList();

			if (data instanceof CloudObject[] || data instanceof Integer[]
					|| data instanceof String[] || data instanceof Double[]) {

				CloudObject[] object = new CloudObject[data.length];

				if (data instanceof CloudObject[]) {
					columnName = columnName + "._id";
					for (int i = 0; i < data.length; i++) {
						object[i] = (CloudObject) data[i];
						if (object[i].getId() == null) {
							throw new CloudException(
									"CloudObject passed should be saved and should have an id before being passed to containedIn");
						}
						data[i] = object[i].getId();
					}

					if (this.query.isNull(columnName)) {
						this.query.put(columnName, JSONObject.NULL);
					}

					if (column.get("$in") == null) {
						$in = new ArrayList();
					}

					if (column.get("$nin") == null) {
						$nin = new ArrayList();
						column.put("$nin", $nin);
					}
					JSONArray nin = column.getJSONArray("$nin");
					for (int i = 0; i < nin.length(); i++) {
						$nin.add(nin.get(i).toString());
					}
					$in = (ArrayList) column.get("$in");
					$nin = (ArrayList) column.get("$nin");

					for (int i = 0; i < data.length; i++) {
						if (!$nin.contains(data[i].toString())) {
							$nin.add(data[i].toString());
							column.put("$nin", $nin);
							this.query.put(columnName, column);
						}

						if ($in.contains(data[i].toString())) {
							$in.remove(data[i].toString());
							column.remove("$in");
							this.query.put(columnName, column);
						}

					}
				} else {

					if (this.query.isNull(columnName)) {
						this.query.put(columnName, (Object) null);
					}

					if (column.isNull("$in")) {
						$in = new ArrayList();
						column.put("$in", $in);
					}

					if (column.isNull("$nin")) {
						$nin = new ArrayList();
						column.put("$nin", $nin);
					}

					for (int i = 0; i < data.length; i++) {
						$nin.add(data[i].toString());
						if ($in.contains(data[i].toString())) {
							$in.remove(data[i].toString());
						}
					}
					column.put("$in", $in);
					column.remove("$in");
					column.put("$nin", $nin);
					this.query.put(columnName, column);
				}

			} else {
				throw new CloudException(
						"Pass only Integer, Double, String or CloudObject as an argument");
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return this;
	}

	/**
	 * 
	 * CloudQuery Contains All
	 * 
	 * @param columnName
	 * @param data
	 * @return CloudQuery
	 * @throws CloudException
	 */
	@SuppressWarnings("unchecked")
	public CloudQuery containsAll(String columnName, Object[] data)
			throws CloudException {

		if (columnName.equals("id") || columnName.equals("expires"))
			columnName = "_" + columnName;
		try {
			this.query.put("$include", $include);
			this.query.put("$includeList", $includeList);
			if (data instanceof CloudObject[] || data instanceof Integer[]
					|| data instanceof String[] || data instanceof Double[]) {

				ArrayList $all;
				CloudObject[] object = new CloudObject[data.length];
				JSONObject column = new JSONObject();
				if (this.query.has(columnName)) {
					column = this.query.getJSONObject(columnName);
				}
				if (data instanceof CloudObject[]) {

					for (int i = 0; i < data.length; i++) {
						object[i] = (CloudObject) data[i];
						if (object[i].getId() == null) {
							throw new CloudException(
									"CloudObject passed should be saved and should have an id before being passed to containedIn");
						}
						data[i] = object[i].getId();
					}

					if (this.query.has(columnName)) {
						this.query.put(columnName, JSONObject.NULL);
					}

					if (column.has("$all")) {
						$all = new ArrayList();
					}

					$all = (ArrayList) column.get("$all");

					for (int i = 0; i < data.length; i++) {
						if (!$all.contains(data[i])) {
							$all.add(data[i]);
						}
					}

					column.put("$all", $all);
					this.query.put(columnName, column);

				} else {

					if (this.query.has(columnName)) {
						this.query.put(columnName, JSONObject.NULL);
					}

					$all = new ArrayList();
					if (column.has("$all"))
						$all = PrivateMethod._toObjectArray(column
								.getJSONArray("$all"));

					for (int i = 0; i < data.length; i++) {
						$all.add(data[i]);
					}

					column.put("$all", $all);
					this.query.put(columnName, column);
				}

			} else {
				throw new CloudException(
						"Pass only Integer, Double, String or CloudObject as an argument");
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return this;
	}

	/**
	 * 
	 * CloudQuery Starts With
	 * 
	 * @param columnName
	 * @param value
	 * @return CloudQuery
	 */
	public CloudQuery startsWith(String columnName, Object value) {

		if (columnName.equals("id") || columnName.equals("expires"))
			columnName = "_" + columnName;

		String regex = "^" + value.toString();
		try {
			this.query.put(columnName, JSONObject.NULL);
			
			JSONObject args = new JSONObject();
			args.put("$regex", regex);
			args.put("$options", "im");
			this.query.put(columnName, args);
		} catch (JSONException e) {
			
			e.printStackTrace();
		}
		return this;
	}

	/**
	 * 
	 * CloudQuery Near
	 * 
	 * @param columnName
	 * @param geoPoint
	 * @param maxDistance
	 * @param minDistance
	 * @return CloudQuery
	 */
	public CloudQuery near(String columnName, CloudGeoPoint geoPoint,
			Double maxDistance, Double minDistance) {

		try {
			this.query.put(columnName, JSONObject.NULL);

			String $near = "{ '$geometry': {coordinates:"
					+ geoPoint.document.get("coordinates")
					+ " , type:'Point' }, '$maxDistance': " + maxDistance
					+ ", '$minDistance': " + minDistance + "}";
			this.query.put(columnName, $near);
		} catch (JSONException e) {
			
			e.printStackTrace();
		}
		return this;
	}

	/**
	 * 
	 * CloudQuery Geo With In
	 * 
	 * 
	 * @param columnName
	 * @param geoPoint
	 * @param radius
	 * @return CloudQuery
	 */
	//
	public CloudQuery geoWithin(String columnName, CloudGeoPoint geoPoint,
			Double radius) {

		try {
			this.query.put(columnName, JSONObject.NULL);

			String $geoWithin = "{ '$centerSphere':["
					+ geoPoint.document.get("coordinates") + ", " + radius
					/ 3963.2 + "] }";
			this.query.put(columnName, $geoWithin);
		} catch (JSONException e) {
			
			e.printStackTrace();
		}
		return this;
	}

	/**
	 * 
	 * CloudQuery Geo With In
	 * 
	 * @param columnName
	 * @param geoPoint
	 * @return CloudQuery
	 */
	public CloudQuery geoWithin(String columnName, CloudGeoPoint[] geoPoint) {
		JSONArray coordinates = new JSONArray();
		try {

			for (int i = 0; i < geoPoint.length; i++) {
				if (geoPoint[i].document.get("coordinates") != null) {
					JSONArray point = new JSONArray(geoPoint[i].document.get(
							"coordinates").toString());
					coordinates.put(point.get(0));
					coordinates.put(point.get(1));
				}
			}
			this.query.put(columnName, JSONObject.NULL);
			String $geoWithin = "{ '$geometry':{ 'type': 'Polygon', 'coordinates': "
					+ coordinates.toString() + "} }";
			this.query.put(columnName, $geoWithin);
		} catch (JSONException e) {
			
			e.printStackTrace();
		}
		return this;
	}

	public void count(CloudIntegerCallback callbackObject)
			throws CloudException {
		if (CloudApp.getAppId() == null) {
			throw new CloudException("App Id is null");
		}

		JSONObject params = new JSONObject();
		try {
			params.put("query", this.query);

			params.put("limit", this.limit);
			params.put("skip", this.skip);
			params.put("key", CloudApp.getAppKey());
		} catch (JSONException e2) {
			
			e2.printStackTrace();
		}
		String url = CloudApp.getApiUrl() + "/data/" + CloudApp.getAppId()
				+ "/" + this.tableName + "/count";
		CBResponse response=CBParser.callJson(url, "POST", params);
		if(response.getStatusCode()==200){
			callbackObject.done(Integer.valueOf(response.getResponseBody()), null);
			
		}else callbackObject.done(null, new CloudException(response.getStatusMessage()));

	}

	public void distinct(String[] keys, CloudObjectArrayCallback callbackObject)
			throws CloudException {
		if (CloudApp.getAppId() == null) {
			throw new CloudException("App Id is null");
		}

		JSONObject params = new JSONObject();
		try {
			params.put("query", this.query);

			params.put("onKey", keys);
			params.put("select", this.select);
			params.put("limit", this.limit);
			params.put("skip", this.skip);
			params.put("key", CloudApp.getAppKey());

		String url = CloudApp.getApiUrl() + "/data/" + CloudApp.getAppId()
				+ "/" + this.tableName + "/distinct";

		CBResponse response=CBParser.callJson(url, "POST", params);
		 if(response.getStatusCode() == 200){
		 JSONArray body = new JSONArray(response.getResponseBody());
		 CloudObject[] object = new CloudObject[body.length()];
		
		 for(int i=0; i0){
			if(totalItemsPerPage>0){
				setSkip((pageNo*totalItemsPerPage)-totalItemsPerPage);
				setLimit(totalItemsPerPage);
			}
		}
		if(totalItemsPerPage>0)
			setLimit(totalItemsPerPage);
		find(new CloudObjectArrayCallback() {
			
			@Override
			public void done(final CloudObject[] x, CloudException t) throws CloudException {
				
				if(t!=null)
					callback.done(null, null, null, t);
				else{
					setSkip(0);
					setLimit(99999999);
					count(new CloudIntegerCallback() {
						
						@Override
						public void done(Integer count, CloudException e) throws CloudException {
							if(e!=null)
								callback.done(null, null, null, e);
							else{
								callback.done(x, count, (int) Math.ceil(count/totalItems), null);
							}
							
						}
					});
				}
				
			}
		});
			
	}
}