2016-12-21 4 views
2

Я пишу своего рода REST-подобный API в Go. У меня есть база данных, поэтому я не могу управлять именами полей или структурой или что-то в этом роде. Я абстрагирую методы доступа к базе данных в отдельном пакете под названием datastore. Код у меня выглядит следующим образом (пропуская все обработки и т.д. ошибка)Пользовательский сканер для структур в Go

 
type Datastore struct {} 

type Object struct { 
    id uint 
    name string 
    ... zillion more fields here 
} 

func (Datastore) ObjectList() { 
    var objects *[]Object 
    db, _ := sqlx.Open("postgres", conn_info) 
    rows, _ := sqlx.Queryx("SELECT * FROM object_table") 
    defer rows.Close() 
    for rows.Next() { 
    var obj Object 
    rows.Scan(&obj.id, &obj.name) 
    objects = append(objects, obj) 
    } 
    return objects 
} 

проблема я в настоящее время имею что таблица объект имеет десятки и десятки полей. Некоторые меня волнуют, но некоторые я этого не делаю. Некоторые из них называются такими же, как Object, а некоторые - нет. В конце концов, мне нужно будет поддержать большинство из них, но сначала я работаю над доказательством концепции. Кажется, что код сканирования сбой, если он находит больше полей в строке, чем в аргументах для Scan(). Я мог бы перечислить поля, которые я просматриваю, в запросе select id, name from object_table, но 1. он делает код крайне уродливым (SQL не получается отформатированным прямо gofmt) 2. он добавляет другое место, которое мне нужно изменить, когда я хочу поддержать другое поле

Есть ли способ реализовать пользовательский интерфейс сканера, который займет объект rows, загрузить некоторые данные из него в структуру и игнорировать остальные?

+0

Вы должны сделать это ясно, что вы используете SQLX в вашем вопросе, не делают люди пытаются угадать, что продолжается. Кроме того, так работает API. Вам нужно 3 поля, сканирование занимает 3 значения, период вокруг не существует. Если вам нужно другое поведение, используйте другой метод, например Get или Select. – mpm

+0

Я бы сказал, что вы можете попробовать ORM, например https://github.com/jinzhu/gorm. –

+0

@mpm Get() и Select() работают в одной и той же проблеме. Что значит «нет»? Всегда есть способ обойти это. Это может быть реализация моего собственного сканирования, но я не могу понять, как это сделать. –

ответ

0

Вы уже используете SQLX так просто использовать * DB.Unsafe() перед запрашивая:

var db *sqlx.DB 

// exactly the same as the built-in 
db = sqlx.Open("sqlite3", ":memory:") 
var p Person 
udb := db.Unsafe() 
err = udb.Get(&p, "SELECT * FROM person, place LIMIT 1;") 
+0

Huh ... именно то, что я искал. Эта функция должна быть более заметной в документах :) –