## Migrating Between Versions
* [To v8](#v8)
* [To v7](#v7)
### `v7 to v8`
A major change the the API was made in `v8` to seperate concerns between the different SQL statement types.
**Why the change?**
1. There were feature requests that could not be cleanly implemented with everything in a single dataset.
2. Too much functionality was encapsulated in a single datastructure.
* It was unclear what methods could be used for each SQL statement type.
* Changing a feature for one statement type had the possiblity of breaking another statement type.
* Test coverage was decent but was almost solely concerned about SELECT statements, breaking them up allowed for focused testing on each statement type.
* Most the SQL generation methods (`ToInsertSQL`, `ToUpdateSQL` etc.) took arguments which lead to an ugly API that was not uniform for each statement type, and proved to be inflexible.
**What Changed**
There are now five dataset types, `SelectDataset`, `InsertDataset`, `UpdateDataset`, `DeleteDataset` and `TruncateDataset`
Each dataset type has its own entry point.
* `goqu.From`, `Database#From`, `DialectWrapper#From` - Create SELECT
* `goqu.Insert`, `Database#Insert`, `DialectWrapper#Insert` - Create INSERT
* `goqu.Update`, `Database#db.Update`, `DialectWrapper#Update` - Create UPDATE
* `goqu.Delete`, `Database#Delete`, `DialectWrapper#Delete` - Create DELETE
* `goqu.Truncate`, `Database#Truncate`, `DialectWrapper#Truncate` - Create TRUNCATE
`ToInsertSQL`, `ToUpdateSQL`, `ToDeleteSQL`, and `ToTruncateSQL` (and variations of them) methods have been removed from the `SelectDataset`. Instead use the `ToSQL` methods on each dataset type.
Each dataset type will have an `Executor` and `ToSQL` method so a common interface can be created for each type.
**How to insert.**
In older versions of `goqu` there was `ToInsertSQL` method on the `Dataset` in the latest version there is a new entry point to create INSERTS.
```go
// old way
goqu.From("test").ToInsertSQL(...rows)
// new way
goqu.Insert("test").Rows(...rows).ToSQL()
goqu.From("test").Insert().Rows(...rows).ToSQL()
```
In older versions of `goqu` there was `Insert` method on the `Dataset` to execute an insert in the latest version there is a new `Exectutor` method.
```go
// old way
db.From("test").Insert(...rows).Exec()
// new way
db.Insert("test").Rows(...rows).Executor().Exec()
// or
db.From("test").Insert().Rows(...rows).Executor().Exec()
```
The new `InsertDataset` also has an `OnConflict` method that replaces the `ToInsertConflictSQL` and `ToInsertIgnoreSQL`
```go
// old way
goqu.From("test").ToInsertIgnoreSQL(...rows)
// new way
goqu.Insert("test").Rows(...rows).OnConflict(goqu.DoNothing()).ToSQL()
// OR
goqu.From("test").Insert().Rows(...rows).OnConflict(goqu.DoNothing()).ToSQL()
```
```go
// old way
goqu.From("items").ToInsertConflictSQL(
goqu.DoUpdate("key", goqu.Record{"updated": goqu.L("NOW()")}),
goqu.Record{"name": "Test1", "address": "111 Test Addr"},
goqu.Record{"name": "Test2", "address": "112 Test Addr"},
)
fmt.Println(sql, args)
// new way
goqu.Insert("test").
Rows(
goqu.Record{"name": "Test1", "address": "111 Test Addr"},
goqu.Record{"name": "Test2", "address": "112 Test Addr"},
).
OnConflict(goqu.DoUpdate("key", goqu.Record{"updated": goqu.L("NOW()")})).
ToSQL()
// OR
goqu.From("test").
Insert().
Rows(
goqu.Record{"name": "Test1", "address": "111 Test Addr"},
goqu.Record{"name": "Test2", "address": "112 Test Addr"},
).
OnConflict(goqu.DoUpdate("key", goqu.Record{"updated": goqu.L("NOW()")})).
ToSQL()
```
**How to update.**
In older versions of `goqu` there was `ToUpdateSQL` method on the `Dataset` in the latest version there is a new entry point to create UPDATEs.
```go
// old way
goqu.From("items").ToUpdateSQL(
goqu.Record{"name": "Test", "address": "111 Test Addr"},
)
// new way
goqu.Update("items").
Set(goqu.Record{"name": "Test", "address": "111 Test Addr"}).
ToSQL()
// OR
goqu.From("items").
Update()
Set(goqu.Record{"name": "Test", "address": "111 Test Addr"}).
ToSQL()
```
In older versions of `goqu` there was `Insert` method on the `Dataset` to execute an insert in the latest version there is a new `Exectutor` method.
```go
// old way
db.From("items").Update(
goqu.Record{"name": "Test", "address": "111 Test Addr"},
).Exec()
// new way
db.Update("items").
Set(goqu.Record{"name": "Test", "address": "111 Test Addr"}).
Executor().Exec()
// OR
db.From("items").
Update().
Set(goqu.Record{"name": "Test", "address": "111 Test Addr"}).
Executor().Exec()
```
**How to delete.**
In older versions of `goqu` there was `ToDeleteSQL` method on the `Dataset` in the latest version there is a new entry point to create DELETEs.
```go
// old way
goqu.From("items").
Where(goqu.Ex{"id": goqu.Op{"gt": 10}}).
ToDeleteSQL()
// new way
goqu.Delete("items").
Where(goqu.Ex{"id": goqu.Op{"gt": 10}}).
ToSQL()
// OR
goqu.From("items").
Delete()
Where(goqu.Ex{"id": goqu.Op{"gt": 10}}).
ToSQL()
```
In older versions of `goqu` there was `Delete` method on the `Dataset` to execute an insert in the latest version there is a new `Exectutor` method.
```go
// old way
db.From("items").
Where(goqu.Ex{"id": goqu.Op{"gt": 10}}).
Delete().Exec()
// new way
db.Delete("items").
Where(goqu.Ex{"id": goqu.Op{"gt": 10}}).
Executor().Exec()
// OR
db.From("items").
Delete()
Where(goqu.Ex{"id": goqu.Op{"gt": 10}}).
Executor().Exec()
```
**How to truncate.**
In older versions of `goqu` there was `ToTruncateSQL` method on the `Dataset` in the latest version there is a new entry point to create TRUNCATEs.
```go
// old way
goqu.From("items").ToTruncateSQL()
// new way
goqu.Truncate("items").ToSQL()
```
### ` `ToSQL`
* `ToInsertSql` -> `ToInsertSQL`
* `ToUpdateSql` -> `ToUpdateSQL`
* `ToDeleteSql` -> `ToDeleteSQL`
* `ToTruncateSql` -> `ToTruncateSQL`
* Abstracted out `dialect_options` from the adapter to make the dialect self contained.
* This also removed the `dataset<->adapter` co dependency making the dialect self contained.
* Added new dialect options to specify the order than SQL statements are built.
* Refactored the `goqu.I` method.
* Added new `goqu.S`, `goqu.T` and `goqu.C` methods to clarify why type of identifier you are using.
* `goqu.I` should only be used when you have a qualified identifier (e.g. `goqu.I("my_schema.my_table.my_col")
* Added new `goqu.Dialect` method to make using `goqu` as an SQL builder easier.