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 static final String PARAMETER_NAME = RenderingStrategy.DEFAULT_PARAMETER_PREFIX;
42 private final StatementConfiguration statementConfiguration;
43
44 private RenderingContext(Builder builder) {
45 renderingStrategy = Objects.requireNonNull(builder.renderingStrategy);
46 tableAliasCalculator = Objects.requireNonNull(builder.tableAliasCalculator);
47 statementConfiguration = Objects.requireNonNull(builder.statementConfiguration);
48 sequence = Objects.requireNonNullElseGet(builder.sequence, () -> new AtomicInteger(1));
49 }
50
51 private String nextMapKey() {
52 return renderingStrategy.formatParameterMapKey(sequence);
53 }
54
55 private <T> String renderedPlaceHolder(String mapKey, BindableColumn<T> column) {
56 return column.renderingStrategy().orElse(renderingStrategy)
57 .getFormattedJdbcPlaceholder(column, PARAMETER_NAME, mapKey);
58 }
59
60 public RenderedParameterInfo calculateFetchFirstRowsParameterInfo() {
61 String mapKey = renderingStrategy.formatParameterMapKeyForFetchFirstRows(sequence);
62 return new RenderedParameterInfo(mapKey,
63 renderingStrategy.getFormattedJdbcPlaceholderForPagingParameters(PARAMETER_NAME, mapKey));
64 }
65
66 public RenderedParameterInfo calculateLimitParameterInfo() {
67 String mapKey = renderingStrategy.formatParameterMapKeyForLimit(sequence);
68 return new RenderedParameterInfo(mapKey,
69 renderingStrategy.getFormattedJdbcPlaceholderForPagingParameters(PARAMETER_NAME, mapKey));
70 }
71
72 public RenderedParameterInfo calculateOffsetParameterInfo() {
73 String mapKey = renderingStrategy.formatParameterMapKeyForOffset(sequence);
74 return new RenderedParameterInfo(mapKey,
75 renderingStrategy.getFormattedJdbcPlaceholderForPagingParameters(PARAMETER_NAME, mapKey));
76 }
77
78 public <T> RenderedParameterInfo calculateParameterInfo(BindableColumn<T> column) {
79 String mapKey = nextMapKey();
80 return new RenderedParameterInfo(mapKey, renderedPlaceHolder(mapKey, column));
81 }
82
83 public <T> String aliasedColumnName(SqlColumn<T> column) {
84 return tableAliasCalculator.aliasForColumn(column.table())
85 .map(alias -> aliasedColumnName(column, alias))
86 .orElseGet(column::name);
87 }
88
89 public <T> String aliasedColumnName(SqlColumn<T> column, String explicitAlias) {
90 return explicitAlias + "." + column.name();
91 }
92
93 public String aliasedTableName(SqlTable table) {
94 return tableAliasCalculator.aliasForTable(table)
95 .map(a -> table.tableName() + spaceBefore(a))
96 .orElseGet(table::tableName);
97 }
98
99 public boolean isNonRenderingClauseAllowed() {
100 return statementConfiguration.isNonRenderingWhereClauseAllowed();
101 }
102
103
104
105
106
107
108
109
110
111
112 public RenderingContext withChildTableAliasCalculator(TableAliasCalculator childTableAliasCalculator) {
113 TableAliasCalculator tac = new TableAliasCalculatorWithParent.Builder()
114 .withParent(tableAliasCalculator)
115 .withChild(childTableAliasCalculator)
116 .build();
117
118 return new Builder()
119 .withRenderingStrategy(this.renderingStrategy)
120 .withSequence(this.sequence)
121 .withTableAliasCalculator(tac)
122 .withStatementConfiguration(statementConfiguration)
123 .build();
124 }
125
126 public static Builder withRenderingStrategy(RenderingStrategy renderingStrategy) {
127 return new Builder().withRenderingStrategy(renderingStrategy);
128 }
129
130 public static class Builder {
131 private @Nullable RenderingStrategy renderingStrategy;
132 private @Nullable AtomicInteger sequence;
133 private @Nullable TableAliasCalculator tableAliasCalculator = TableAliasCalculator.empty();
134 private @Nullable StatementConfiguration statementConfiguration;
135
136 public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) {
137 this.renderingStrategy = renderingStrategy;
138 return this;
139 }
140
141 public Builder withSequence(AtomicInteger sequence) {
142 this.sequence = sequence;
143 return this;
144 }
145
146 public Builder withTableAliasCalculator(TableAliasCalculator tableAliasCalculator) {
147 this.tableAliasCalculator = tableAliasCalculator;
148 return this;
149 }
150
151 public Builder withStatementConfiguration(StatementConfiguration statementConfiguration) {
152 this.statementConfiguration = statementConfiguration;
153 return this;
154 }
155
156 public RenderingContext build() {
157 return new RenderingContext(this);
158 }
159 }
160 }