Stores: blogstore

Persist and publish posts with github.com/dracory/blogstore.

github.com/dracory/blogstore

blogstore persists blog posts (title, slug, content, status, metadata) in SQL so Go applications can publish and manage posts without custom persistence code.


Highlights

  • Automigration – optional table creation via NewStoreOptions.
  • Fluent post model – getters/setters for title, slug, excerpt, author, tags, publish timestamps, and metadata (JSON metas).
  • Status helpers – draft/published/archived convenience methods.
  • Query builder – filter posts by status, slug, author, publish window, pagination, ordering, and soft-delete inclusion.
  • Soft deletion – hide posts without losing history.
  • Debug logging – enable SQL tracing with DebugEnabled.

Creating a Store

func NewBlogStore(db *sql.DB, debug bool) (blogstore.StoreInterface, error) {
    st, err := blogstore.NewStore(blogstore.NewStoreOptions{
        DB:                  db,
        PostTableName:       "snv_blogs_post",
        TaxonomyEnabled:     true,
        TaxonomyTableName:   "snv_blogs_taxonomy",
        TermTableName:       "snv_blogs_term",
        VersioningEnabled:   true,
        VersioningTableName: "snv_blogs_version",
        AutomigrateEnabled:  true,
    })
    if err != nil {
        return nil, err
    }
    st.EnableDebug(debug)
    return st, nil
}
  • blogstore is the only store in the project that uses AutomigrateEnabled: true.
  • Taxonomy support – enabled with TaxonomyEnabled: true, TaxonomyTableName, and TermTableName.
  • Versioning support – enabled with VersioningEnabled: true and VersioningTableName.
  • Debug is controlled via st.EnableDebug(debug) after store creation.

Creating & Publishing Posts

post := blogstore.NewPost().
    SetTitle("Hello World").
    SetSlug("hello-world").
    SetContent("<p>Hello!</p>").
    SetStatus(blogstore.POST_STATUS_DRAFT).
    SetAuthorID("user_123")

if err := store.PostCreate(ctx, post); err != nil {
    log.Fatal(err)
}

post.SetStatus(blogstore.POST_STATUS_PUBLISHED).
post.SetPublishedAt(blogstore.NowUTC())
if err := store.PostUpdate(ctx, post); err != nil {
    log.Fatal(err)
}
  • Posts track dirty fields and only persist changes when updated.
  • SetMetas, Meta, UpsertMetas handle JSON metadata (tags, SEO info).

Querying Posts

query := blogstore.NewPostQuery().
    SetStatus(blogstore.POST_STATUS_PUBLISHED).
    SetPublishedAtGte("2025-01-01 00:00:00").
    SetOrderBy("published_at").
    SetSortDirection("desc").
    SetLimit(20)

list, err := store.PostList(ctx, query)
count, err := store.PostCount(ctx, query)
  • Filters include slug, author, search terms, created/published ranges, and soft-delete inclusion.

  • Design Principles – learn about the shared Dracory store architecture.
  • Entities & Interfaces – inspect how blogstore posts embed dataobject traits.
  • Testing – repository includes SQLite-based coverage for CRUD flows.
  • Create Your Own Store – extend these patterns for additional CMS content.