1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.dynamic.sql.insert.render;
17
18 import static org.mybatis.dynamic.sql.util.StringUtilities.spaceAfter;
19
20 import java.util.Objects;
21 import java.util.stream.Collectors;
22
23 import org.jspecify.annotations.Nullable;
24 import org.mybatis.dynamic.sql.SqlColumn;
25 import org.mybatis.dynamic.sql.insert.InsertColumnListModel;
26 import org.mybatis.dynamic.sql.insert.InsertSelectModel;
27 import org.mybatis.dynamic.sql.render.RenderingContext;
28 import org.mybatis.dynamic.sql.render.RenderingStrategy;
29 import org.mybatis.dynamic.sql.select.render.SubQueryRenderer;
30 import org.mybatis.dynamic.sql.util.FragmentAndParameters;
31
32 public class InsertSelectRenderer {
33
34 private final InsertSelectModel model;
35 private final RenderingContext renderingContext;
36
37 private InsertSelectRenderer(Builder builder) {
38 model = Objects.requireNonNull(builder.model);
39 renderingContext = RenderingContext.withRenderingStrategy(Objects.requireNonNull(builder.renderingStrategy))
40 .withStatementConfiguration(model.statementConfiguration())
41 .build();
42 }
43
44 public InsertSelectStatementProvider render() {
45 String statementStart = InsertRenderingUtilities.calculateInsertStatementStart(model.table());
46 String columnsPhrase = calculateColumnsPhrase();
47 String prefix = statementStart + spaceAfter(columnsPhrase);
48
49 FragmentAndParameters fragmentAndParameters = SubQueryRenderer.withSelectModel(model.selectModel())
50 .withRenderingContext(renderingContext)
51 .withPrefix(prefix)
52 .build()
53 .render();
54
55 return DefaultGeneralInsertStatementProvider.withInsertStatement(fragmentAndParameters.fragment())
56 .withParameters(fragmentAndParameters.parameters())
57 .build();
58 }
59
60 private String calculateColumnsPhrase() {
61 return model.columnList().map(this::calculateColumnsPhrase).orElse("");
62 }
63
64 private String calculateColumnsPhrase(InsertColumnListModel columnList) {
65 return columnList.columns()
66 .map(SqlColumn::name)
67 .collect(Collectors.joining(", ", " (", ")"));
68 }
69
70 public static Builder withInsertSelectModel(InsertSelectModel model) {
71 return new Builder().withInsertSelectModel(model);
72 }
73
74 public static class Builder {
75 private @Nullable InsertSelectModel model;
76 private @Nullable RenderingStrategy renderingStrategy;
77
78 public Builder withInsertSelectModel(InsertSelectModel model) {
79 this.model = model;
80 return this;
81 }
82
83 public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) {
84 this.renderingStrategy = renderingStrategy;
85 return this;
86 }
87
88 public InsertSelectRenderer build() {
89 return new InsertSelectRenderer(this);
90 }
91 }
92 }