Added rs:new and rs:query
This commit is contained in:
parent
cb908ec4eb
commit
6bf721873b
|
@ -162,9 +162,12 @@ func main() {
|
|||
|
||||
commandController := commandctrl.NewCommandController(inputHistoryService,
|
||||
cmdpacks.StandardCommands{
|
||||
ReadController: tableReadController,
|
||||
WriteController: tableWriteController,
|
||||
ExportController: exportController,
|
||||
TableService: tableService,
|
||||
State: state,
|
||||
ReadController: tableReadController,
|
||||
WriteController: tableWriteController,
|
||||
ExportController: exportController,
|
||||
KeyBindingController: keyBindingController,
|
||||
},
|
||||
)
|
||||
commandController.AddCommandLookupExtension(scriptController)
|
||||
|
|
6
go.mod
6
go.mod
|
@ -1,8 +1,8 @@
|
|||
module github.com/lmika/dynamo-browse
|
||||
|
||||
go 1.22
|
||||
go 1.24
|
||||
|
||||
toolchain go1.22.0
|
||||
toolchain go1.24.0
|
||||
|
||||
require (
|
||||
github.com/alecthomas/participle/v2 v2.1.1
|
||||
|
@ -117,5 +117,5 @@ require (
|
|||
golang.org/x/text v0.9.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
ucl.lmika.dev v0.0.0-20250306030053-ad6d002a22e8 // indirect
|
||||
ucl.lmika.dev v0.0.0-20250517003439-109be33d1495 // indirect
|
||||
)
|
||||
|
|
4
go.sum
4
go.sum
|
@ -438,3 +438,7 @@ ucl.lmika.dev v0.0.0-20240504013531-0dc9fd3c3281 h1:/M7phiv/0XVp3wKkOxEnGQysf8+R
|
|||
ucl.lmika.dev v0.0.0-20240504013531-0dc9fd3c3281/go.mod h1:T6V4jIUxlWvMTgn4J752VDHNA8iyVrEX6v98EvDj8G4=
|
||||
ucl.lmika.dev v0.0.0-20250306030053-ad6d002a22e8 h1:vWttdW8GJWcTUQeJFbQHqCHJDLFWQ9nccUTx/lW2v8s=
|
||||
ucl.lmika.dev v0.0.0-20250306030053-ad6d002a22e8/go.mod h1:FMP2ncSu4UxfvB0iA2zlebwL+1UPCARdyYNOrmi86A4=
|
||||
ucl.lmika.dev v0.0.0-20250515115457-27b6cc0b92e2 h1:cvguOoQ0HVgLKbHH17ZHvAUFht6HXApLi0o8JOdaaNU=
|
||||
ucl.lmika.dev v0.0.0-20250515115457-27b6cc0b92e2/go.mod h1:/MMZKm6mOMtnY4I8TYEot4Pc8dKEy+/IAQo1VdpA5EY=
|
||||
ucl.lmika.dev v0.0.0-20250517003439-109be33d1495 h1:r46r+7T59Drm+in7TEWKCZfFYIM0ZyZ26QjHAbj8Lto=
|
||||
ucl.lmika.dev v0.0.0-20250517003439-109be33d1495/go.mod h1:/MMZKm6mOMtnY4I8TYEot4Pc8dKEy+/IAQo1VdpA5EY=
|
||||
|
|
123
internal/common/ui/commandctrl/cmdpacks/modrs.go
Normal file
123
internal/common/ui/commandctrl/cmdpacks/modrs.go
Normal file
|
@ -0,0 +1,123 @@
|
|||
package cmdpacks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/controllers"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/models"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/models/queryexpr"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/services/tables"
|
||||
"github.com/pkg/errors"
|
||||
"ucl.lmika.dev/repl"
|
||||
"ucl.lmika.dev/ucl"
|
||||
)
|
||||
|
||||
type rsModule struct {
|
||||
tableService *tables.Service
|
||||
state *controllers.State
|
||||
}
|
||||
|
||||
var rsNewDoc = repl.Doc{
|
||||
Brief: "Creates a new, empty result set",
|
||||
}
|
||||
|
||||
func (rs *rsModule) rsNew(ctx context.Context, args ucl.CallArgs) (any, error) {
|
||||
return &ResultSetProxy{
|
||||
RS: &models.ResultSet{},
|
||||
}, nil
|
||||
}
|
||||
|
||||
var rsQueryDoc = repl.Doc{
|
||||
Brief: "Runs a query and returns the results as a result-set",
|
||||
Usage: "QUERY [ARGS] [-table NAME]",
|
||||
Args: []repl.ArgDoc{
|
||||
{Name: "query", Brief: "Query expression to run"},
|
||||
{Name: "args", Brief: "Hash of argument values to substitute into the query"},
|
||||
{Name: "-table", Brief: "Optional table name to use for the query"},
|
||||
},
|
||||
Detailed: `
|
||||
If no table is specified, then the value of @table will be used. If this is unavailable,
|
||||
the command will return an error.
|
||||
`,
|
||||
}
|
||||
|
||||
func (rs *rsModule) rsQuery(ctx context.Context, args ucl.CallArgs) (any, error) {
|
||||
var expr string
|
||||
if err := args.Bind(&expr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
q, err := queryexpr.Parse(expr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if args.NArgs() > 0 {
|
||||
var queryArgs ucl.Hashable
|
||||
if err := args.Bind(&queryArgs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
queryNames := map[string]string{}
|
||||
queryValues := map[string]types.AttributeValue{}
|
||||
queryArgs.Each(func(k string, v ucl.Object) error {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
queryNames[k] = v.String()
|
||||
|
||||
switch v.(type) {
|
||||
case ucl.StringObject:
|
||||
queryValues[k] = &types.AttributeValueMemberS{Value: v.String()}
|
||||
case ucl.IntObject:
|
||||
queryValues[k] = &types.AttributeValueMemberN{Value: v.String()}
|
||||
// TODO: other types
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
q = q.WithNameParams(queryNames).WithValueParams(queryValues)
|
||||
}
|
||||
|
||||
var tableInfo *models.TableInfo
|
||||
if args.HasSwitch("table") {
|
||||
var tblName string
|
||||
if err := args.BindSwitch("table", &tblName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tableInfo, err = rs.tableService.Describe(ctx, tblName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if currRs := rs.state.ResultSet(); currRs != nil && currRs.TableInfo != nil {
|
||||
tableInfo = currRs.TableInfo
|
||||
} else {
|
||||
return nil, errors.New("no table specified")
|
||||
}
|
||||
|
||||
newResultSet, err := rs.tableService.ScanOrQuery(context.Background(), tableInfo, q, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ResultSetProxy{
|
||||
RS: newResultSet,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func moduleRS(tableService *tables.Service, state *controllers.State) ucl.Module {
|
||||
m := &rsModule{
|
||||
tableService: tableService,
|
||||
state: state,
|
||||
}
|
||||
|
||||
return ucl.Module{
|
||||
Name: "rs",
|
||||
Builtins: map[string]ucl.BuiltinHandler{
|
||||
"new": m.rsNew,
|
||||
"query": m.rsQuery,
|
||||
},
|
||||
}
|
||||
}
|
80
internal/common/ui/commandctrl/cmdpacks/modrs_test.go
Normal file
80
internal/common/ui/commandctrl/cmdpacks/modrs_test.go
Normal file
|
@ -0,0 +1,80 @@
|
|||
package cmdpacks_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/lmika/dynamo-browse/internal/common/ui/commandctrl/cmdpacks"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestModRS_New(t *testing.T) {
|
||||
svc := newService(t)
|
||||
|
||||
rsProxy, err := svc.CommandController.ExecuteAndWait(t.Context(), `rs:new`)
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.IsType(t, rsProxy, &cmdpacks.ResultSetProxy{})
|
||||
}
|
||||
|
||||
func TestModRS_Query(t *testing.T) {
|
||||
tests := []struct {
|
||||
descr string
|
||||
cmd string
|
||||
wantRows []int
|
||||
}{
|
||||
{
|
||||
descr: "query with pk 1",
|
||||
cmd: `rs:query 'pk="abc"' -table service-test-data`,
|
||||
wantRows: []int{0, 1},
|
||||
},
|
||||
{
|
||||
descr: "query with pk 2",
|
||||
cmd: `rs:query 'pk="bbb"' -table service-test-data`,
|
||||
wantRows: []int{2},
|
||||
},
|
||||
{
|
||||
descr: "query with sk 1",
|
||||
cmd: `rs:query 'sk="222"' -table service-test-data`,
|
||||
wantRows: []int{1},
|
||||
},
|
||||
{
|
||||
descr: "query with args 1",
|
||||
cmd: `rs:query 'pk=$v' [v:'abc'] -table service-test-data`,
|
||||
wantRows: []int{0, 1},
|
||||
},
|
||||
{
|
||||
descr: "query with args 2",
|
||||
cmd: `rs:query ':k=$v' [k:'pk' v:'abc'] -table service-test-data`,
|
||||
wantRows: []int{0, 1},
|
||||
},
|
||||
{
|
||||
descr: "query with args 3",
|
||||
cmd: `rs:query ':k=$v' [k:'beta' v:1231] -table service-test-data`,
|
||||
wantRows: []int{1},
|
||||
},
|
||||
{
|
||||
descr: "query with args with no table set",
|
||||
cmd: `rs:query ':k=$v' [k:'beta' v:1231]`,
|
||||
wantRows: []int{1},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.descr, func(t *testing.T) {
|
||||
svc := newService(t)
|
||||
|
||||
res, err := svc.CommandController.ExecuteAndWait(t.Context(), tt.cmd)
|
||||
assert.NoError(t, err)
|
||||
|
||||
rs := res.(*cmdpacks.ResultSetProxy).RS
|
||||
assert.Len(t, rs.Items(), len(tt.wantRows))
|
||||
|
||||
for i, rowIndex := range tt.wantRows {
|
||||
for key, want := range testData[0].Data[rowIndex] {
|
||||
have, ok := rs.Items()[i].AttributeValueAsString(key)
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, fmt.Sprint(want), have)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
7
internal/common/ui/commandctrl/cmdpacks/proxy.go
Normal file
7
internal/common/ui/commandctrl/cmdpacks/proxy.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package cmdpacks
|
||||
|
||||
import "github.com/lmika/dynamo-browse/internal/dynamo-browse/models"
|
||||
|
||||
type ResultSetProxy struct {
|
||||
RS *models.ResultSet
|
||||
}
|
|
@ -6,12 +6,15 @@ import (
|
|||
"github.com/lmika/dynamo-browse/internal/common/ui/commandctrl"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/controllers"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/models"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/services/tables"
|
||||
"github.com/pkg/errors"
|
||||
"ucl.lmika.dev/repl"
|
||||
"ucl.lmika.dev/ucl"
|
||||
)
|
||||
|
||||
type StandardCommands struct {
|
||||
TableService *tables.Service
|
||||
State *controllers.State
|
||||
ReadController *controllers.TableReadController
|
||||
WriteController *controllers.TableWriteController
|
||||
ExportController *controllers.ExportController
|
||||
|
@ -358,6 +361,12 @@ func (sc StandardCommands) cmdRebind(ctx context.Context, args ucl.CallArgs) (an
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (sc StandardCommands) InstOptions() []ucl.InstOption {
|
||||
return []ucl.InstOption{
|
||||
ucl.WithModule(moduleRS(sc.TableService, sc.State)),
|
||||
}
|
||||
}
|
||||
|
||||
func (sc StandardCommands) ConfigureUCL(ucl *ucl.Inst) {
|
||||
ucl.SetBuiltin("quit", sc.cmdQuit)
|
||||
ucl.SetBuiltin("table", sc.cmdTable)
|
||||
|
|
143
internal/common/ui/commandctrl/cmdpacks/stdcmds_test.go
Normal file
143
internal/common/ui/commandctrl/cmdpacks/stdcmds_test.go
Normal file
|
@ -0,0 +1,143 @@
|
|||
package cmdpacks_test
|
||||
|
||||
import (
|
||||
"github.com/lmika/dynamo-browse/internal/common/ui/commandctrl"
|
||||
"github.com/lmika/dynamo-browse/internal/common/ui/commandctrl/cmdpacks"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/controllers"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/providers/dynamo"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/providers/inputhistorystore"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/providers/pasteboardprovider"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/providers/settingstore"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/providers/workspacestore"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/services/inputhistory"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/services/itemrenderer"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/services/jobs"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/services/tables"
|
||||
"github.com/lmika/dynamo-browse/internal/dynamo-browse/services/viewsnapshot"
|
||||
"github.com/lmika/dynamo-browse/test/testdynamo"
|
||||
"github.com/lmika/dynamo-browse/test/testworkspace"
|
||||
bus "github.com/lmika/events"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStdCmds_Mark(t *testing.T) {
|
||||
tests := []struct {
|
||||
descr string
|
||||
cmd string
|
||||
wantMarks []bool
|
||||
}{
|
||||
{descr: "mark default", cmd: "mark", wantMarks: []bool{true, true, true}},
|
||||
{descr: "mark all", cmd: "mark all", wantMarks: []bool{true, true, true}},
|
||||
{descr: "mark none", cmd: "mark none", wantMarks: []bool{false, false, false}},
|
||||
{descr: "mark where", cmd: `mark -where 'sk="222"'`, wantMarks: []bool{false, true, false}},
|
||||
{descr: "mark toggle", cmd: "mark ; mark toggle", wantMarks: []bool{false, false, false}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.descr, func(t *testing.T) {
|
||||
svc := newService(t)
|
||||
|
||||
_, err := svc.CommandController.ExecuteAndWait(t.Context(), tt.cmd)
|
||||
assert.NoError(t, err)
|
||||
|
||||
for i, want := range tt.wantMarks {
|
||||
assert.Equal(t, want, svc.State.ResultSet().Marked(i))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type services struct {
|
||||
CommandController *commandctrl.CommandController
|
||||
SelItemIndex int
|
||||
|
||||
State *controllers.State
|
||||
}
|
||||
|
||||
func newService(t *testing.T) *services {
|
||||
ws := testworkspace.New(t)
|
||||
|
||||
resultSetSnapshotStore := workspacestore.NewResultSetSnapshotStore(ws)
|
||||
settingStore := settingstore.New(ws)
|
||||
inputHistoryStore := inputhistorystore.NewInputHistoryStore(ws)
|
||||
|
||||
workspaceService := viewsnapshot.NewService(resultSetSnapshotStore)
|
||||
itemRendererService := itemrenderer.NewService(itemrenderer.PlainTextRenderer(), itemrenderer.PlainTextRenderer())
|
||||
inputHistoryService := inputhistory.New(inputHistoryStore)
|
||||
|
||||
client := testdynamo.SetupTestTable(t, testData)
|
||||
|
||||
provider := dynamo.NewProvider(client)
|
||||
service := tables.NewService(provider, settingStore)
|
||||
eventBus := bus.New()
|
||||
|
||||
state := controllers.NewState()
|
||||
jobsController := controllers.NewJobsController(jobs.NewService(eventBus), eventBus, true)
|
||||
readController := controllers.NewTableReadController(
|
||||
state,
|
||||
service,
|
||||
workspaceService,
|
||||
itemRendererService,
|
||||
jobsController,
|
||||
inputHistoryService,
|
||||
eventBus,
|
||||
pasteboardprovider.NilProvider{},
|
||||
nil,
|
||||
"service-test-data",
|
||||
)
|
||||
writeController := controllers.NewTableWriteController(state, service, jobsController, readController, settingStore)
|
||||
settingsController := controllers.NewSettingsController(settingStore, eventBus)
|
||||
columnsController := controllers.NewColumnsController(readController, eventBus)
|
||||
exportController := controllers.NewExportController(state, service, jobsController, columnsController, pasteboardprovider.NilProvider{})
|
||||
|
||||
_ = settingsController
|
||||
commandController := commandctrl.NewCommandController(inputHistoryService,
|
||||
cmdpacks.StandardCommands{
|
||||
State: state,
|
||||
TableService: service,
|
||||
ReadController: readController,
|
||||
WriteController: writeController,
|
||||
ExportController: exportController,
|
||||
},
|
||||
)
|
||||
|
||||
s := &services{
|
||||
State: state,
|
||||
CommandController: commandController,
|
||||
}
|
||||
|
||||
commandController.SetUIStateProvider(s)
|
||||
readController.Init()
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *services) SelectedItemIndex() int {
|
||||
return s.SelItemIndex
|
||||
}
|
||||
|
||||
var testData = []testdynamo.TestData{
|
||||
{
|
||||
TableName: "service-test-data",
|
||||
Data: []map[string]interface{}{
|
||||
{
|
||||
"pk": "abc",
|
||||
"sk": "111",
|
||||
"alpha": "This is some value",
|
||||
},
|
||||
{
|
||||
"pk": "abc",
|
||||
"sk": "222",
|
||||
"alpha": "This is another some value",
|
||||
"beta": 1231,
|
||||
},
|
||||
{
|
||||
"pk": "bbb",
|
||||
"sk": "131",
|
||||
"beta": 2468,
|
||||
"gamma": "foobar",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
|
@ -43,11 +43,17 @@ func NewCommandController(historyProvider IterProvider, pkgs ...CommandPack) *Co
|
|||
msgChan: make(chan tea.Msg),
|
||||
interactive: true,
|
||||
}
|
||||
cc.uclInst = ucl.New(
|
||||
|
||||
options := []ucl.InstOption{
|
||||
ucl.WithOut(ucl.LineHandler(cc.printLine)),
|
||||
ucl.WithModule(builtins.OS()),
|
||||
ucl.WithModule(builtins.FS(nil)),
|
||||
)
|
||||
}
|
||||
for _, pkg := range pkgs {
|
||||
options = append(options, pkg.InstOptions()...)
|
||||
}
|
||||
|
||||
cc.uclInst = ucl.New(options...)
|
||||
|
||||
for _, pkg := range pkgs {
|
||||
pkg.ConfigureUCL(cc.uclInst)
|
||||
|
@ -126,26 +132,20 @@ func (c *CommandController) execute(ctx ExecContext, commandInput string) tea.Ms
|
|||
return events.Error(errors.New("command currently running"))
|
||||
}
|
||||
|
||||
/*
|
||||
res, err := c.uclInst.Eval(context.Background(), commandInput)
|
||||
if err != nil {
|
||||
return events.Error(err)
|
||||
}
|
||||
|
||||
if teaMsg, ok := res.(teaMsgWrapper); ok {
|
||||
return teaMsg.msg
|
||||
}
|
||||
*/
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CommandController) ExecuteAndWait(ctx context.Context, commandInput string) (any, error) {
|
||||
return c.uclInst.Eval(ctx, commandInput)
|
||||
}
|
||||
|
||||
func (c *CommandController) cmdLooper() {
|
||||
ctx := context.WithValue(context.Background(), commandCtlKey, c)
|
||||
|
||||
for {
|
||||
select {
|
||||
case cmdChan := <-c.cmdChan:
|
||||
res, err := c.uclInst.Eval(ctx, cmdChan.cmd)
|
||||
res, err := c.ExecuteAndWait(ctx, cmdChan.cmd)
|
||||
if err != nil {
|
||||
c.postMessage(events.Error(err))
|
||||
} else if res != nil {
|
||||
|
|
|
@ -3,5 +3,6 @@ package commandctrl
|
|||
import "ucl.lmika.dev/ucl"
|
||||
|
||||
type CommandPack interface {
|
||||
InstOptions() []ucl.InstOption
|
||||
ConfigureUCL(ucl *ucl.Inst)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type exprValue interface {
|
||||
|
@ -62,6 +63,14 @@ func newExprValueFromAttributeValue(ev types.AttributeValue) (exprValue, error)
|
|||
case *types.AttributeValueMemberS:
|
||||
return stringExprValue(xVal.Value), nil
|
||||
case *types.AttributeValueMemberN:
|
||||
if !strings.Contains(xVal.Value, ".") {
|
||||
iVal, err := strconv.ParseInt(xVal.Value, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return int64ExprValue(iVal), nil
|
||||
}
|
||||
|
||||
xNumVal, _, err := big.ParseFloat(xVal.Value, 10, 63, big.ToNearestEven)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -139,6 +148,32 @@ func (s int64ExprValue) typeName() string {
|
|||
return "N"
|
||||
}
|
||||
|
||||
type bigIntExprValue struct {
|
||||
num *big.Int
|
||||
}
|
||||
|
||||
func (i bigIntExprValue) asGoValue() any {
|
||||
return i.num
|
||||
}
|
||||
|
||||
func (i bigIntExprValue) asAttributeValue() types.AttributeValue {
|
||||
return &types.AttributeValueMemberN{Value: i.num.String()}
|
||||
}
|
||||
|
||||
func (i bigIntExprValue) asInt() int64 {
|
||||
return i.num.Int64()
|
||||
}
|
||||
|
||||
func (i bigIntExprValue) asBigFloat() *big.Float {
|
||||
var f big.Float
|
||||
f.SetInt64(i.num.Int64())
|
||||
return &f
|
||||
}
|
||||
|
||||
func (s bigIntExprValue) typeName() string {
|
||||
return "N"
|
||||
}
|
||||
|
||||
type bigNumExprValue struct {
|
||||
num *big.Float
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue