Skip to content
This repository was archived by the owner on Apr 21, 2026. It is now read-only.

Commit 5d76f41

Browse files
committed
fix: Replace generate_series with ColdFusion date iteration for dashboard charts
Fixes SQL errors in dashboard queries by building 7-day date series in ColdFusion instead of using generate_series(), avoiding JDBC parameter binding issues with PostgreSQL.
1 parent cb25bbb commit 5d76f41

2 files changed

Lines changed: 102 additions & 78 deletions

File tree

app/controllers/admin/AdminController.cfc

Lines changed: 101 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -574,121 +574,144 @@ component extends="app.Controllers.Controller" {
574574
* Admin Dashboard
575575
*/
576576
function dashboard(){
577+
// Basic counts
577578
totalBlogs = model("blog").count();
578579
totalTestimonials = model("testimonial").count();
579580
totalNewUser = model("user").count(where="createdat >= '#dateFormat(now(), "yyyy-mm-dd")#'");
580581
totalUser = model("user").count();
581582
activeUsers = model("user").count(where="status = 'true'");
582-
583-
sevenDaysAgo = dateAdd("d", -7, now());
583+
584+
// ==================== USER DATA ====================
585+
sevenDaysAgo = dateAdd("d", -6, now()); // 6 days ago = 7 days total
586+
587+
// Get list of users from last 7 days (for display)
584588
last_seven_days_user = model("user").findAll(
585-
where="createdat >= '#sevenDaysAgo#'",
586-
order="createdat DESC");
587-
588-
last_7Days_Users = queryExecute("
589-
SELECT TO_CHAR(d::date, 'YYYY-MM-DD') AS day,
590-
COUNT(u.createdat) AS usercount
591-
FROM generate_series(
592-
:startDate::date,
593-
:startDate::date + INTERVAL '6 days',
594-
INTERVAL '1 day'
595-
) AS d
596-
LEFT JOIN users u
597-
ON TO_CHAR(u.createdat, 'YYYY-MM-DD') = TO_CHAR(d::date, 'YYYY-MM-DD')
598-
AND u.deletedat IS NULL
599-
GROUP BY d::date
600-
ORDER BY d::date ASC
589+
where="createdat >= '#dateFormat(sevenDaysAgo, "yyyy-mm-dd")#'",
590+
order="createdat DESC"
591+
);
592+
593+
// Get actual user counts for chart
594+
userCounts = queryExecute("
595+
SELECT DATE(createdat) AS day, COUNT(*) AS usercount
596+
FROM users
597+
WHERE createdat >= :startDate
598+
AND deletedat IS NULL
599+
GROUP BY DATE(createdat)
600+
ORDER BY DATE(createdat) ASC
601601
",
602602
{
603-
startDate: dateFormat(now() - 6, "yyyy-MM-dd")
603+
startDate: {value: dateFormat(sevenDaysAgo, "yyyy-mm-dd"), cfsqltype: "cf_sql_date"}
604604
},
605-
{datasource="wheels.dev"}
605+
{datasource: "wheels.dev"}
606606
);
607-
608-
userChartData = []; // Save chart data from query
609-
610-
for (i = 1; i <= last_7Days_Users.recordCount; i++) {
611-
arrayAppend(userChartData, {
612-
"day": last_7Days_Users.day[i],
613-
"usercount": last_7Days_Users.usercount[i]
607+
608+
// Build complete 7-day series in ColdFusion
609+
userChartData = [];
610+
for (i = 0; i < 7; i++) {
611+
currentDay = dateAdd("d", i, sevenDaysAgo);
612+
dayString = dateFormat(currentDay, "yyyy-mm-dd");
613+
614+
// Find count for this day (default to 0 if no data)
615+
dayCount = 0;
616+
for (row in userCounts) {
617+
if (dateFormat(row.day, "yyyy-mm-dd") == dayString) {
618+
dayCount = row.usercount;
619+
break;
620+
}
621+
}
622+
623+
arrayAppend(userChartData, {
624+
"day": dayString,
625+
"usercount": dayCount
614626
});
615627
}
616628
userJsonData = serializeJSON(userChartData);
617-
629+
630+
// ==================== BLOG DATA ====================
618631
distinctCategories = model("BlogCategory").findAll(select="categoryId", DISTINCT=true);
619632
totalCategories = distinctCategories.recordcount;
620-
621-
totalBlogs = model("blog").count();
633+
622634
totalApprovedBlogs = model("blog").count(where="status = 'Approved'");
623635
rejectedBlogs = model("blog").count(where="status = 'Rejected'");
624636
waitingforApprovalBlogs = model("blog").count(where="status IS NULL");
625-
626-
627-
last_7Days_Blogs = queryExecute("
628-
SELECT TO_CHAR(d::date, 'YYYY-MM-DD') AS day,
629-
COUNT(b.createdat) AS blogcount
630-
FROM generate_series(
631-
:startDate::date,
632-
:startDate::date + INTERVAL '6 days',
633-
INTERVAL '1 day'
634-
) AS d
635-
LEFT JOIN blog_posts b
636-
ON TO_CHAR(b.createdat, 'YYYY-MM-DD') = TO_CHAR(d::date, 'YYYY-MM-DD')
637-
AND b.deletedat IS NULL
638-
GROUP BY d::date
639-
ORDER BY d::date ASC
637+
638+
// Get actual blog counts for chart
639+
blogCounts = queryExecute("
640+
SELECT DATE(createdat) AS day, COUNT(*) AS blogcount
641+
FROM blog_posts
642+
WHERE createdat >= :startDate
643+
AND deletedat IS NULL
644+
GROUP BY DATE(createdat)
645+
ORDER BY DATE(createdat) ASC
640646
",
641647
{
642-
startDate: dateFormat(now() - 6, "yyyy-MM-dd")
648+
startDate: {value: dateFormat(sevenDaysAgo, "yyyy-mm-dd"), cfsqltype: "cf_sql_date"}
643649
},
644-
{datasource="wheels.dev"}
650+
{datasource: application.env.datasource}
645651
);
646-
647-
// Prepare data for chart
652+
653+
// Build complete 7-day series
648654
blogChartData = [];
649-
for (i = 1; i <= last_7Days_Blogs.recordCount; i++) {
650-
arrayAppend(blogChartData, {
651-
"day": last_7Days_Blogs.day[i],
652-
"blogcount": last_7Days_Blogs.blogcount[i]
655+
for (i = 0; i < 7; i++) {
656+
currentDay = dateAdd("d", i, sevenDaysAgo);
657+
dayString = dateFormat(currentDay, "yyyy-mm-dd");
658+
659+
dayCount = 0;
660+
for (row in blogCounts) {
661+
if (dateFormat(row.day, "yyyy-mm-dd") == dayString) {
662+
dayCount = row.blogcount;
663+
break;
664+
}
665+
}
666+
667+
arrayAppend(blogChartData, {
668+
"day": dayString,
669+
"blogcount": dayCount
653670
});
654671
}
655672
blogJsonData = serializeJSON(blogChartData);
656-
673+
674+
// ==================== COMMENT DATA ====================
657675
totalComments = model("comment").count();
658676
totalPublishComments = model("comment").count(where="isPublished = 1");
659677
totalUnPublishComments = model("comment").count(where="isPublished = 0");
660-
661-
last_7Days_Comments = queryExecute("
662-
SELECT TO_CHAR(d::date, 'YYYY-MM-DD') AS day,
663-
COUNT(c.published_at) AS commentcount
664-
FROM generate_series(
665-
:startDate::date,
666-
:startDate::date + INTERVAL '6 days',
667-
INTERVAL '1 day'
668-
) AS d
669-
LEFT JOIN comments c
670-
ON TO_CHAR(c.published_at, 'YYYY-MM-DD') = TO_CHAR(d::date, 'YYYY-MM-DD')
671-
AND c.deletedat IS NULL
672-
AND c.is_published = true
673-
GROUP BY d::date
674-
ORDER BY d::date ASC
678+
679+
// Get actual comment counts for chart
680+
commentCounts = queryExecute("
681+
SELECT DATE(published_at) AS day, COUNT(*) AS commentcount
682+
FROM comments
683+
WHERE published_at >= :startDate
684+
AND deletedat IS NULL
685+
AND is_published = true
686+
GROUP BY DATE(published_at)
687+
ORDER BY DATE(published_at) ASC
675688
",
676689
{
677-
startDate: dateFormat(now() - 6, "yyyy-MM-dd")
690+
startDate: {value: dateFormat(sevenDaysAgo, "yyyy-mm-dd"), cfsqltype: "cf_sql_date"}
678691
},
679-
{datasource="wheels.dev"}
692+
{datasource: "wheels.dev"}
680693
);
681-
682-
// Prepare data for chart
694+
695+
// Build complete 7-day series
683696
commentChartData = [];
684-
for (i = 1; i <= last_7Days_Comments.recordCount; i++) {
685-
arrayAppend(commentChartData, {
686-
"day": last_7Days_Comments.day[i],
687-
"commentcount": last_7Days_Comments.commentcount[i]
697+
for (i = 0; i < 7; i++) {
698+
currentDay = dateAdd("d", i, sevenDaysAgo);
699+
dayString = dateFormat(currentDay, "yyyy-mm-dd");
700+
701+
dayCount = 0;
702+
for (row in commentCounts) {
703+
if (dateFormat(row.day, "yyyy-mm-dd") == dayString) {
704+
dayCount = row.commentcount;
705+
break;
706+
}
707+
}
708+
709+
arrayAppend(commentChartData, {
710+
"day": dayString,
711+
"commentcount": dayCount
688712
});
689713
}
690714
commentJsonData = serializeJSON(commentChartData);
691-
692715
}
693716

694717
/**

deploy/swarm/.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ reloadPassword=w4u6r7daKHAYMDLZXDgUcwn99RReNium
66
cfconfig_adminPassword=commandbox
77

88
application_host=https://wheels.dev
9+
datasource=wheels.dev
910

1011
wheelsdev_host=10.100.10.230
1112
wheelsdev_port=26257

0 commit comments

Comments
 (0)