• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

torand / FasterSQL / 12970217277

26 Jan 2025 01:31AM UTC coverage: 49.458%. Remained the same
12970217277

push

github

torand
refactor: condition -> predicate

108 of 322 branches covered (33.54%)

Branch coverage included in aggregate %.

58 of 137 new or added lines in 12 files covered. (42.34%)

3 existing lines in 2 files now uncovered.

622 of 1154 relevant lines covered (53.9%)

2.85 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.1
/src/main/java/io/github/torand/fastersql/statement/UpdateStatement.java
1
/*
2
 * Copyright (c) 2024 Tore Eide Andersen
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
package io.github.torand.fastersql.statement;
17

18
import io.github.torand.fastersql.Context;
19
import io.github.torand.fastersql.Field;
20
import io.github.torand.fastersql.Table;
21
import io.github.torand.fastersql.constant.Constant;
22
import io.github.torand.fastersql.function.Function;
23
import io.github.torand.fastersql.predicate.OptionalPredicate;
24
import io.github.torand.fastersql.predicate.Predicate;
25
import io.github.torand.fastersql.util.functional.Optionals;
26

27
import java.util.Collection;
28
import java.util.List;
29
import java.util.Optional;
30
import java.util.stream.Stream;
31

32
import static io.github.torand.fastersql.Command.UPDATE;
33
import static io.github.torand.fastersql.util.collection.CollectionHelper.*;
34
import static io.github.torand.fastersql.util.contract.Requires.requireNonEmpty;
35
import static java.util.Objects.requireNonNull;
36
import static java.util.stream.Collectors.joining;
37

38
public class UpdateStatement extends PreparableStatement {
39
    private final Table<?> table;
40
    private final List<FieldValue> fieldValues;
41
    private final List<Predicate> predicates;
42

43
    UpdateStatement(Table<?> table, Collection<FieldValue> fieldValues, Collection<Predicate> predicates) {
2✔
44
        this.table = requireNonNull(table, "No table specified");
6✔
45
        this.fieldValues = asList(fieldValues);
4✔
46
        this.predicates = asList(predicates);
4✔
47
    }
1✔
48

49
    public UpdateStatement set(Field field, Constant constant) {
50
        requireNonNull(field, "No field specified");
×
51
        requireNonNull(constant, "No constant specified");
×
52

53
        List<FieldValue> concatenated = concat(this.fieldValues, new FieldValue(field, constant.value()));
×
NEW
54
        return new UpdateStatement(table, concatenated, predicates);
×
55
    }
56

57
    public UpdateStatement set(Field field, Function function) {
58
        requireNonNull(field, "No field specified");
4✔
59
        requireNonNull(function, "No function specified");
4✔
60

61
        List<FieldValue> concatenated = concat(this.fieldValues, new FieldValue(field, function));
14✔
62
        return new UpdateStatement(table, concatenated, predicates);
9✔
63
    }
64

65
    public UpdateStatement set(Field field, Object value) {
66
        requireNonNull(field, "No field specified");
4✔
67

68
        List<FieldValue> concatenated = concat(this.fieldValues, new FieldValue(field, value));
14✔
69
        return new UpdateStatement(table, concatenated, predicates);
9✔
70
    }
71

72
    public UpdateStatement set(Field field, Optional<?> maybeValue) {
73
        requireNonNull(field, "No field specified");
×
74
        requireNonNull(maybeValue, "No value specified");
×
75

76
        if (maybeValue.isPresent()) {
×
77
            List<FieldValue> concatenated = concat(this.fieldValues, new FieldValue(field, maybeValue.get()));
×
NEW
78
            return new UpdateStatement(table, concatenated, predicates);
×
79
        } else {
80
            return this;
×
81
        }
82
    }
83

84
    public UpdateStatement where(Predicate... predicates) {
85
        requireNonEmpty(predicates, "No predicates specified");
6✔
86

87
        List<Predicate> concatenated = concat(this.predicates, predicates);
5✔
88
        return new UpdateStatement(table, fieldValues, concatenated);
9✔
89
    }
90

91
    /**
92
     * Same as other method of same name, but only adds to the where clause predicates that are present.
93
     * @param maybePredicates the predicates that may be present or not
94
     * @return updated statement, for method chaining
95
     */
96
    public final UpdateStatement where(OptionalPredicate... maybePredicates) {
NEW
97
        requireNonEmpty(maybePredicates, "No optional predicates specified");
×
98

NEW
99
        List<Predicate> concatenated = concat(this.predicates, OptionalPredicate.unwrap(maybePredicates));
×
100
        return new UpdateStatement(table, fieldValues, concatenated);
×
101
    }
102

103
    @Override
104
    String sql(Context context) {
105
        final Context localContext = context.withCommand(UPDATE);
4✔
106
        validate();
2✔
107

108
        StringBuilder sb = new StringBuilder();
4✔
109
        sb.append("update ");
4✔
110
        sb.append(table.sql(context));
7✔
111
        sb.append(" set ");
4✔
112
        sb.append(streamSafely(fieldValues).map(fv -> fv.field().sql(localContext) + " = " + fv.valueSql(localContext)).collect(joining(", ")));
22✔
113
        if (nonEmpty(predicates)) {
4!
114
            sb.append(" where ");
4✔
115
            sb.append(streamSafely(predicates).map(e -> e.sql(localContext)).collect(joining(" and ")));
17✔
116
        }
117

118
        return sb.toString();
3✔
119
    }
120

121
    @Override
122
    List<Object> params(Context context) {
123
        return Stream.concat(streamSafely(fieldValues).map(FieldValue::param).flatMap(Optionals::stream), streamSafely(predicates).flatMap(e -> e.params(context))).toList();
20✔
124
    }
125

126
    private void validate() {
127
        if (isEmpty(fieldValues)) {
4!
128
            throw new IllegalStateException("No values to set");
×
129
        }
130
        validateFieldTableRelations(streamSafely(fieldValues).map(FieldValue::field));
7✔
131
        validateFieldTableRelations(streamSafely(predicates).flatMap(Predicate::fieldRefs));
7✔
132
    }
1✔
133

134
    private void validateFieldTableRelations(Stream<Field> fields) {
135
        fields
3✔
136
            .filter(f -> !table.name().equalsIgnoreCase(f.table().name()))
11!
137
            .findFirst()
2✔
138
            .ifPresent(f -> {
1✔
139
                throw new IllegalStateException("Field " + f.name() + " belongs to table " + f.table().name() + ", but is not specified in the UPDATE clause");
×
140
            });
141
    }
1✔
142
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc