diff --git a/sqlbuilder/column.go b/sqlbuilder/column.go index 057056d..cba7933 100644 --- a/sqlbuilder/column.go +++ b/sqlbuilder/column.go @@ -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 { diff --git a/sqlbuilder/column_types_test.go b/sqlbuilder/column_types_test.go index e13656a..adfde82 100644 --- a/sqlbuilder/column_types_test.go +++ b/sqlbuilder/column_types_test.go @@ -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) diff --git a/sqlbuilder/table.go b/sqlbuilder/table.go index 567fe4e..7870f08 100644 --- a/sqlbuilder/table.go +++ b/sqlbuilder/table.go @@ -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) { diff --git a/sqlbuilder/table_test.go b/sqlbuilder/table_test.go index 5c46ea0..59209bb 100644 --- a/sqlbuilder/table_test.go +++ b/sqlbuilder/table_test.go @@ -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))