- Add SiteManager for registering and managing static sites with file-based enhancement - Implement EnhanceInPlace method for in-place file modification using database content - Integrate automatic file enhancement triggers in UpdateContent API handler - Add comprehensive site configuration support in insertr.yaml with auto-enhancement - Extend serve command to automatically register and manage configured sites - Add backup system for original files before enhancement - Support multi-site hosting with individual auto-enhancement settings - Update documentation for server-hosted enhancement workflow This enables real-time content deployment where database content changes immediately update static files without requiring rebuilds or redeployment. The database remains the single source of truth while maintaining static file performance benefits.
684 lines
19 KiB
Go
684 lines
19 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/insertr/insertr/internal/auth"
|
|
"github.com/insertr/insertr/internal/content"
|
|
"github.com/insertr/insertr/internal/db"
|
|
"github.com/insertr/insertr/internal/db/postgresql"
|
|
"github.com/insertr/insertr/internal/db/sqlite"
|
|
)
|
|
|
|
// ContentHandler handles all content-related HTTP requests
|
|
type ContentHandler struct {
|
|
database *db.Database
|
|
authService *auth.AuthService
|
|
siteManager *content.SiteManager
|
|
}
|
|
|
|
// NewContentHandler creates a new content handler
|
|
func NewContentHandler(database *db.Database, authService *auth.AuthService) *ContentHandler {
|
|
return &ContentHandler{
|
|
database: database,
|
|
authService: authService,
|
|
siteManager: nil, // Will be set via SetSiteManager
|
|
}
|
|
}
|
|
|
|
// SetSiteManager sets the site manager for file enhancement
|
|
func (h *ContentHandler) SetSiteManager(siteManager *content.SiteManager) {
|
|
h.siteManager = siteManager
|
|
}
|
|
|
|
// GetContent handles GET /api/content/{id}
|
|
func (h *ContentHandler) GetContent(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
contentID := vars["id"]
|
|
siteID := r.URL.Query().Get("site_id")
|
|
|
|
if siteID == "" {
|
|
http.Error(w, "site_id parameter is required", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var content interface{}
|
|
var err error
|
|
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
content, err = h.database.GetSQLiteQueries().GetContent(context.Background(), sqlite.GetContentParams{
|
|
ID: contentID,
|
|
SiteID: siteID,
|
|
})
|
|
case "postgresql":
|
|
content, err = h.database.GetPostgreSQLQueries().GetContent(context.Background(), postgresql.GetContentParams{
|
|
ID: contentID,
|
|
SiteID: siteID,
|
|
})
|
|
default:
|
|
http.Error(w, "Unsupported database type", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
http.Error(w, "Content not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
http.Error(w, fmt.Sprintf("Database error: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
item := h.convertToAPIContent(content)
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(item)
|
|
}
|
|
|
|
// GetAllContent handles GET /api/content
|
|
func (h *ContentHandler) GetAllContent(w http.ResponseWriter, r *http.Request) {
|
|
siteID := r.URL.Query().Get("site_id")
|
|
if siteID == "" {
|
|
http.Error(w, "site_id parameter is required", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var dbContent interface{}
|
|
var err error
|
|
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
dbContent, err = h.database.GetSQLiteQueries().GetAllContent(context.Background(), siteID)
|
|
case "postgresql":
|
|
dbContent, err = h.database.GetPostgreSQLQueries().GetAllContent(context.Background(), siteID)
|
|
default:
|
|
http.Error(w, "Unsupported database type", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Database error: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
items := h.convertToAPIContentList(dbContent)
|
|
response := ContentResponse{Content: items}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(response)
|
|
}
|
|
|
|
// GetBulkContent handles GET /api/content/bulk
|
|
func (h *ContentHandler) GetBulkContent(w http.ResponseWriter, r *http.Request) {
|
|
siteID := r.URL.Query().Get("site_id")
|
|
if siteID == "" {
|
|
http.Error(w, "site_id parameter is required", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Parse ids parameter
|
|
idsParam := r.URL.Query()["ids[]"]
|
|
if len(idsParam) == 0 {
|
|
// Try single ids parameter
|
|
idsStr := r.URL.Query().Get("ids")
|
|
if idsStr == "" {
|
|
http.Error(w, "ids parameter is required", http.StatusBadRequest)
|
|
return
|
|
}
|
|
idsParam = strings.Split(idsStr, ",")
|
|
}
|
|
|
|
var dbContent interface{}
|
|
var err error
|
|
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
dbContent, err = h.database.GetSQLiteQueries().GetBulkContent(context.Background(), sqlite.GetBulkContentParams{
|
|
SiteID: siteID,
|
|
Ids: idsParam,
|
|
})
|
|
case "postgresql":
|
|
dbContent, err = h.database.GetPostgreSQLQueries().GetBulkContent(context.Background(), postgresql.GetBulkContentParams{
|
|
SiteID: siteID,
|
|
Ids: idsParam,
|
|
})
|
|
default:
|
|
http.Error(w, "Unsupported database type", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Database error: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
items := h.convertToAPIContentList(dbContent)
|
|
response := ContentResponse{Content: items}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(response)
|
|
}
|
|
|
|
// CreateContent handles POST /api/content
|
|
func (h *ContentHandler) CreateContent(w http.ResponseWriter, r *http.Request) {
|
|
var req CreateContentRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
http.Error(w, "Invalid JSON", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
siteID := r.URL.Query().Get("site_id")
|
|
if siteID == "" {
|
|
siteID = req.SiteID // fallback to request body
|
|
}
|
|
if siteID == "" {
|
|
siteID = "default" // final fallback
|
|
}
|
|
|
|
// Extract user from request using authentication service
|
|
userInfo, authErr := h.authService.ExtractUserFromRequest(r)
|
|
if authErr != nil {
|
|
http.Error(w, fmt.Sprintf("Authentication error: %v", authErr), http.StatusUnauthorized)
|
|
return
|
|
}
|
|
userID := userInfo.ID
|
|
|
|
var content interface{}
|
|
var err error
|
|
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
content, err = h.database.GetSQLiteQueries().CreateContent(context.Background(), sqlite.CreateContentParams{
|
|
ID: req.ID,
|
|
SiteID: siteID,
|
|
Value: req.Value,
|
|
Type: req.Type,
|
|
LastEditedBy: userID,
|
|
})
|
|
case "postgresql":
|
|
content, err = h.database.GetPostgreSQLQueries().CreateContent(context.Background(), postgresql.CreateContentParams{
|
|
ID: req.ID,
|
|
SiteID: siteID,
|
|
Value: req.Value,
|
|
Type: req.Type,
|
|
LastEditedBy: userID,
|
|
})
|
|
default:
|
|
http.Error(w, "Unsupported database type", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Failed to create content: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
item := h.convertToAPIContent(content)
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusCreated)
|
|
json.NewEncoder(w).Encode(item)
|
|
}
|
|
|
|
// UpdateContent handles PUT /api/content/{id} with upsert functionality
|
|
func (h *ContentHandler) UpdateContent(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
contentID := vars["id"]
|
|
siteID := r.URL.Query().Get("site_id")
|
|
|
|
if siteID == "" {
|
|
http.Error(w, "site_id parameter is required", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var req UpdateContentRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
http.Error(w, "Invalid JSON", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Extract user from request using authentication service
|
|
userInfo, authErr := h.authService.ExtractUserFromRequest(r)
|
|
if authErr != nil {
|
|
http.Error(w, fmt.Sprintf("Authentication error: %v", authErr), http.StatusUnauthorized)
|
|
return
|
|
}
|
|
userID := userInfo.ID
|
|
|
|
// Check if content exists for version history (non-blocking)
|
|
var existingContent interface{}
|
|
var contentExists bool
|
|
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
existingContent, _ = h.database.GetSQLiteQueries().GetContent(context.Background(), sqlite.GetContentParams{
|
|
ID: contentID,
|
|
SiteID: siteID,
|
|
})
|
|
contentExists = existingContent != nil
|
|
case "postgresql":
|
|
existingContent, _ = h.database.GetPostgreSQLQueries().GetContent(context.Background(), postgresql.GetContentParams{
|
|
ID: contentID,
|
|
SiteID: siteID,
|
|
})
|
|
contentExists = existingContent != nil
|
|
}
|
|
|
|
// Archive existing version before upsert (only if content already exists)
|
|
if contentExists {
|
|
if err := h.createContentVersion(existingContent); err != nil {
|
|
// Log error but don't fail the request - version history is non-critical
|
|
fmt.Printf("Warning: Failed to create content version: %v\n", err)
|
|
}
|
|
}
|
|
|
|
// Determine content type: use provided type, fallback to existing type, default to "text"
|
|
contentType := req.Type
|
|
if contentType == "" && contentExists {
|
|
contentType = h.getContentType(existingContent)
|
|
}
|
|
if contentType == "" {
|
|
contentType = "text" // default type for new content
|
|
}
|
|
|
|
// Perform upsert operation
|
|
var upsertedContent interface{}
|
|
var err error
|
|
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
upsertedContent, err = h.database.GetSQLiteQueries().UpsertContent(context.Background(), sqlite.UpsertContentParams{
|
|
ID: contentID,
|
|
SiteID: siteID,
|
|
Value: req.Value,
|
|
Type: contentType,
|
|
LastEditedBy: userID,
|
|
})
|
|
case "postgresql":
|
|
upsertedContent, err = h.database.GetPostgreSQLQueries().UpsertContent(context.Background(), postgresql.UpsertContentParams{
|
|
ID: contentID,
|
|
SiteID: siteID,
|
|
Value: req.Value,
|
|
Type: contentType,
|
|
LastEditedBy: userID,
|
|
})
|
|
default:
|
|
http.Error(w, "Unsupported database type", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Failed to upsert content: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
item := h.convertToAPIContent(upsertedContent)
|
|
|
|
// Trigger file enhancement if site is registered for auto-enhancement
|
|
if h.siteManager != nil && h.siteManager.IsAutoEnhanceEnabled(siteID) {
|
|
go func() {
|
|
if err := h.siteManager.EnhanceSite(siteID); err != nil {
|
|
log.Printf("⚠️ Failed to enhance site %s: %v", siteID, err)
|
|
} else {
|
|
log.Printf("✅ Enhanced files for site %s", siteID)
|
|
}
|
|
}()
|
|
}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(item)
|
|
}
|
|
|
|
// DeleteContent handles DELETE /api/content/{id}
|
|
func (h *ContentHandler) DeleteContent(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
contentID := vars["id"]
|
|
siteID := r.URL.Query().Get("site_id")
|
|
|
|
if siteID == "" {
|
|
http.Error(w, "site_id parameter is required", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var err error
|
|
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
err = h.database.GetSQLiteQueries().DeleteContent(context.Background(), sqlite.DeleteContentParams{
|
|
ID: contentID,
|
|
SiteID: siteID,
|
|
})
|
|
case "postgresql":
|
|
err = h.database.GetPostgreSQLQueries().DeleteContent(context.Background(), postgresql.DeleteContentParams{
|
|
ID: contentID,
|
|
SiteID: siteID,
|
|
})
|
|
default:
|
|
http.Error(w, "Unsupported database type", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Failed to delete content: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
|
|
// GetContentVersions handles GET /api/content/{id}/versions
|
|
func (h *ContentHandler) GetContentVersions(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
contentID := vars["id"]
|
|
siteID := r.URL.Query().Get("site_id")
|
|
|
|
if siteID == "" {
|
|
http.Error(w, "site_id parameter is required", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Parse limit parameter (default to 10)
|
|
limit := int64(10)
|
|
if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
|
|
if parsedLimit, err := strconv.ParseInt(limitStr, 10, 64); err == nil {
|
|
limit = parsedLimit
|
|
}
|
|
}
|
|
|
|
var dbVersions interface{}
|
|
var err error
|
|
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
dbVersions, err = h.database.GetSQLiteQueries().GetContentVersionHistory(context.Background(), sqlite.GetContentVersionHistoryParams{
|
|
ContentID: contentID,
|
|
SiteID: siteID,
|
|
LimitCount: limit,
|
|
})
|
|
case "postgresql":
|
|
// Note: PostgreSQL uses different parameter names due to int32 vs int64
|
|
dbVersions, err = h.database.GetPostgreSQLQueries().GetContentVersionHistory(context.Background(), postgresql.GetContentVersionHistoryParams{
|
|
ContentID: contentID,
|
|
SiteID: siteID,
|
|
LimitCount: int32(limit),
|
|
})
|
|
default:
|
|
http.Error(w, "Unsupported database type", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Database error: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
versions := h.convertToAPIVersionList(dbVersions)
|
|
response := ContentVersionsResponse{Versions: versions}
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(response)
|
|
}
|
|
|
|
// RollbackContent handles POST /api/content/{id}/rollback
|
|
func (h *ContentHandler) RollbackContent(w http.ResponseWriter, r *http.Request) {
|
|
vars := mux.Vars(r)
|
|
contentID := vars["id"]
|
|
siteID := r.URL.Query().Get("site_id")
|
|
|
|
if siteID == "" {
|
|
http.Error(w, "site_id parameter is required", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var req RollbackContentRequest
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
http.Error(w, "Invalid JSON", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Get the target version
|
|
var targetVersion interface{}
|
|
var err error
|
|
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
targetVersion, err = h.database.GetSQLiteQueries().GetContentVersion(context.Background(), req.VersionID)
|
|
case "postgresql":
|
|
targetVersion, err = h.database.GetPostgreSQLQueries().GetContentVersion(context.Background(), int32(req.VersionID))
|
|
default:
|
|
http.Error(w, "Unsupported database type", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
if err == sql.ErrNoRows {
|
|
http.Error(w, "Version not found", http.StatusNotFound)
|
|
return
|
|
}
|
|
http.Error(w, fmt.Sprintf("Database error: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// Verify the version belongs to the correct content
|
|
if !h.versionMatches(targetVersion, contentID, siteID) {
|
|
http.Error(w, "Version does not match content", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Extract user from request using authentication service
|
|
userInfo, authErr := h.authService.ExtractUserFromRequest(r)
|
|
if authErr != nil {
|
|
http.Error(w, fmt.Sprintf("Authentication error: %v", authErr), http.StatusUnauthorized)
|
|
return
|
|
}
|
|
userID := userInfo.ID
|
|
|
|
// Archive current version before rollback
|
|
var currentContent interface{}
|
|
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
currentContent, err = h.database.GetSQLiteQueries().GetContent(context.Background(), sqlite.GetContentParams{
|
|
ID: contentID,
|
|
SiteID: siteID,
|
|
})
|
|
case "postgresql":
|
|
currentContent, err = h.database.GetPostgreSQLQueries().GetContent(context.Background(), postgresql.GetContentParams{
|
|
ID: contentID,
|
|
SiteID: siteID,
|
|
})
|
|
default:
|
|
http.Error(w, "Unsupported database type", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Failed to get current content: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
err = h.createContentVersion(currentContent)
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Failed to create version: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// Rollback to target version
|
|
var updatedContent interface{}
|
|
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
sqliteVersion := targetVersion.(sqlite.ContentVersion)
|
|
updatedContent, err = h.database.GetSQLiteQueries().UpdateContent(context.Background(), sqlite.UpdateContentParams{
|
|
Value: sqliteVersion.Value,
|
|
Type: sqliteVersion.Type,
|
|
LastEditedBy: userID,
|
|
ID: contentID,
|
|
SiteID: siteID,
|
|
})
|
|
case "postgresql":
|
|
pgVersion := targetVersion.(postgresql.ContentVersion)
|
|
updatedContent, err = h.database.GetPostgreSQLQueries().UpdateContent(context.Background(), postgresql.UpdateContentParams{
|
|
Value: pgVersion.Value,
|
|
Type: pgVersion.Type,
|
|
LastEditedBy: userID,
|
|
ID: contentID,
|
|
SiteID: siteID,
|
|
})
|
|
default:
|
|
http.Error(w, "Unsupported database type", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Failed to rollback content: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
item := h.convertToAPIContent(updatedContent)
|
|
|
|
w.Header().Set("Content-Type", "application/json")
|
|
json.NewEncoder(w).Encode(item)
|
|
}
|
|
|
|
// Helper functions for type conversion
|
|
func (h *ContentHandler) convertToAPIContent(content interface{}) ContentItem {
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
c := content.(sqlite.Content)
|
|
return ContentItem{
|
|
ID: c.ID,
|
|
SiteID: c.SiteID,
|
|
Value: c.Value,
|
|
Type: c.Type,
|
|
CreatedAt: time.Unix(c.CreatedAt, 0),
|
|
UpdatedAt: time.Unix(c.UpdatedAt, 0),
|
|
LastEditedBy: c.LastEditedBy,
|
|
}
|
|
case "postgresql":
|
|
c := content.(postgresql.Content)
|
|
return ContentItem{
|
|
ID: c.ID,
|
|
SiteID: c.SiteID,
|
|
Value: c.Value,
|
|
Type: c.Type,
|
|
CreatedAt: time.Unix(c.CreatedAt, 0),
|
|
UpdatedAt: time.Unix(c.UpdatedAt, 0),
|
|
LastEditedBy: c.LastEditedBy,
|
|
}
|
|
}
|
|
return ContentItem{} // Should never happen
|
|
}
|
|
|
|
func (h *ContentHandler) convertToAPIContentList(contentList interface{}) []ContentItem {
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
list := contentList.([]sqlite.Content)
|
|
items := make([]ContentItem, len(list))
|
|
for i, content := range list {
|
|
items[i] = h.convertToAPIContent(content)
|
|
}
|
|
return items
|
|
case "postgresql":
|
|
list := contentList.([]postgresql.Content)
|
|
items := make([]ContentItem, len(list))
|
|
for i, content := range list {
|
|
items[i] = h.convertToAPIContent(content)
|
|
}
|
|
return items
|
|
}
|
|
return []ContentItem{} // Should never happen
|
|
}
|
|
|
|
func (h *ContentHandler) convertToAPIVersionList(versionList interface{}) []ContentVersion {
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
list := versionList.([]sqlite.ContentVersion)
|
|
versions := make([]ContentVersion, len(list))
|
|
for i, version := range list {
|
|
versions[i] = ContentVersion{
|
|
VersionID: version.VersionID,
|
|
ContentID: version.ContentID,
|
|
SiteID: version.SiteID,
|
|
Value: version.Value,
|
|
Type: version.Type,
|
|
CreatedAt: time.Unix(version.CreatedAt, 0),
|
|
CreatedBy: version.CreatedBy,
|
|
}
|
|
}
|
|
return versions
|
|
case "postgresql":
|
|
list := versionList.([]postgresql.ContentVersion)
|
|
versions := make([]ContentVersion, len(list))
|
|
for i, version := range list {
|
|
versions[i] = ContentVersion{
|
|
VersionID: int64(version.VersionID),
|
|
ContentID: version.ContentID,
|
|
SiteID: version.SiteID,
|
|
Value: version.Value,
|
|
Type: version.Type,
|
|
CreatedAt: time.Unix(version.CreatedAt, 0),
|
|
CreatedBy: version.CreatedBy,
|
|
}
|
|
}
|
|
return versions
|
|
}
|
|
return []ContentVersion{} // Should never happen
|
|
}
|
|
|
|
func (h *ContentHandler) createContentVersion(content interface{}) error {
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
c := content.(sqlite.Content)
|
|
return h.database.GetSQLiteQueries().CreateContentVersion(context.Background(), sqlite.CreateContentVersionParams{
|
|
ContentID: c.ID,
|
|
SiteID: c.SiteID,
|
|
Value: c.Value,
|
|
Type: c.Type,
|
|
CreatedBy: c.LastEditedBy,
|
|
})
|
|
case "postgresql":
|
|
c := content.(postgresql.Content)
|
|
return h.database.GetPostgreSQLQueries().CreateContentVersion(context.Background(), postgresql.CreateContentVersionParams{
|
|
ContentID: c.ID,
|
|
SiteID: c.SiteID,
|
|
Value: c.Value,
|
|
Type: c.Type,
|
|
CreatedBy: c.LastEditedBy,
|
|
})
|
|
}
|
|
return fmt.Errorf("unsupported database type")
|
|
}
|
|
|
|
func (h *ContentHandler) getContentType(content interface{}) string {
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
return content.(sqlite.Content).Type
|
|
case "postgresql":
|
|
return content.(postgresql.Content).Type
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (h *ContentHandler) versionMatches(version interface{}, contentID, siteID string) bool {
|
|
switch h.database.GetDBType() {
|
|
case "sqlite3":
|
|
v := version.(sqlite.ContentVersion)
|
|
return v.ContentID == contentID && v.SiteID == siteID
|
|
case "postgresql":
|
|
v := version.(postgresql.ContentVersion)
|
|
return v.ContentID == contentID && v.SiteID == siteID
|
|
}
|
|
return false
|
|
}
|