ISUCONにGo言語で参加することになったのですがGoを全く触ったことがなく、このままだと当日爆死するのが目に見えているため勉強がてらapp.go
を読んでみることにしました。
package main
import (
crand "crypto/rand"
"fmt"
"html/template"
"io"
"log"
"net/http"
"net/url"
"os"
"os/exec"
"path"
"regexp"
"strconv"
"strings"
"time"
"github.com/bradfitz/gomemcache/memcache"
gsm "github.com/bradleypeabody/gorilla-sessions-memcache"
"github.com/go-chi/chi/v5"
_ "github.com/go-sql-driver/mysql"
"github.com/gorilla/sessions"
"github.com/jmoiron/sqlx"
)
必要なパッケージをインポートしています。
// グローバル変数を定義
var (
db *sqlx.DB
store *gsm.MemcacheStore
)
-
var()
グローバル変数を一括で定義しています。 -
db
*sqlx.DB型のポインタで、データベース接続を表します。
sqlxは、標準のdatabase/sqlパッケージを拡張した便利なライブラリで、構造体とデータベースのマッピングやその他の操作を簡単にします。
db
はこのプログラム全体で共有されるデータベース接続として利用されます。 -
store
*gsm.MemcacheStore型のポインタで、メモリキャッシュのストアを表します。
const (
postsPerPage = 20 // ページネーションで1ページあたりに表示する投稿数
ISO8601Format = "2006-01-02T15:04:05-07:00" //日時のフォーマット
UploadLimit = 10 * 1024 * 1024 // ファイルアップロードの最大サイズ10MB
)
-
const()
定数を一括で定義しています
type User struct {
ID int `db:"id"`
AccountName string `db:"account_name"`
Passhash string `db:"passhash"`
Authority int `db:"authority"`
DelFlg int `db:"del_flg"`
CreatedAt time.Time `db:"created_at"`
}
-
User
ユーザー情報を表す構造体です。
フィールドの横にあるdb:"..."
タグは、データベースのカラム名とのマッピングを指定しています。 - 各フィールドの意味
- ID: ユーザーのID。
- AccountName: ユーザー名。
- Passhash: パスワードのハッシュ。
- Authority: 権限レベル(例: 管理者や一般ユーザーなど)。
- DelFlg: 削除フラグ(論理削除用)。
- CreatedAt: ユーザー作成日時。
type Post struct {
ID int `db:"id"`
UserID int `db:"user_id"`
Imgdata []byte `db:"imgdata"`
Body string `db:"body"`
Mime string `db:"mime"`
CreatedAt time.Time `db:"created_at"`
CommentCount int
Comments []Comment
User User
CSRFToken string
}
-
Post
投稿を表す構造体です。 - 各フィールドの意味
- ID: 投稿のID。
- UserID: 投稿を作成したユーザーのID。
- Imgdata: 画像データ(バイナリ形式)。
- Body: 投稿の本文。
- Mime: 投稿画像のMIMEタイプ(例: "image/png")。
- CreatedAt: 投稿作成日時。
- CommentCount: コメントの数。
- Comments: 投稿に紐づくコメントのリスト。
- User: 投稿を作成したユーザーの詳細。
- CSRFToken: CSRF対策用のトークン(フォーム送信の検証用)。
type Comment struct {
ID int `db:"id"`
PostID int `db:"post_id"`
UserID int `db:"user_id"`
Comment string `db:"comment"`
CreatedAt time.Time `db:"created_at"`
User User
}
-
Comment
コメントを表す構造体です。 - 各フィールドの意味
- ID: コメントのID。
- PostID: 紐づいている投稿のID。
- UserID: コメントを作成したユーザーのID。
- Comment: コメント本文。
- CreatedAt: コメント作成日時。
- User: コメントを作成したユーザーの詳細。
func init() {
// 環境変数からMemcachedのアドレスを取得
memdAddr := os.Getenv("ISUCONP_MEMCACHED_ADDRESS")
// アドレスが設定されていなければデフォルト値を使用
if memdAddr == "" {
memdAddr = "localhost:11211"
}
// Memcachedクライアントを作成し、アプリケーション全体で使うキャッシュストアを初期化
memcacheClient := memcache.New(memdAddr)
store = gsm.NewMemcacheStore(memcacheClient, "iscogram_", []byte("sendagaya"))
// ログ設定を行う
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
}
-
init関数
プログラム実行時に自動的に呼び出される特別な関数で、主に初期化処理を記述します。 - 詳細
-
os.Getenv
Go言語の標準ライブラリで提供されるosパッケージ
に含まれる関数で、環境変数の値を取得するために使用します。 -
memdAddr = "localhost:11211"
Memcachedサーバーがローカルホストのポート11211で動作していることを意味します。 -
memcache.New(memdAddr)
memcacheパッケージを使って、指定したアドレスに接続するMemcachedクライアントを作成しています。
これによりアプリケーションがMemcachedサーバーに接続し、キャッシュ操作を実行できるようにしています。 -
log.SetFlags
log.SetFlagsは、Go言語の標準ライブラリlogパッケージ
に含まれる関数で、ログメッセージの出力形式を指定するために使用します。
-