1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.healthconnect.storage.utils; 18 19 import com.android.server.healthconnect.storage.request.ReadTableRequest; 20 21 import java.util.ArrayList; 22 import java.util.List; 23 import java.util.stream.Collectors; 24 25 /** @hide */ 26 public final class WhereClauses { 27 private final List<String> mClauses = new ArrayList<>(); 28 private boolean mUseOr = false; 29 addWhereBetweenClause(String columnName, long start, long end)30 public WhereClauses addWhereBetweenClause(String columnName, long start, long end) { 31 mClauses.add(columnName + " BETWEEN " + start + " AND " + end); 32 33 return this; 34 } 35 addWhereBetweenTimeClause(String columnName, long startTime, long endTime)36 public WhereClauses addWhereBetweenTimeClause(String columnName, long startTime, long endTime) { 37 if (endTime < 0 || endTime < startTime) { 38 // Below method has check for startTime less than 0. 39 // If both startTime and endTime are less than 0 then no new time clause will be added 40 // and just return current object. 41 return addWhereLaterThanTimeClause(columnName, startTime); 42 } 43 44 mClauses.add(columnName + " BETWEEN " + startTime + " AND " + endTime); 45 46 return this; 47 } 48 addWhereLaterThanTimeClause(String columnName, long startTime)49 public WhereClauses addWhereLaterThanTimeClause(String columnName, long startTime) { 50 if (startTime < 0) { 51 return this; 52 } 53 54 mClauses.add(columnName + " > " + startTime); 55 56 return this; 57 } 58 addWhereInClause(String columnName, List<String> values)59 public WhereClauses addWhereInClause(String columnName, List<String> values) { 60 if (values == null || values.isEmpty()) return this; 61 62 mClauses.add(columnName + " IN " + "('" + String.join("', '", values) + "')"); 63 64 return this; 65 } 66 addWhereInClauseWithoutQuotes(String columnName, List<String> values)67 public WhereClauses addWhereInClauseWithoutQuotes(String columnName, List<String> values) { 68 if (values == null || values.isEmpty()) return this; 69 70 mClauses.add(columnName + " IN " + "(" + String.join(", ", values) + ")"); 71 72 return this; 73 } 74 addWhereEqualsClause(String columnName, String value)75 public WhereClauses addWhereEqualsClause(String columnName, String value) { 76 if (columnName == null || value == null || value.isEmpty() || columnName.isEmpty()) { 77 return this; 78 } 79 80 mClauses.add(columnName + " = " + StorageUtils.getNormalisedString(value)); 81 return this; 82 } 83 addWhereGreaterThanClause(String columnName, String value)84 public WhereClauses addWhereGreaterThanClause(String columnName, String value) { 85 mClauses.add(columnName + " > '" + value + "'"); 86 87 return this; 88 } 89 90 /** Add clause columnName > value */ addWhereGreaterThanClause(String columnName, long value)91 public WhereClauses addWhereGreaterThanClause(String columnName, long value) { 92 mClauses.add(columnName + " > " + value); 93 94 return this; 95 } 96 addWhereGreaterThanOrEqualClause(String columnName, long value)97 public WhereClauses addWhereGreaterThanOrEqualClause(String columnName, long value) { 98 mClauses.add(columnName + " >= " + value); 99 100 return this; 101 } 102 addWhereLessThanOrEqualClause(String columnName, long value)103 public WhereClauses addWhereLessThanOrEqualClause(String columnName, long value) { 104 mClauses.add(columnName + " <= " + value); 105 106 return this; 107 } 108 109 /** Add clause columnName < value */ addWhereLessThanClause(String columnName, long value)110 public WhereClauses addWhereLessThanClause(String columnName, long value) { 111 mClauses.add(columnName + " < " + value); 112 113 return this; 114 } 115 addWhereInIntsClause(String columnName, List<Integer> values)116 public WhereClauses addWhereInIntsClause(String columnName, List<Integer> values) { 117 if (values == null || values.isEmpty()) return this; 118 119 mClauses.add( 120 columnName 121 + " IN (" 122 + values.stream().map(String::valueOf).collect(Collectors.joining(", ")) 123 + ")"); 124 125 return this; 126 } 127 128 /** 129 * Adds where in condition for the column 130 * 131 * @param columnName Column name on which where condition to be applied 132 * @param values to check in the where condition 133 */ addWhereInLongsClause(String columnName, List<Long> values)134 public WhereClauses addWhereInLongsClause(String columnName, List<Long> values) { 135 if (values == null || values.isEmpty()) return this; 136 137 mClauses.add( 138 columnName 139 + " IN (" 140 + values.stream().map(String::valueOf).collect(Collectors.joining(", ")) 141 + ")"); 142 143 return this; 144 } 145 146 /** 147 * Creates IN clause, where in range is another SQL request. Returns instance with extra clauses 148 * set. 149 */ addWhereInSQLRequestClause(String columnName, ReadTableRequest inRequest)150 public WhereClauses addWhereInSQLRequestClause(String columnName, ReadTableRequest inRequest) { 151 mClauses.add(columnName + " IN (" + inRequest.getReadCommand() + ") "); 152 153 return this; 154 } 155 156 /** 157 * Returns where clauses joined by 'AND', if the input parameter isIncludeWHEREinClauses is true 158 * then the clauses are preceded by 'WHERE'. 159 */ get(boolean withWhereKeyword)160 public String get(boolean withWhereKeyword) { 161 if (mClauses.isEmpty()) { 162 return ""; 163 } 164 165 return (withWhereKeyword ? " WHERE " : "") + String.join(getJoinClause(), mClauses); 166 } 167 getJoinClause()168 private String getJoinClause() { 169 return mUseOr ? " OR " : " AND "; 170 } 171 setUseOr(boolean useOr)172 public WhereClauses setUseOr(boolean useOr) { 173 mUseOr = useOr; 174 175 return this; 176 } 177 } 178