1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.dynamic.sql.render;
17
18 import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore;
19
20 import java.util.Objects;
21 import java.util.concurrent.atomic.AtomicInteger;
22
23 import org.jspecify.annotations.Nullable;
24 import org.mybatis.dynamic.sql.BindableColumn;
25 import org.mybatis.dynamic.sql.SqlColumn;
26 import org.mybatis.dynamic.sql.SqlTable;
27 import org.mybatis.dynamic.sql.configuration.StatementConfiguration;
28
29
30
31
32
33
34
35
36 public class RenderingContext {
37
38 private final RenderingStrategy renderingStrategy;
39 private final AtomicInteger sequence;
40 private final TableAliasCalculator tableAliasCalculator;
41 private final @Nullable String configuredParameterName;
42 private final String calculatedParameterName;
43 private final StatementConfiguration statementConfiguration;
44
45 private RenderingContext(Builder builder) {
46 renderingStrategy = Objects.requireNonNull(builder.renderingStrategy);
47 configuredParameterName = builder.parameterName;
48 tableAliasCalculator = Objects.requireNonNull(builder.tableAliasCalculator);
49 statementConfiguration = Objects.requireNonNull(builder.statementConfiguration);
50
51
52 sequence = builder.sequence == null ? new AtomicInteger(1) : builder.sequence;
53 calculatedParameterName = builder.parameterName == null ? RenderingStrategy.DEFAULT_PARAMETER_PREFIX
54 : builder.parameterName + "." + RenderingStrategy.DEFAULT_PARAMETER_PREFIX;
55 }
56
57 private String nextMapKey() {
58 return renderingStrategy.formatParameterMapKey(sequence);
59 }
60
61 private <T> String renderedPlaceHolder(String mapKey, BindableColumn<T> column) {
62 return column.renderingStrategy().orElse(renderingStrategy)
63 .getFormattedJdbcPlaceholder(column, calculatedParameterName, mapKey);
64 }
65
66 public RenderedParameterInfo calculateFetchFirstRowsParameterInfo() {
67 String mapKey = renderingStrategy.formatParameterMapKeyForFetchFirstRows(sequence);
68 return new RenderedParameterInfo(mapKey,
69 renderingStrategy.getFormattedJdbcPlaceholderForPagingParameters(calculatedParameterName, mapKey));
70 }
71
72 public RenderedParameterInfo calculateLimitParameterInfo() {
73 String mapKey = renderingStrategy.formatParameterMapKeyForLimit(sequence);
74 return new RenderedParameterInfo(mapKey,
75 renderingStrategy.getFormattedJdbcPlaceholderForPagingParameters(calculatedParameterName, mapKey));
76 }
77
78 public RenderedParameterInfo calculateOffsetParameterInfo() {
79 String mapKey = renderingStrategy.formatParameterMapKeyForOffset(sequence);
80 return new RenderedParameterInfo(mapKey,
81 renderingStrategy.getFormattedJdbcPlaceholderForPagingParameters(calculatedParameterName, mapKey));
82 }
83
84 public <T> RenderedParameterInfo calculateParameterInfo(BindableColumn<T> column) {
85 String mapKey = nextMapKey();
86 return new RenderedParameterInfo(mapKey, renderedPlaceHolder(mapKey, column));
87 }
88
89 public <T> String aliasedColumnName(SqlColumn<T> column) {
90 return tableAliasCalculator.aliasForColumn(column.table())
91 .map(alias -> aliasedColumnName(column, alias))
92 .orElseGet(column::name);
93 }
94
95 public <T> String aliasedColumnName(SqlColumn<T> column, String explicitAlias) {
96 return explicitAlias + "." + column.name();
97 }
98
99 public String aliasedTableName(SqlTable table) {
100 return tableAliasCalculator.aliasForTable(table)
101 .map(a -> table.tableName() + spaceBefore(a))
102 .orElseGet(table::tableName);
103 }
104
105 public boolean isNonRenderingClauseAllowed() {
106 return statementConfiguration.isNonRenderingWhereClauseAllowed();
107 }
108
109
110
111
112
113
114
115
116
117
118 public RenderingContext withChildTableAliasCalculator(TableAliasCalculator childTableAliasCalculator) {
119 TableAliasCalculator tac = new TableAliasCalculatorWithParent.Builder()
120 .withParent(tableAliasCalculator)
121 .withChild(childTableAliasCalculator)
122 .build();
123
124 return new Builder()
125 .withRenderingStrategy(this.renderingStrategy)
126 .withSequence(this.sequence)
127 .withParameterName(this.configuredParameterName)
128 .withTableAliasCalculator(tac)
129 .withStatementConfiguration(statementConfiguration)
130 .build();
131 }
132
133 public static Builder withRenderingStrategy(RenderingStrategy renderingStrategy) {
134 return new Builder().withRenderingStrategy(renderingStrategy);
135 }
136
137 public static class Builder {
138 private @Nullable RenderingStrategy renderingStrategy;
139 private @Nullable AtomicInteger sequence;
140 private @Nullable TableAliasCalculator tableAliasCalculator = TableAliasCalculator.empty();
141 private @Nullable String parameterName;
142 private @Nullable StatementConfiguration statementConfiguration;
143
144 public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) {
145 this.renderingStrategy = renderingStrategy;
146 return this;
147 }
148
149 public Builder withSequence(AtomicInteger sequence) {
150 this.sequence = sequence;
151 return this;
152 }
153
154 public Builder withTableAliasCalculator(TableAliasCalculator tableAliasCalculator) {
155 this.tableAliasCalculator = tableAliasCalculator;
156 return this;
157 }
158
159 public Builder withParameterName(@Nullable String parameterName) {
160 this.parameterName = parameterName;
161 return this;
162 }
163
164 public Builder withStatementConfiguration(StatementConfiguration statementConfiguration) {
165 this.statementConfiguration = statementConfiguration;
166 return this;
167 }
168
169 public RenderingContext build() {
170 return new RenderingContext(this);
171 }
172 }
173 }