001/* 002 * Copyright 2015-2022 Transmogrify LLC, 2022-2024 Revetware LLC. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.pyranid; 018 019import javax.annotation.Nonnull; 020import javax.annotation.Nullable; 021import javax.annotation.concurrent.NotThreadSafe; 022import javax.annotation.concurrent.ThreadSafe; 023import java.util.ArrayList; 024import java.util.Arrays; 025import java.util.Collections; 026import java.util.List; 027import java.util.Objects; 028import java.util.Optional; 029import java.util.stream.Collectors; 030 031import static java.lang.String.format; 032import static java.util.Objects.requireNonNull; 033 034/** 035 * Data that represents a SQL statement. 036 * 037 * @author <a href="https://www.revetkn.com">Mark Allen</a> 038 * @since 2.0.0 039 */ 040@ThreadSafe 041public class StatementContext<T> { 042 @Nonnull 043 private final Statement statement; 044 @Nonnull 045 private final List<Object> parameters; 046 @Nullable 047 private final Class<T> resultSetRowType; 048 049 protected StatementContext(@Nonnull Builder builder) { 050 requireNonNull(builder); 051 052 this.statement = builder.statement; 053 this.parameters = builder.parameters == null ? List.of() : Collections.unmodifiableList(builder.parameters); 054 this.resultSetRowType = builder.resultSetRowType; 055 } 056 057 @Override 058 public int hashCode() { 059 return Objects.hash(getStatement(), getParameters(), getResultSetRowType()); 060 } 061 062 @Override 063 public boolean equals(Object object) { 064 if (this == object) 065 return true; 066 067 if (!(object instanceof StatementContext)) 068 return false; 069 070 StatementContext statementContext = (StatementContext) object; 071 072 return Objects.equals(statementContext.getStatement(), getStatement()) 073 && Objects.equals(statementContext.getParameters(), getParameters()) 074 && Objects.equals(statementContext.getResultSetRowType(), getResultSetRowType()); 075 } 076 077 @Override 078 public String toString() { 079 List<String> components = new ArrayList<>(3); 080 081 components.add(format("statement=%s", getStatement())); 082 083 if (getParameters().size() > 0) 084 components.add(format("parameters=%s", getParameters())); 085 086 Class<T> resultSetRowType = getResultSetRowType().orElse(null); 087 088 if (resultSetRowType != null) 089 components.add(format("resultSetRowType=%s", resultSetRowType)); 090 091 return format("%s{%s}", getClass().getSimpleName(), components.stream().collect(Collectors.joining(", "))); 092 } 093 094 @Nonnull 095 public Statement getStatement() { 096 return this.statement; 097 } 098 099 @Nonnull 100 public List<Object> getParameters() { 101 return this.parameters; 102 } 103 104 @Nonnull 105 public Optional<Class<T>> getResultSetRowType() { 106 return Optional.ofNullable(this.resultSetRowType); 107 } 108 109 /** 110 * Builder used to construct instances of {@link StatementContext}. 111 * <p> 112 * This class is intended for use by a single thread. 113 * 114 * @author <a href="https://www.revetkn.com">Mark Allen</a> 115 * @since 2.0.0 116 */ 117 @NotThreadSafe 118 public static class Builder<T> { 119 @Nonnull 120 private final Statement statement; 121 @Nullable 122 private List<Object> parameters; 123 @Nullable 124 private Class<T> resultSetRowType; 125 126 public Builder(@Nonnull Statement statement) { 127 requireNonNull(statement); 128 this.statement = statement; 129 } 130 131 @Nonnull 132 public Builder parameters(@Nullable List<Object> parameters) { 133 this.parameters = parameters; 134 return this; 135 } 136 137 @Nonnull 138 public Builder parameters(@Nullable Object... parameters) { 139 this.parameters = parameters == null ? null : Arrays.asList(parameters); 140 return this; 141 } 142 143 @Nonnull 144 public Builder resultSetRowType(Class<T> resultSetRowType) { 145 this.resultSetRowType = resultSetRowType; 146 return this; 147 } 148 149 @Nonnull 150 public StatementContext build() { 151 return new StatementContext(this); 152 } 153 } 154}