Hi! It seems that the driver sometimes does not return an error if a column 
is null and I scan for s string, but instead returns the column name. I 
have to explicitly use the following function to test for null.

func FieldIsNull(db *sql.DB, table string, item string, field string) bool {
    var result int
    err := db.QueryRow(fmt.Sprintf(`SELECT EXISTS (SELECT 1 FROM "%s" WHERE 
? IS NULL and Id=?)`, table), field, item).Scan(&result)
    if err != nil {
        return false
    }
    return result > 0
}

The problem is, however, that I also sometimes have a custom table with no 
rows in it. Again, instead of returning an error, the driver or the sql 
package returns the column name instead of an error. The following test 
does *not* work:

func HasListFieldValue(db *sql.DB, table string, item string, field string) 
bool {
    var result int
    err := db.QueryRow(fmt.Sprintf(`SELECT EXISTS (SELECT 1 FROM "%s" WHERE 
"%s" IS NOT NULL AND Owner=?)`, table, field), item).Scan(&result)
    if err != nil {
        return false
    }
    return result > 0
}

(It's called a "ListField", because I'm abstracting from the database 
schema and allow "fields" with single values and those with list values, 
who are stored in a separate table.)

How can I check whether the rows returned are empty? When the table whose 
name is in tableName exists and has no rows, then the code below does *not* 
return an error but instead the string passed in variable "field"! How is 
this even possible? Am I overlooking something totally obvious?

Does an sql database driver return the column names first, before it 
returns any rows? That would explain it but would unusual and does not seem 
to have been  documented.

func getListField(db *sql.DB, table string, item string, field string) (
string, error) {
    tableName := listFieldToTableName(table, field)
    if !TableExists(db, tableName) {
        return "", errors.New(fmt.Sprintf("list field %s does not exist in 
table %s", field, table))
    }
    if !FieldExists(db, tableName, field) {
        return "", errors.New(fmt.Sprintf("internal error, %s does not have 
a field %s", tableName, field))
    }
    todo not working
    if HasListFieldValue(db, tableName, item, field) {
        return "", errors.New(fmt.Sprintf("NULL list field %s of item %s in 
table %s", field, item, table))
    }
    rows, err := db.Query(fmt.Sprintf(`SELECT ? FROM "%s" WHERE Owner=?`, 
tableName), field, item)
    if err != nil {
        return "", errors.New(fmt.Sprintf("list field %s of item %s in 
table %s not found: %s", field, item, table, err))
    }
    results := make([]string, 0)
    for rows.Next() {
        var datum sql.NullString
        if err := rows.Scan(&datum); err != nil {
            rows.Close()
            return "", errors.New(fmt.Sprintf("cannot retrieve list field 
%s of item %s in table %s: %s", field, item, table, err))
        }
        if !datum.Valid {
            rows.Close()
            return "", errors.New(fmt.Sprintf("NULL for field %s of item %s 
in table %s", field, item, table))
        }
        results = append(results, datum.String)
    }
    rows.Close()
    if err := rows.Err(); err != nil {
        return "", errors.New(fmt.Sprintf("cannot retrieve list field %s of 
item %s in table %s: %s", field, item, table, err))
    }
    return strings.Join(results, "\n"), nil
}


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to