mirror of
https://github.com/ent/ent.git
synced 2026-03-05 19:35:23 +03:00
doc/features: add dynamic values support (#3436)
This commit is contained in:
@@ -2217,7 +2217,7 @@ func (s *Selector) AppendSelect(columns ...string) *Selector {
|
||||
// AppendSelectAs appends additional column to the SELECT statement with the given alias.
|
||||
func (s *Selector) AppendSelectAs(column, as string) *Selector {
|
||||
s.selection = append(s.selection, ExprFunc(func(b *Builder) {
|
||||
if b.isIdent(column) {
|
||||
if b.isIdent(column) || isFunc(column) || isModifier(column) {
|
||||
b.WriteString(column)
|
||||
} else {
|
||||
b.WriteString(s.C(column))
|
||||
|
||||
@@ -353,6 +353,12 @@ func TestInterface(t *testing.T) {
|
||||
require.Equal(t, []driver.Value{int64(10), int64(20)}, values)
|
||||
}
|
||||
|
||||
func TestScanTypeOf(t *testing.T) {
|
||||
mock := &Rows{ColumnScanner: toRows(sqlmock.NewRows([]string{"age"}).AddRow(10))}
|
||||
tv := ScanTypeOf(mock, 0)
|
||||
require.IsType(t, (*any)(nil), tv)
|
||||
}
|
||||
|
||||
func toRows(mrows *sqlmock.Rows) *sql.Rows {
|
||||
db, mock, _ := sqlmock.New()
|
||||
mock.ExpectQuery("").WillReturnRows(mrows)
|
||||
|
||||
@@ -144,6 +144,30 @@ The above code will produce the following SQL query:
|
||||
SELECT SUM(LENGTH(name)) FROM `pet`
|
||||
```
|
||||
|
||||
#### Select and Scan Dynamic Values
|
||||
|
||||
If you work with SQL modifiers and need to scan dynamic values not present in your Ent schema definition, such as
|
||||
aggregation or custom ordering, you can apply `AppendSelect`/`AppendSelectAs` to the `sql.Selector`. You can later
|
||||
access their values using the `Value` method defined on each entity:
|
||||
|
||||
```go {6,11}
|
||||
const as = "name_length"
|
||||
|
||||
// Query the entity with the dynamic value.
|
||||
p := client.Pet.Query().
|
||||
Modify(func(s *sql.Selector) {
|
||||
s.AppendSelectAs("LENGTH(name)", as)
|
||||
}).
|
||||
FirstX(ctx)
|
||||
|
||||
// Read the value from the entity.
|
||||
n, err := p.Value(as)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println("Name length: %d == %d", n, len(p.Name))
|
||||
```
|
||||
|
||||
#### Modify Example 2
|
||||
|
||||
```go
|
||||
|
||||
@@ -24,8 +24,6 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/entc/integration/ent/exvaluescan"
|
||||
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
sqlschema "entgo.io/ent/dialect/sql/schema"
|
||||
@@ -33,6 +31,7 @@ import (
|
||||
"entgo.io/ent/entc/integration/ent"
|
||||
"entgo.io/ent/entc/integration/ent/card"
|
||||
"entgo.io/ent/entc/integration/ent/enttest"
|
||||
"entgo.io/ent/entc/integration/ent/exvaluescan"
|
||||
"entgo.io/ent/entc/integration/ent/file"
|
||||
"entgo.io/ent/entc/integration/ent/filetype"
|
||||
"entgo.io/ent/entc/integration/ent/group"
|
||||
@@ -779,6 +778,19 @@ func Select(t *testing.T, client *ent.Client) {
|
||||
}).
|
||||
ExecX(ctx)
|
||||
require.True(allUpper(), "at names must be upper-cased")
|
||||
|
||||
// Select and scan dynamic values.
|
||||
const as = "name_length"
|
||||
pets = client.Pet.Query().
|
||||
Modify(func(s *sql.Selector) {
|
||||
s.AppendSelectAs("LENGTH(name)", as)
|
||||
}).
|
||||
AllX(ctx)
|
||||
for _, p := range pets {
|
||||
n, err := p.Value(as)
|
||||
require.NoError(err)
|
||||
require.EqualValues(len(p.Name), n)
|
||||
}
|
||||
}
|
||||
|
||||
func Aggregate(t *testing.T, client *ent.Client) {
|
||||
|
||||
Reference in New Issue
Block a user