クエリをpostgresに送信して結果をページャーに送信するGolangコードの例を書きました:
package main
import (
"fmt"
"database/sql"
_ "github.com/lib/pq"
"log"
"os/exec"
"strings"
"os"
)
func main() {
connstr := "user=postgres dbname=postgres sslmode=disable"
db, err := sql.Open("postgres", connstr)
if err != nil { log.Fatal(err) }
rows, err := db.Query("SELECT schemaname, relname, seq_scan FROM pg_stat_all_tables ORDER BY 1 LIMIT 10")
if err != nil { log.Fatal(err) }
defer rows.Close()
var buf string
for rows.Next() {
var s, r string
var ss int
if err := rows.Scan(&s, &r, &ss); err != nil { log.Fatal(err) }
buf = fmt.Sprintf("%s %s %d\n", buf + s, r, ss)
}
cmd := exec.Command("less")
cmd.Stdin = strings.NewReader(buf)
cmd.Stdout = os.Stdout
err = cmd.Run()
if err != nil { log.Fatal(err) }
}
しかし、次の行:
buf = fmt.Sprintf("%s %s %d\n", buf + s, r, ss)
私には失礼に見えますが、これが正しい方法かどうかはわかりません。よりエレガントな方法で結果を達成する方法はありますか?ある種のバッファとio.Readersで可能ですか?
Goの文字列は不変であり、変数に新しい値を割り当てるたびに、新しい文字列を作成し、既存の文字列の内容をその文字列にコピーする必要があります。
のbytes.Buffer
代わりにstring
を使用して、各反復での再作成を回避できます。
package main
import (
"fmt"
"database/sql"
_ "github.com/lib/pq"
"log"
"os/exec"
"strings"
"os"
"bytes"
)
func main() {
connstr := "user=postgres dbname=postgres sslmode=disable"
db, err := sql.Open("postgres", connstr)
if err != nil { log.Fatal(err) }
rows, err := db.Query("SELECT schemaname, relname, seq_scan FROM pg_stat_all_tables ORDER BY 1 LIMIT 10")
if err != nil { log.Fatal(err) }
defer rows.Close()
var buf = new(bytes.Buffer)
for rows.Next() {
var s, r string
var ss int
if err := rows.Scan(&s, &r, &ss); err != nil { log.Fatal(err) }
buf.WriteString(fmt.Sprintf("%s %s %d\n", s, r, ss))
}
cmd := exec.Command("less")
cmd.Stdin = buf
cmd.Stdout = os.Stdout
err = cmd.Run()
if err != nil { log.Fatal(err) }
}
ところで、文字列ビルダーはGo 1.10で追加されましたhttps://godoc.org/strings#Builder
文字列連結ベンチマークの詳細については、http://herman.asia/efficient-string-concatenation-in-goをご覧ください。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加