good morning!!!!

Skip to content
Snippets Groups Projects
Commit e6590da2 authored by José Carlos Nieto's avatar José Carlos Nieto
Browse files

Adding Result.

parent 8fbd43eb
No related branches found
No related tags found
No related merge requests found
...@@ -27,62 +27,24 @@ import ( ...@@ -27,62 +27,24 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/gosexy/db" "github.com/gosexy/db"
"github.com/gosexy/db/util"
"github.com/gosexy/db/util/sqlutil" "github.com/gosexy/db/util/sqlutil"
"github.com/gosexy/to" "github.com/gosexy/to"
"strings" "strings"
"time" "time"
) )
/* // Represents a PostgreSQL table.
Fetches a result delimited by terms into a pointer to map or struct given by type Table struct {
dst. source *Source
*/ sqlutil.T
func (self *Table) Fetch(dst interface{}, terms ...interface{}) error {
found := self.Find(terms...)
return util.Fetch(dst, found)
}
/*
Returns true if the collection exists.
*/
func (self *Table) Exists() bool {
result, err := self.source.doQuery(
fmt.Sprintf(`
SELECT table_name
FROM information_schema.tables
WHERE table_catalog = '%s' AND table_name = '%s'
`,
self.source.Name(),
self.Name(),
),
)
if err != nil {
return false
}
if result.Next() == true {
result.Close()
return true
}
return false
} }
/* func (self *Table) Query(terms ...interface{}) (db.Result, error) {
Fetches results delimited by terms into an slice of maps or structs given by
the pointer dst.
*/
func (self *Table) FetchAll(dst interface{}, terms ...interface{}) error {
var err error var err error
queryChunks := sqlutil.NewQueryChunks() queryChunks := sqlutil.NewQueryChunks()
err = util.ValidateDestination(dst)
if err != nil {
return err
}
// Analyzing given terms. // Analyzing given terms.
for _, term := range terms { for _, term := range terms {
...@@ -91,7 +53,7 @@ func (self *Table) FetchAll(dst interface{}, terms ...interface{}) error { ...@@ -91,7 +53,7 @@ func (self *Table) FetchAll(dst interface{}, terms ...interface{}) error {
if queryChunks.Limit == "" { if queryChunks.Limit == "" {
queryChunks.Limit = fmt.Sprintf("LIMIT %d", v) queryChunks.Limit = fmt.Sprintf("LIMIT %d", v)
} else { } else {
return errors.New("A query can accept only one db.Limit() parameter.") return nil, errors.New("A query can accept only one db.Limit() parameter.")
} }
case db.Sort: case db.Sort:
if queryChunks.Sort == "" { if queryChunks.Sort == "" {
...@@ -110,13 +72,13 @@ func (self *Table) FetchAll(dst interface{}, terms ...interface{}) error { ...@@ -110,13 +72,13 @@ func (self *Table) FetchAll(dst interface{}, terms ...interface{}) error {
} }
queryChunks.Sort = fmt.Sprintf("ORDER BY %s", strings.Join(sortChunks, ", ")) queryChunks.Sort = fmt.Sprintf("ORDER BY %s", strings.Join(sortChunks, ", "))
} else { } else {
return errors.New("A query can accept only one db.Sort{} parameter.") return nil, errors.New("A query can accept only one db.Sort{} parameter.")
} }
case db.Offset: case db.Offset:
if queryChunks.Offset == "" { if queryChunks.Offset == "" {
queryChunks.Offset = fmt.Sprintf("OFFSET %d", v) queryChunks.Offset = fmt.Sprintf("OFFSET %d", v)
} else { } else {
return errors.New("A query can accept only one db.Offset() parameter.") return nil, errors.New("A query can accept only one db.Offset() parameter.")
} }
case db.Fields: case db.Fields:
queryChunks.Fields = append(queryChunks.Fields, v...) queryChunks.Fields = append(queryChunks.Fields, v...)
...@@ -124,7 +86,7 @@ func (self *Table) FetchAll(dst interface{}, terms ...interface{}) error { ...@@ -124,7 +86,7 @@ func (self *Table) FetchAll(dst interface{}, terms ...interface{}) error {
for name, terms := range v { for name, terms := range v {
col, err := self.RelationCollection(name, terms) col, err := self.RelationCollection(name, terms)
if err != nil { if err != nil {
return err return nil, err
} }
queryChunks.Relations = append(queryChunks.Relations, db.Relation{All: false, Name: name, Collection: col, On: terms}) queryChunks.Relations = append(queryChunks.Relations, db.Relation{All: false, Name: name, Collection: col, On: terms})
} }
...@@ -132,7 +94,7 @@ func (self *Table) FetchAll(dst interface{}, terms ...interface{}) error { ...@@ -132,7 +94,7 @@ func (self *Table) FetchAll(dst interface{}, terms ...interface{}) error {
for name, terms := range v { for name, terms := range v {
col, err := self.RelationCollection(name, terms) col, err := self.RelationCollection(name, terms)
if err != nil { if err != nil {
return err return nil, err
} }
queryChunks.Relations = append(queryChunks.Relations, db.Relation{All: true, Name: name, Collection: col, On: terms}) queryChunks.Relations = append(queryChunks.Relations, db.Relation{All: true, Name: name, Collection: col, On: terms})
} }
...@@ -161,28 +123,42 @@ func (self *Table) FetchAll(dst interface{}, terms ...interface{}) error { ...@@ -161,28 +123,42 @@ func (self *Table) FetchAll(dst interface{}, terms ...interface{}) error {
) )
if err != nil { if err != nil {
return err return nil, err
} }
// Fetching rows. result := &Result{
err = self.FetchRows(dst, rows) sqlutil.Result{
Rows: rows,
if err != nil { Table: &self.T,
return err Relations: queryChunks.Relations,
},
} }
if err != nil { return result, nil
return err
} }
// Fetching relations /*
err = self.FetchRelations(dst, queryChunks.Relations, toInternalInterface) Returns true if the collection exists.
*/
func (self *Table) Exists() bool {
result, err := self.source.doQuery(
fmt.Sprintf(`
SELECT table_name
FROM information_schema.tables
WHERE table_catalog = '%s' AND table_name = '%s'
`,
self.source.Name(),
self.Name(),
),
)
if err != nil { if err != nil {
return err return false
} }
if result.Next() == true {
return nil result.Close()
return true
}
return false
} }
/* /*
...@@ -334,48 +310,49 @@ func (self *Table) Update(terms ...interface{}) error { ...@@ -334,48 +310,49 @@ func (self *Table) Update(terms ...interface{}) error {
/* /*
Returns a slice of rows that match certain conditions. Returns a slice of rows that match certain conditions.
*/ */
func (self *Table) FindAll(terms ...interface{}) []db.Item { func (self *Table) FindAll(terms ...interface{}) ([]db.Item, error) {
results := []db.Item{} items := []db.Item{}
err := self.FetchAll(&results, terms...) res, err := self.Query(terms...)
if err != nil { if err == nil {
panic(err) err = res.All(&items)
} }
return results return items, err
} }
/* /*
Returns the number of rows in the current table that match certain conditions. Returns the number of rows in the current table that match certain conditions.
*/ */
func (self *Table) Count(terms ...interface{}) (int, error) { func (self *Table) Count(terms ...interface{}) (int, error) {
terms = append(terms, db.Fields{"COUNT(1) AS _total"}) terms = append(terms, db.Fields{"COUNT(1) AS _total"})
result := self.FindAll(terms...) result, err := self.FindAll(terms...)
if len(result) > 0 { if err == nil {
return to.Int(result[0]["_total"]), nil return to.Int(result[0]["_total"]), nil
} }
return 0, nil return 0, err
} }
/* /*
Returns the first row in the table that matches certain conditions. Returns the first row in the table that matches certain conditions.
*/ */
func (self *Table) Find(terms ...interface{}) db.Item { func (self *Table) Find(terms ...interface{}) (db.Item, error) {
var item db.Item
var err error
terms = append(terms, db.Limit(1)) terms = append(terms, db.Limit(1))
result := self.FindAll(terms...) res, err := self.Query(terms...)
if len(result) > 0 { if err == nil {
return result[0] err = res.One(&item)
} }
return nil return item, err
} }
/* /*
......
...@@ -28,7 +28,6 @@ import ( ...@@ -28,7 +28,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/gosexy/db" "github.com/gosexy/db"
"github.com/gosexy/db/util/sqlutil"
_ "github.com/xiam/gopostgresql" _ "github.com/xiam/gopostgresql"
"reflect" "reflect"
"regexp" "regexp"
...@@ -289,14 +288,6 @@ func (self *Source) ExistentCollection(name string) db.Collection { ...@@ -289,14 +288,6 @@ func (self *Source) ExistentCollection(name string) db.Collection {
return col return col
} }
// Represents a PostgreSQL table.
type Table struct {
source *Source
//name string
//types map[string]reflect.Kind
sqlutil.T
}
/* /*
Returns a table struct by name. Returns a table struct by name.
*/ */
......
...@@ -198,6 +198,7 @@ func TestAppend(t *testing.T) { ...@@ -198,6 +198,7 @@ func TestAppend(t *testing.T) {
func TestFind(t *testing.T) { func TestFind(t *testing.T) {
var err error var err error
var res db.Result
sess, err := db.Open(wrapperName, settings) sess, err := db.Open(wrapperName, settings)
...@@ -210,16 +211,22 @@ func TestFind(t *testing.T) { ...@@ -210,16 +211,22 @@ func TestFind(t *testing.T) {
people, _ := sess.Collection("people") people, _ := sess.Collection("people")
// Testing Find() // Testing Find()
result := people.Find(db.Cond{"name": "José"}) item, _ := people.Find(db.Cond{"name": "José"})
if result["name"] != "José" { if item["name"] != "José" {
t.Fatalf("Could not find a recently appended item.") t.Fatalf("Could not find a recently appended item.")
} }
// Fetch into map slice. // Fetch into map slice.
dst := []map[string]string{} dst := []map[string]string{}
err = people.FetchAll(&dst, db.Cond{"name": "José"}) res, err = people.Query(db.Cond{"name": "José"})
if err != nil {
t.Fatalf(err.Error())
}
err = res.All(&dst)
if err != nil { if err != nil {
t.Fatalf(err.Error()) t.Fatalf(err.Error())
...@@ -236,7 +243,13 @@ func TestFind(t *testing.T) { ...@@ -236,7 +243,13 @@ func TestFind(t *testing.T) {
// Fetch into struct slice. // Fetch into struct slice.
dst2 := []struct{ Name string }{} dst2 := []struct{ Name string }{}
err = people.FetchAll(&dst2, db.Cond{"name": "José"}) res, err = people.Query(db.Cond{"name": "José"})
if err != nil {
t.Fatalf(err.Error())
}
err = res.All(&dst2)
if err != nil { if err != nil {
t.Fatalf(err.Error()) t.Fatalf(err.Error())
...@@ -253,20 +266,28 @@ func TestFind(t *testing.T) { ...@@ -253,20 +266,28 @@ func TestFind(t *testing.T) {
// Fetch into map. // Fetch into map.
dst3 := map[string]interface{}{} dst3 := map[string]interface{}{}
err = people.Fetch(&dst3, db.Cond{"name": "José"}) res, err = people.Query(db.Cond{"name": "José"})
if err != nil { if err != nil {
t.Fatalf(err.Error()) t.Fatalf(err.Error())
} }
if dst3["name"] != "José" { err = res.One(&dst3)
t.Fatalf("Could not find a recently appended item.")
if err != nil {
t.Fatalf(err.Error())
} }
// Fetch into struct. // Fetch into struct.
dst4 := struct{ Name string }{} dst4 := struct{ Name string }{}
err = people.Fetch(&dst4, db.Cond{"name": "José"}) res, err = people.Query(db.Cond{"name": "José"})
if err != nil {
t.Fatalf(err.Error())
}
err = res.One(&dst4)
if err != nil { if err != nil {
t.Fatalf(err.Error()) t.Fatalf(err.Error())
...@@ -276,6 +297,32 @@ func TestFind(t *testing.T) { ...@@ -276,6 +297,32 @@ func TestFind(t *testing.T) {
t.Fatalf("Could not find a recently appended item.") t.Fatalf("Could not find a recently appended item.")
} }
// Makes a query and stores the result
res, err = people.Query(nil)
if err != nil {
t.Fatalf(err.Error())
}
dst5 := struct{ Name string }{}
found := false
for true {
err = res.Next(&dst5)
if err != nil {
break
}
if dst5.Name == "José" {
found = true
}
}
res.Close()
if found == false {
t.Fatalf("José was not found.")
}
} }
// Tries to delete rows. // Tries to delete rows.
...@@ -292,7 +339,7 @@ func TestDelete(t *testing.T) { ...@@ -292,7 +339,7 @@ func TestDelete(t *testing.T) {
people.Remove(db.Cond{"name": "Juan"}) people.Remove(db.Cond{"name": "Juan"})
result := people.Find(db.Cond{"name": "Juan"}) result, _ := people.Find(db.Cond{"name": "Juan"})
if len(result) > 0 { if len(result) > 0 {
t.Fatalf("Could not remove a recently appended item.") t.Fatalf("Could not remove a recently appended item.")
...@@ -314,7 +361,7 @@ func TestUpdate(t *testing.T) { ...@@ -314,7 +361,7 @@ func TestUpdate(t *testing.T) {
people.Update(db.Cond{"name": "José"}, db.Set{"name": "Joseph"}) people.Update(db.Cond{"name": "José"}, db.Set{"name": "Joseph"})
result := people.Find(db.Cond{"name": "Joseph"}) result, _ := people.Find(db.Cond{"name": "Joseph"})
if len(result) == 0 { if len(result) == 0 {
t.Fatalf("Could not update a recently appended item.") t.Fatalf("Could not update a recently appended item.")
...@@ -346,7 +393,7 @@ func TestPopulate(t *testing.T) { ...@@ -346,7 +393,7 @@ func TestPopulate(t *testing.T) {
}) })
} }
results := people.FindAll( results, _ := people.FindAll(
db.Fields{"id", "name"}, db.Fields{"id", "name"},
db.Sort{"name": "ASC", "id": -1}, db.Sort{"name": "ASC", "id": -1},
) )
...@@ -370,7 +417,7 @@ func TestPopulate(t *testing.T) { ...@@ -370,7 +417,7 @@ func TestPopulate(t *testing.T) {
// Has visited // Has visited
for j := 0; j < 3; j++ { for j := 0; j < 3; j++ {
place := places.Find(db.Cond{ place, _ := places.Find(db.Cond{
"code_id": int(rand.Float32() * float32(len(results))), "code_id": int(rand.Float32() * float32(len(results))),
}) })
visits.Append(db.Item{ visits.Append(db.Item{
...@@ -394,7 +441,7 @@ func TestRelation(t *testing.T) { ...@@ -394,7 +441,7 @@ func TestRelation(t *testing.T) {
people, _ := sess.Collection("people") people, _ := sess.Collection("people")
results := people.FindAll( results, _ := people.FindAll(
db.Relate{ db.Relate{
"lives_in": db.On{ "lives_in": db.On{
sess.ExistentCollection("places"), sess.ExistentCollection("places"),
...@@ -425,6 +472,7 @@ func TestRelation(t *testing.T) { ...@@ -425,6 +472,7 @@ func TestRelation(t *testing.T) {
// Tests relations between collections using structs. // Tests relations between collections using structs.
func TestRelationStruct(t *testing.T) { func TestRelationStruct(t *testing.T) {
var err error var err error
var res db.Result
sess, err := db.Open(wrapperName, settings) sess, err := db.Open(wrapperName, settings)
...@@ -454,7 +502,7 @@ func TestRelationStruct(t *testing.T) { ...@@ -454,7 +502,7 @@ func TestRelationStruct(t *testing.T) {
} }
}{} }{}
err = people.FetchAll(&results, res, err = people.Query(
db.Relate{ db.Relate{
"LivesIn": db.On{ "LivesIn": db.On{
sess.ExistentCollection("places"), sess.ExistentCollection("places"),
...@@ -483,11 +531,18 @@ func TestRelationStruct(t *testing.T) { ...@@ -483,11 +531,18 @@ func TestRelationStruct(t *testing.T) {
t.Fatalf(err.Error()) t.Fatalf(err.Error())
} }
err = res.All(&results)
if err != nil {
t.Fatalf(err.Error())
}
fmt.Printf("relations (2) %# v\n", pretty.Formatter(results)) fmt.Printf("relations (2) %# v\n", pretty.Formatter(results))
} }
// Tests datatype conversions. // Tests datatype conversions.
func TestDataTypes(t *testing.T) { func TestDataTypes(t *testing.T) {
var res db.Result
sess, err := db.Open(wrapperName, settings) sess, err := db.Open(wrapperName, settings)
...@@ -518,7 +573,7 @@ func TestDataTypes(t *testing.T) { ...@@ -518,7 +573,7 @@ func TestDataTypes(t *testing.T) {
} }
// Getting and reinserting (a db.Item). // Getting and reinserting (a db.Item).
item := dataTypes.Find() item, _ := dataTypes.Find()
_, err = dataTypes.Append(item) _, err = dataTypes.Append(item)
...@@ -536,7 +591,14 @@ func TestDataTypes(t *testing.T) { ...@@ -536,7 +591,14 @@ func TestDataTypes(t *testing.T) {
// Testing struct // Testing struct
sresults := []testValuesStruct{} sresults := []testValuesStruct{}
err = dataTypes.FetchAll(&sresults)
res, err = dataTypes.Query()
if err != nil {
t.Fatalf(err.Error())
}
err = res.All(&sresults)
if err != nil { if err != nil {
t.Fatalf(err.Error()) t.Fatalf(err.Error())
...@@ -550,7 +612,7 @@ func TestDataTypes(t *testing.T) { ...@@ -550,7 +612,7 @@ func TestDataTypes(t *testing.T) {
} }
// Testing maps // Testing maps
results := dataTypes.FindAll() results, _ := dataTypes.FindAll()
for _, item := range results { for _, item := range results {
......
/*
Copyright (c) 2013 José Carlos Nieto, http://xiam.menteslibres.org/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package postgresql
import (
"github.com/gosexy/db/util/sqlutil"
)
type Result struct {
sqlutil.Result
}
func (self *Result) All(dst interface{}) error {
return self.FetchAll(dst, toInternalInterface)
}
func (self *Result) Next(dst interface{}) error {
return self.FetchNext(dst, toInternalInterface)
}
func (self *Result) One(dst interface{}) error {
return self.FetchOne(dst, toInternalInterface)
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment