Skip to content

Commit b665e9a

Browse files
committed
Start sketching on documentation and shaping up/restructuring the API where needed
1 parent a3a0dfc commit b665e9a

File tree

6 files changed

+86
-15
lines changed

6 files changed

+86
-15
lines changed

aggregation/strings.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ package aggregation
22

33
import "strings"
44

5+
// StrJoin creates a function that joins a slice of strings into
6+
// a single string using the provided separator.
7+
// It is provided as an example and can be used in aggregations
8+
// on string and enum columns.
59
func StrJoin(sep string) func([]*string) *string {
610
return func(input []*string) *string {
711
s := make([]string, 0, len(input))

doc.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/*
2+
qframe is...
3+
*/
4+
package qframe

expression.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ import (
1010
"strconv"
1111
)
1212

13-
// TODO
14-
// - Auto cast int -> float for operations on float columns where the operand is an int?
15-
// - Tests
16-
// - Review all public QFrame functions so that they contain guards against Err execution.
17-
1813
type functionsByArgCount struct {
1914
singleArgs map[string]interface{}
2015
doubleArgs map[string]interface{}
@@ -123,6 +118,7 @@ func (ctx *ExprCtx) setFunc(typ types.FunctionType, ac argCount, name string, fn
123118
}
124119
}
125120

121+
// TODO-C
126122
func (ctx *ExprCtx) SetFunc(name string, fn interface{}) error {
127123
// Since there's such a flexibility in the function types that can be
128124
// used and there is no static typing to support it this function
@@ -185,7 +181,7 @@ type Expression interface {
185181
Err() error
186182
}
187183

188-
func NewExpr(expr interface{}) Expression {
184+
func newExpr(expr interface{}) Expression {
189185
// Try, in turn, to decode expr into a valid expression type.
190186
if e, ok := expr.(Expression); ok {
191187
return e
@@ -247,6 +243,7 @@ func (e colExpr) execute(qf QFrame, _ *ExprCtx) (QFrame, string) {
247243
return qf, e.srcCol
248244
}
249245

246+
// TODO-C
250247
func (e colExpr) Err() error {
251248
return nil
252249
}
@@ -441,12 +438,12 @@ func newExprExpr(x interface{}) Expression {
441438
return errorExpr{err: errors.New("newExprExpr", "invalid operation: %v", l[0])}
442439
}
443440

444-
lhs := NewExpr(l[1])
441+
lhs := newExpr(l[1])
445442
if lhs.Err() != nil {
446443
return errorExpr{err: errors.Propagate("newExprExpr", lhs.Err())}
447444
}
448445

449-
rhs := NewExpr(l[2])
446+
rhs := newExpr(l[2])
450447
if rhs.Err() != nil {
451448
return errorExpr{err: errors.Propagate("newExprExpr", rhs.Err())}
452449
}
@@ -495,14 +492,17 @@ func (e errorExpr) Err() error {
495492
return e.err
496493
}
497494

495+
// TODO-C
498496
func Val(value interface{}) Expression {
499-
return NewExpr(value)
497+
return newExpr(value)
500498
}
501499

500+
// TODO-C
502501
func Expr1(name, column string) Expression {
503-
return NewExpr([]interface{}{name, column})
502+
return newExpr([]interface{}{name, column})
504503
}
505504

505+
// TODO-C
506506
func Expr2(name, val1, val2 interface{}) Expression {
507-
return NewExpr([]interface{}{name, val1, val2})
507+
return newExpr([]interface{}{name, val1, val2})
508508
}

filter.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,35 @@ import (
99
"strings"
1010
)
1111

12+
// FilterClause is an internal interface representing a filter of some kind.
1213
type FilterClause interface {
1314
fmt.Stringer
1415
filter(qf QFrame) QFrame
1516
Err() error
1617
}
1718

19+
// Filter is the lowest level in a filter clause.
20+
// It specifies the filter operation, which column to operate on and what
21+
// to filter/compare that column against.
1822
type Filter filter.Filter
1923

2024
type comboClause struct {
2125
err error
2226
subClauses []FilterClause
2327
}
2428

29+
// AndClause represents the logical conjunction of multiple clauses.
2530
type AndClause comboClause
2631

32+
// OrClause represents the logical disjunction of multiple clauses.
2733
type OrClause comboClause
2834

35+
// OrClause represents the logical inverse of of a filter clause.
2936
type NotClause struct {
3037
subClause FilterClause
3138
}
3239

33-
// Convenience type to simplify clients when no filtering is to be done.
40+
// NullClause is a convenience type to simplify clients when no filtering is to be done.
3441
type NullClause struct{}
3542

3643
func anyFilterErr(clauses []FilterClause) error {
@@ -42,6 +49,7 @@ func anyFilterErr(clauses []FilterClause) error {
4249
return nil
4350
}
4451

52+
// And returns a new AndClause that represents the conjunction of the passed filter clauses.
4553
func And(clauses ...FilterClause) AndClause {
4654
if len(clauses) == 0 {
4755
return AndClause{err: errors.New("new and clause", "zero subclauses not allowed")}
@@ -59,6 +67,7 @@ func clauseString(clauses []FilterClause) string {
5967
return strings.Join(reps, ", ")
6068
}
6169

70+
// String returns a textual description of the filter.
6271
func (c AndClause) String() string {
6372
if c.Err() != nil {
6473
return c.Err().Error()
@@ -84,10 +93,12 @@ func (c AndClause) filter(qf QFrame) QFrame {
8493
return *filteredQf
8594
}
8695

96+
// Err returns any error that may have occurred during creation of the filter
8797
func (c AndClause) Err() error {
8898
return c.err
8999
}
90100

101+
// Or returns a new OrClause that represents the disjunction of the passed filter clauses.
91102
func Or(clauses ...FilterClause) OrClause {
92103
if len(clauses) == 0 {
93104
return OrClause{err: errors.New("new or clause", "zero subclauses not allowed")}
@@ -96,6 +107,7 @@ func Or(clauses ...FilterClause) OrClause {
96107
return OrClause{subClauses: clauses, err: anyFilterErr(clauses)}
97108
}
98109

110+
// String returns a textual description of the filter.
99111
func (c OrClause) String() string {
100112
if c.Err() != nil {
101113
return c.Err().Error()
@@ -178,10 +190,12 @@ func (c OrClause) filter(qf QFrame) QFrame {
178190
return *filteredQf
179191
}
180192

193+
// Err returns any error that may have occurred during creation of the filter
181194
func (c OrClause) Err() error {
182195
return c.err
183196
}
184197

198+
// String returns a textual description of the filter.
185199
func (c Filter) String() string {
186200
if c.Err() != nil {
187201
return c.Err().Error()
@@ -194,14 +208,17 @@ func (c Filter) filter(qf QFrame) QFrame {
194208
return qf.filter(filter.Filter(c))
195209
}
196210

211+
// Err returns any error that may have occurred during creation of the filter
197212
func (c Filter) Err() error {
198213
return nil
199214
}
200215

216+
// Not creates a new NotClause that represents the inverse of the passed filter clause.
201217
func Not(c FilterClause) NotClause {
202218
return NotClause{subClause: c}
203219
}
204220

221+
// String returns a textual description of the filter clause.
205222
func (c NotClause) String() string {
206223
if c.Err() != nil {
207224
return c.Err().Error()
@@ -243,14 +260,17 @@ func (c NotClause) filter(qf QFrame) QFrame {
243260
return qf.withIndex(newIx)
244261
}
245262

263+
// Err returns any error that may have occurred during creation of the filter
246264
func (c NotClause) Err() error {
247265
return c.subClause.Err()
248266
}
249267

268+
// Null returns a new NullClause
250269
func Null() NullClause {
251270
return NullClause{}
252271
}
253272

273+
// Err for NullClause always returns an empty string.
254274
func (c NullClause) String() string {
255275
return ""
256276
}
@@ -259,6 +279,7 @@ func (c NullClause) filter(qf QFrame) QFrame {
259279
return qf
260280
}
261281

282+
// Err for NullClause always returns nil.
262283
func (c NullClause) Err() error {
263284
return nil
264285
}

qframe.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,9 @@ func createColumn(name string, data interface{}, config *Config) (column.Column,
165165
return localS, nil
166166
}
167167

168-
func New(data map[string]interface{}, fns ...ConfigFunc) QFrame {
168+
// New creates a new QFrame with column content from data.
169+
// TODO-C Examples
170+
func New(data map[string]types.DataSlice, fns ...ConfigFunc) QFrame {
169171
config := newConfig(fns)
170172
if len(config.columnOrder) == 0 {
171173
config.columnOrder = make([]string, 0, len(data))
@@ -219,11 +221,14 @@ func New(data map[string]interface{}, fns ...ConfigFunc) QFrame {
219221
return QFrame{columns: s, columnsByName: sByName, index: index.NewAscending(uint32(currentLen)), Err: nil}
220222
}
221223

224+
// Contains reports if a columns with colName is present in the frame.
222225
func (qf QFrame) Contains(colName string) bool {
223226
_, ok := qf.columnsByName[colName]
224227
return ok
225228
}
226229

230+
// Filter filters the frame according to the filters in clause.
231+
// TODO-C Examples
227232
func (qf QFrame) Filter(clause FilterClause) QFrame {
228233
if qf.Err != nil {
229234
return qf
@@ -543,8 +548,9 @@ func (qf QFrame) GroupBy(configFns ...GroupByConfigFn) Grouper {
543548
return g
544549
}
545550

551+
// TODO-C
546552
type Aggregation struct {
547-
Fn interface{}
553+
Fn types.SliceFuncOrBuiltInId
548554
Column string
549555
}
550556

@@ -601,7 +607,9 @@ func fixLengthString(s string, pad string, desiredLen int) string {
601607
return s
602608
}
603609

604-
// Simple string representation of the table
610+
// String returns a simple string representation of the table.
611+
// Output is currently capped to 50 rows. Use Slice followed by String if you want
612+
// to print rows that are not among the first 50.
605613
func (qf QFrame) String() string {
606614
// There are a lot of potential improvements to this function at the moment:
607615
// - Limit output, both columns and rows
@@ -644,6 +652,8 @@ func (qf QFrame) String() string {
644652
return strings.Join(result, "\n")
645653
}
646654

655+
// Slice returns a new QFrame consisting of rows [start, end[.
656+
// Note that the underlying storage is kept. Slicing a frame will not release memory used to store the columns.
647657
func (qf QFrame) Slice(start, end int) QFrame {
648658
if qf.Err != nil {
649659
return qf
@@ -688,6 +698,7 @@ func (qf QFrame) setColumn(name string, c column.Column) QFrame {
688698
return newF
689699
}
690700

701+
// TODO-C
691702
func (qf QFrame) Copy(dstCol, srcCol string) QFrame {
692703
if qf.Err != nil {
693704
return qf
@@ -827,6 +838,7 @@ func (qf QFrame) apply2(fn interface{}, dstCol, srcCol1, srcCol2 string) QFrame
827838
return qf.setColumn(dstCol, resultColumn)
828839
}
829840

841+
// TODO-C
830842
type Instruction struct {
831843
Fn interface{}
832844
DstCol string
@@ -836,6 +848,8 @@ type Instruction struct {
836848
SrcCol2 string
837849
}
838850

851+
// TODO: Should this function be made private and only rely on Eval to do this. As it is now there
852+
// is redundancy in the interface.
839853
func (qf QFrame) Apply(instructions ...Instruction) QFrame {
840854
result := qf
841855
for _, a := range instructions {
@@ -870,6 +884,7 @@ func (qf QFrame) Eval(destCol string, expr Expression, ctx *ExprCtx) QFrame {
870884
return qf
871885
}
872886

887+
// TODO: Might want to change this to take use functional arguments instead...
873888
if ctx == nil {
874889
ctx = NewDefaultExprCtx()
875890
}
@@ -1222,3 +1237,6 @@ func (qf QFrame) ByteSize() int {
12221237
// aggregation for example.
12231238
// - Add different "cover types" for interface{} here and there to improve documentation?
12241239
// - Change column package layout?
1240+
// - Remove column based json Read/Write until someone needs it?
1241+
// - Make config package with subpackages named after what they configure?
1242+
// - Move Grouper to own file

types/aliases.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package types
2+
3+
/*
4+
DataSlice can be a slice of any of the supported data types.
5+
6+
The following types are currently supported:
7+
[]bool
8+
[]float64
9+
[]int
10+
[]string
11+
[]*string
12+
*/
13+
type DataSlice = interface{}
14+
15+
/*
16+
SliceFuncOrBuiltInId can be a function taking a slice of type T and returning a value of type T.
17+
18+
For example:
19+
func(x []float64) float64
20+
func(x []int) int
21+
func(x []*string) *string
22+
func(x []bool) bool
23+
*/
24+
type SliceFuncOrBuiltInId = interface{}

0 commit comments

Comments
 (0)