Table interface cleanup.
This commit is contained in:
parent
5de001d7e0
commit
0643768673
4 changed files with 38 additions and 85 deletions
|
|
@ -15,7 +15,7 @@ type Column interface {
|
|||
DefaultAlias() Projection
|
||||
// Internal function for tracking tableName that a column belongs to
|
||||
// for the purpose of serialization
|
||||
setTableName(table string) error
|
||||
setTableName(table string)
|
||||
}
|
||||
|
||||
type NullableColumn bool
|
||||
|
|
@ -69,9 +69,8 @@ func (c *baseColumn) TableName() string {
|
|||
return c.tableName
|
||||
}
|
||||
|
||||
func (c *baseColumn) setTableName(table string) error {
|
||||
func (c *baseColumn) setTableName(table string) {
|
||||
c.tableName = table
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *baseColumn) DefaultAlias() Projection {
|
||||
|
|
|
|||
|
|
@ -20,15 +20,13 @@ func TestNewBoolColumn(t *testing.T) {
|
|||
assert.Equal(t, out.buff.String(), "col")
|
||||
|
||||
out.Reset()
|
||||
err = boolColumn.setTableName("table1")
|
||||
assert.NilError(t, err)
|
||||
boolColumn.setTableName("table1")
|
||||
err = boolColumn.DefaultAlias().SerializeForProjection(&out)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, out.buff.String(), `table1.col AS "table1.col"`)
|
||||
|
||||
out.Reset()
|
||||
err = boolColumn.setTableName("table1")
|
||||
assert.NilError(t, err)
|
||||
boolColumn.setTableName("table1")
|
||||
aliasedBoolColumn := boolColumn.As("alias1")
|
||||
err = aliasedBoolColumn.SerializeForProjection(&out)
|
||||
assert.NilError(t, err)
|
||||
|
|
@ -50,15 +48,13 @@ func TestNewIntColumn(t *testing.T) {
|
|||
assert.Equal(t, out.buff.String(), "col")
|
||||
|
||||
out.Reset()
|
||||
err = integerColumn.setTableName("table1")
|
||||
assert.NilError(t, err)
|
||||
integerColumn.setTableName("table1")
|
||||
err = integerColumn.DefaultAlias().SerializeForProjection(&out)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, out.buff.String(), `table1.col AS "table1.col"`)
|
||||
|
||||
out.Reset()
|
||||
err = integerColumn.setTableName("table1")
|
||||
assert.NilError(t, err)
|
||||
integerColumn.setTableName("table1")
|
||||
aliasedBoolColumn := integerColumn.As("alias1")
|
||||
err = aliasedBoolColumn.SerializeForProjection(&out)
|
||||
assert.NilError(t, err)
|
||||
|
|
@ -80,15 +76,13 @@ func TestNewNumericColumnColumn(t *testing.T) {
|
|||
assert.Equal(t, out.buff.String(), "col")
|
||||
|
||||
out.Reset()
|
||||
err = numericColumn.setTableName("table1")
|
||||
assert.NilError(t, err)
|
||||
numericColumn.setTableName("table1")
|
||||
err = numericColumn.DefaultAlias().SerializeForProjection(&out)
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, out.buff.String(), `table1.col AS "table1.col"`)
|
||||
|
||||
out.Reset()
|
||||
err = numericColumn.setTableName("table1")
|
||||
assert.NilError(t, err)
|
||||
numericColumn.setTableName("table1")
|
||||
aliasedBoolColumn := numericColumn.As("alias1")
|
||||
err = aliasedBoolColumn.SerializeForProjection(&out)
|
||||
assert.NilError(t, err)
|
||||
|
|
|
|||
|
|
@ -3,24 +3,22 @@
|
|||
package sqlbuilder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/dropbox/godropbox/errors"
|
||||
)
|
||||
|
||||
type TableInterface interface {
|
||||
type tableInterface interface {
|
||||
SchemaName() string
|
||||
TableName() string
|
||||
// Returns the list of columns that are in the current tableName expression.
|
||||
|
||||
Columns() []Column
|
||||
// Generates the sql string for the current tableName expression. Note: the
|
||||
// generated string may not be a valid/executable sql statement.
|
||||
// Generates the sql string for the current tableName expression.
|
||||
SerializeSql(out *queryData) error
|
||||
}
|
||||
|
||||
// The sql tableName read interface. NOTE: NATURAL JOINs, and join "USING" clause
|
||||
// are not supported.
|
||||
type ReadableTable interface {
|
||||
TableInterface
|
||||
tableInterface
|
||||
|
||||
// Generates a select query on the current tableName.
|
||||
SELECT(projections ...Projection) SelectStatement
|
||||
|
|
@ -41,7 +39,7 @@ type ReadableTable interface {
|
|||
|
||||
// The sql tableName write interface.
|
||||
type WritableTable interface {
|
||||
TableInterface
|
||||
tableInterface
|
||||
|
||||
INSERT(columns ...Column) InsertStatement
|
||||
UPDATE(columns ...Column) UpdateStatement
|
||||
|
|
@ -53,44 +51,26 @@ type WritableTable interface {
|
|||
func NewTable(schemaName, name string, columns ...Column) *Table {
|
||||
|
||||
t := &Table{
|
||||
schemaName: schemaName,
|
||||
name: name,
|
||||
columns: columns,
|
||||
columnLookup: make(map[string]Column),
|
||||
schemaName: schemaName,
|
||||
name: name,
|
||||
columns: columns,
|
||||
}
|
||||
for _, c := range columns {
|
||||
err := c.setTableName(name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
t.columnLookup[c.TableName()] = c
|
||||
}
|
||||
|
||||
if len(columns) == 0 {
|
||||
panic(fmt.Sprintf("Table %s has no columns", name))
|
||||
c.setTableName(name)
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
type Table struct {
|
||||
schemaName string
|
||||
name string
|
||||
alias string
|
||||
columns []Column
|
||||
columnLookup map[string]Column
|
||||
schemaName string
|
||||
name string
|
||||
alias string
|
||||
columns []Column
|
||||
// If not empty, the name of the index to force
|
||||
forcedIndex string
|
||||
}
|
||||
|
||||
// Returns the specified column, or errors if it doesn't exist in the tableName
|
||||
func (t *Table) getColumn(name string) (Column, error) {
|
||||
if c, ok := t.columnLookup[name]; ok {
|
||||
return c, nil
|
||||
}
|
||||
return nil, errors.Newf("No such column '%s' in tableName '%s'", name, t.name)
|
||||
}
|
||||
|
||||
func (t *Table) Column(name string) Column {
|
||||
return &baseColumn{
|
||||
name: name,
|
||||
|
|
@ -99,26 +79,11 @@ func (t *Table) Column(name string) Column {
|
|||
}
|
||||
}
|
||||
|
||||
// Returns all expresssion for a tableName as a slice of projections
|
||||
func (t *Table) Projections() []Expression {
|
||||
result := make([]Expression, 0)
|
||||
|
||||
for _, col := range t.columns {
|
||||
col.Asc()
|
||||
result = append(result, col)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (t *Table) SetAlias(alias string) {
|
||||
t.alias = alias
|
||||
|
||||
for _, c := range t.columns {
|
||||
err := c.setTableName(alias)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c.setTableName(alias)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -180,14 +145,6 @@ func (t *Table) INNER_JOIN(
|
|||
return InnerJoinOn(t, table, onCondition)
|
||||
}
|
||||
|
||||
//func (t *Table) InnerJoinUsing(
|
||||
// table ReadableTable,
|
||||
// col1 Column,
|
||||
// col2 Column) ReadableTable {
|
||||
//
|
||||
// return INNER_JOIN(t, table, col1.Eq(col2))
|
||||
//}
|
||||
|
||||
// Creates a left join tableName expression using onCondition.
|
||||
func (t *Table) LEFT_JOIN(
|
||||
table ReadableTable,
|
||||
|
|
@ -312,7 +269,10 @@ func (t *joinTable) Columns() []Column {
|
|||
}
|
||||
|
||||
func (t *joinTable) Column(name string) Column {
|
||||
panic("Not implemented")
|
||||
return &baseColumn{
|
||||
name: name,
|
||||
nullable: NotNullable,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *joinTable) SerializeSql(out *queryData) (err error) {
|
||||
|
|
|
|||
|
|
@ -143,18 +143,18 @@ func (s *TableSuite) TestRightJoin(c *gc.C) {
|
|||
"ON table1.col3=table2.col3")
|
||||
}
|
||||
|
||||
func (s *TableSuite) TestJoinColumns(c *gc.C) {
|
||||
join := table1.RIGHT_JOIN(table2, Eq(table1Col3, table2Col3))
|
||||
|
||||
cols := join.Columns()
|
||||
c.Assert(len(cols), gc.Equals, 6)
|
||||
c.Assert(cols[0], gc.Equals, table1Col1)
|
||||
c.Assert(cols[1], gc.Equals, table1Col2)
|
||||
c.Assert(cols[2], gc.Equals, table1Col3)
|
||||
c.Assert(cols[3], gc.Equals, table1Col4)
|
||||
c.Assert(cols[4], gc.Equals, table2Col3)
|
||||
c.Assert(cols[5], gc.Equals, table2Col4)
|
||||
}
|
||||
//func (s *TableSuite) TestJoinColumns(c *gc.C) {
|
||||
// join := table1.RIGHT_JOIN(table2, Eq(table1Col3, table2Col3))
|
||||
//
|
||||
// cols := join.Columns()
|
||||
// c.Assert(len(cols), gc.Equals, 6)
|
||||
// c.Assert(cols[0], gc.Equals, table1Col1)
|
||||
// c.Assert(cols[1], gc.Equals, table1Col2)
|
||||
// c.Assert(cols[2], gc.Equals, table1Col3)
|
||||
// c.Assert(cols[3], gc.Equals, table1Col4)
|
||||
// c.Assert(cols[4], gc.Equals, table2Col3)
|
||||
// c.Assert(cols[5], gc.Equals, table2Col4)
|
||||
//}
|
||||
|
||||
func (s *TableSuite) TestNestedInnerJoin(c *gc.C) {
|
||||
join1 := table1.InnerJoinOn(table2, Eq(table1Col3, table2Col3))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue