tangled
alpha
login
or
join now
ericwood.org
/
photos-site
1
fork
atom
A little app to serve my photography from my personal website
1
fork
atom
overview
issues
pulls
pipelines
photo count no represents filters
ericwood.org
5 months ago
3de747de
ca706986
+43
-30
3 changed files
expand all
collapse all
unified
split
src
db.rs
routes
photos.rs
templates
photos
index.jinja
+31
-18
src/db.rs
···
2
2
3
3
use crate::{Photo, Tag};
4
4
use serde::{Deserialize, Serialize};
5
5
-
use sqlx::{QueryBuilder, Sqlite, SqlitePool, query::QueryAs};
5
5
+
use sqlx::{QueryBuilder, Sqlite, SqlitePool};
6
6
7
7
#[derive(Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
8
8
#[serde(rename_all = "snake_case")]
···
78
78
pub tag: Option<String>,
79
79
}
80
80
81
81
-
pub async fn get_photo_count(pool: &SqlitePool) -> anyhow::Result<u32> {
82
82
-
let result: (u32,) = sqlx::query_as("SELECT COUNT(*) FROM photos")
81
81
+
pub async fn get_photos(pool: &SqlitePool, pq: PhotoQuery) -> anyhow::Result<(u32, Vec<Photo>)> {
82
82
+
let photos = build_photo_query(&pq, false)
83
83
+
.build_query_as()
84
84
+
.fetch_all(pool)
85
85
+
.await?;
86
86
+
87
87
+
// I like how convenient `QueryAs` is but it doesn't make it easy for me to select a COUNT for
88
88
+
// the results on top of it so whatever! One more query!!
89
89
+
let (count,): (u32,) = build_photo_query(&pq, true)
90
90
+
.build_query_as()
83
91
.fetch_one(pool)
84
92
.await?;
85
85
-
Ok(result.0)
93
93
+
94
94
+
Ok((count, photos))
86
95
}
87
96
88
88
-
pub async fn get_photos(pool: &SqlitePool, pq: PhotoQuery) -> anyhow::Result<Vec<Photo>> {
97
97
+
fn build_photo_query(pq: &PhotoQuery, count: bool) -> QueryBuilder<Sqlite> {
89
98
let offset = pq.pagination.limit * (pq.pagination.page - 1);
90
99
91
91
-
let mut query: QueryBuilder<Sqlite> = QueryBuilder::new("SELECT * FROM photos ");
100
100
+
let select = if count {
101
101
+
"SELECT COUNT(*) FROM photos "
102
102
+
} else {
103
103
+
"SELECT * FROM photos "
104
104
+
};
105
105
+
let mut query = QueryBuilder::new(select);
92
106
93
93
-
if let Some(tag) = pq.tag {
107
107
+
if let Some(tag) = pq.tag.clone() {
94
108
query
95
109
.push("JOIN photo_tags ON photo_tags.tag = ")
96
110
.push_bind(tag)
97
111
.push(" AND photo_tags.photo_id = photos.id ");
98
112
};
99
113
100
100
-
let sort_sql = pq.sort.to_sql();
101
101
-
query.push(format!("ORDER BY {sort_sql}"));
114
114
+
if !count {
115
115
+
let sort_sql = pq.sort.to_sql();
116
116
+
query.push(format!("ORDER BY {sort_sql}"));
117
117
+
118
118
+
query
119
119
+
.push(" LIMIT ")
120
120
+
.push_bind(pq.pagination.limit)
121
121
+
.push(" OFFSET ")
122
122
+
.push_bind(offset);
123
123
+
}
102
124
103
125
query
104
104
-
.push(" LIMIT ")
105
105
-
.push_bind(pq.pagination.limit)
106
106
-
.push(" OFFSET ")
107
107
-
.push_bind(offset);
108
108
-
109
109
-
let query: QueryAs<'_, Sqlite, Photo, _> = query.build_query_as();
110
110
-
let photos = query.fetch_all(pool).await?;
111
111
-
112
112
-
Ok(photos)
113
126
}
114
127
115
128
pub async fn get_photo(pool: &SqlitePool, id: String) -> anyhow::Result<Photo> {
+1
-3
src/routes/photos.rs
···
53
53
let tag = query.tag.clone();
54
54
let sort = query.sort.unwrap_or(SortField::TakenAt);
55
55
let dir = query.dir.unwrap_or(SortDirection::Desc);
56
56
-
let photos = db::get_photos(
56
56
+
let (total_photos, photos) = db::get_photos(
57
57
&state.pool,
58
58
PhotoQuery {
59
59
sort: Sort {
···
65
65
},
66
66
)
67
67
.await?;
68
68
-
69
69
-
let total_photos = db::get_photo_count(&state.pool).await?;
70
68
71
69
let current_tag = tag.clone();
72
70
let mut tags = db::get_tags(&state.pool).await?;
+11
-9
templates/photos/index.jinja
···
46
46
{% endfor %}
47
47
</div>
48
48
49
49
-
<ul class="pagination">
50
50
-
{% if pagination.prev_query %}
51
51
-
<a href="?{{ pagination.prev_query }}">←</a>
52
52
-
{% endif %}
53
53
-
<li>{{ pagination.page }} / {{ pagination.num_pages }}</li>
54
54
-
{% if pagination.next_query %}
55
55
-
<a href="?{{ pagination.next_query }}">→</a>
56
56
-
{% endif %}
57
57
-
</ul>
49
49
+
{% if pagination.num_pages > 1 %}
50
50
+
<ul class="pagination">
51
51
+
{% if pagination.prev_query %}
52
52
+
<a href="?{{ pagination.prev_query }}">←</a>
53
53
+
{% endif %}
54
54
+
<li>{{ pagination.page }} / {{ pagination.num_pages }}</li>
55
55
+
{% if pagination.next_query %}
56
56
+
<a href="?{{ pagination.next_query }}">→</a>
57
57
+
{% endif %}
58
58
+
</ul>
59
59
+
{% endif %}
58
60
{% endblock %}