Skip to content

Commit 69a1aab

Browse files
committed
new sqlpage.current_working_directory() function
1 parent a897a13 commit 69a1aab

File tree

8 files changed

+110
-36
lines changed

8 files changed

+110
-36
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# CHANGELOG.md
22

3-
## 0.10.4 (unreleased)
3+
## 0.11.0 (unreleased)
44
- Better support for connection options in mssql.
55
- New icons (see https://tabler-icons.io/changelog)
66
- New version of the CSS library (see https://preview.tabler.io/changelog.html)
@@ -10,6 +10,7 @@
1010
SQLPage is now running on http://127.0.0.1:8080/
1111
You can write your code in .sql files in /path/to/your/website/directory.
1212
```
13+
- New `sqlpage.current_working_directory` function to get the [current working directory](https://en.wikipedia.org/wiki/Working_directory) of the SQLPage process.
1314
1415
## 0.10.3 (2023-09-14)
1516

examples/official-site/components.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SELECT 'redirect' as component, 'documentation.sql' as link;

examples/official-site/sqlpage/migrations/01_documentation.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ INSERT INTO example(component, description, properties) VALUES
445445
"component": "shell",
446446
"title": "SQLPage documentation",
447447
"link": "/",
448-
"menu_item": "index",
448+
"menu_item": ["index", "blog", "components", "functions"],
449449
"language": "en-US",
450450
"description": "Documentation for the SQLPage low-code web application framework.",
451451
"font": "Poppins",

examples/official-site/sqlpage/migrations/08_functions.sql

Lines changed: 79 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ CREATE TABLE IF NOT EXISTS sqlpage_function_parameters (
1212
"description_md" TEXT,
1313
"type" TEXT
1414
);
15-
INSERT INTO sqlpage_functions ("name", "return_type", "introduced_in_version", "icon", "description_md")
15+
INSERT INTO sqlpage_functions (
16+
"name",
17+
"return_type",
18+
"introduced_in_version",
19+
"icon",
20+
"description_md"
21+
)
1622
VALUES (
1723
'cookie',
1824
'TEXT',
@@ -45,7 +51,12 @@ VALUES (
4551
'The name of the cookie to read.',
4652
'TEXT'
4753
);
48-
INSERT INTO sqlpage_functions ("name", "introduced_in_version", "icon", "description_md")
54+
INSERT INTO sqlpage_functions (
55+
"name",
56+
"introduced_in_version",
57+
"icon",
58+
"description_md"
59+
)
4960
VALUES (
5061
'header',
5162
'0.7.2',
@@ -76,7 +87,13 @@ VALUES (
7687
'The name of the HTTP header to read.',
7788
'TEXT'
7889
);
79-
INSERT INTO sqlpage_functions ("name", "return_type", "introduced_in_version", "icon", "description_md")
90+
INSERT INTO sqlpage_functions (
91+
"name",
92+
"return_type",
93+
"introduced_in_version",
94+
"icon",
95+
"description_md"
96+
)
8097
VALUES (
8198
'basic_auth_username',
8299
'TEXT',
@@ -112,7 +129,12 @@ SELECT ''authentication'' AS component,
112129
```
113130
'
114131
);
115-
INSERT INTO sqlpage_functions ("name", "introduced_in_version", "icon", "description_md")
132+
INSERT INTO sqlpage_functions (
133+
"name",
134+
"introduced_in_version",
135+
"icon",
136+
"description_md"
137+
)
116138
VALUES (
117139
'hash_password',
118140
'0.7.2',
@@ -145,13 +167,17 @@ VALUES (
145167
'The password to hash.',
146168
'TEXT'
147169
);
148-
149-
INSERT INTO sqlpage_functions ("name", "introduced_in_version", "icon", "description_md")
170+
INSERT INTO sqlpage_functions (
171+
"name",
172+
"introduced_in_version",
173+
"icon",
174+
"description_md"
175+
)
150176
VALUES (
151-
'random_string',
152-
'0.7.2',
153-
'arrows-shuffle',
154-
'Returns a cryptographically secure random string of the given length.
177+
'random_string',
178+
'0.7.2',
179+
'arrows-shuffle',
180+
'Returns a cryptographically secure random string of the given length.
155181
156182
### Example
157183
@@ -165,18 +191,48 @@ RETURNING
165191
session_token AS value;
166192
```
167193
'
168-
);
194+
);
169195
INSERT INTO sqlpage_function_parameters (
170-
"function",
171-
"index",
172-
"name",
173-
"description_md",
174-
"type"
175-
)
196+
"function",
197+
"index",
198+
"name",
199+
"description_md",
200+
"type"
201+
)
176202
VALUES (
177-
'random_string',
178-
1,
179-
'length',
180-
'The length of the string to generate.',
181-
'INTEGER'
182-
);
203+
'random_string',
204+
1,
205+
'length',
206+
'The length of the string to generate.',
207+
'INTEGER'
208+
);
209+
INSERT INTO sqlpage_functions (
210+
"name",
211+
"introduced_in_version",
212+
"icon",
213+
"description_md"
214+
)
215+
VALUES (
216+
'current_working_directory',
217+
'0.11.0',
218+
'folder-question',
219+
'Returns the [current working directory](https://en.wikipedia.org/wiki/Working_directory) of the SQLPage server process.
220+
221+
### Example
222+
223+
```sql
224+
SELECT ''text'' AS component;
225+
SELECT ''Currently running from '' AS contents;
226+
SELECT sqlpage.current_working_directory() as contents, true as code;
227+
```
228+
229+
#### Result
230+
231+
Currently running from `/home/user/my_sqlpage_website`
232+
233+
#### Notes
234+
235+
The current working directory is the directory from which the SQLPage server process was started.
236+
By default, this is also the directory from which `.sql` files are loaded and served.
237+
However, this can be changed by setting the `web_root` [configuration option](https://github.com/lovasoa/SQLpage/blob/main/configuration.md).
238+
');

index.sql

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,17 @@ SELECT 'text' as component, -- We can switch to another component at any time ju
1818
-- We are now inside the text component. Each row that will be returned by our SELECT queries will be a span of text
1919
-- The text component has a property called "contents" that can be that we use to set the contents of our block of text
2020
-- and a property called "center" that we use to center the text
21-
SELECT 'In order to get started ' as contents;
22-
select 'visit SQLPage''s website' as contents,
21+
SELECT 'In order to get started, visit ' as contents;
22+
select 'SQLPage''s website' as contents,
2323
'https://sql.ophir.dev/your-first-sql-website/' as link,
2424
true as italics;
2525
SELECT '. You can replace this page''s contents by creating a file named ' as contents;
26-
SELECT 'index.sql' as contents, true as italics;
27-
SELECT ' in the folder where sqlpage is running. ' as contents;
28-
SELECT 'Alternatively, you can create a table called sqlpage_files in your database with the following columns: path, contents, and last_modified.' as contents;
26+
SELECT 'index.sql' as contents, 1 as code;
27+
SELECT ' in the folder where sqlpage is running (current working directory: ' as contents;
28+
SELECT sqlpage.current_working_directory() as contents, 1 as code;
29+
SELECT ').' as contents;
30+
SELECT 'You can customize your server''s [configuration](https://github.com/lovasoa/SQLpage/blob/main/configuration.md)
31+
by creating a file in `' || sqlpage.current_working_directory() || '/sqlpage/sqlpage.json`.' as contents_md;
32+
33+
SELECT '
34+
Alternatively, you can create a table called `sqlpage_files` in your database with the following columns: `path`, `contents`, and `last_modified`.' as contents_md;

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ async fn start() -> anyhow::Result<()> {
1616
let app_config = app_config::load()?;
1717
log::debug!("Starting with the following configuration: {app_config:?}");
1818
let state = AppState::init(&app_config).await?;
19-
webserver::apply_migrations(&state.db, &app_config.web_root).await?;
19+
webserver::apply_migrations(&state.db).await?;
2020
let listen_on = app_config.listen_on;
2121
log::info!("Starting server on {}", listen_on);
2222
let config = Config { listen_on };

src/webserver/database/mod.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use futures_util::StreamExt;
88
use serde_json::Value;
99
use std::borrow::Cow;
1010
use std::fmt::{Display, Formatter};
11-
use std::path::Path;
1211
use std::time::Duration;
1312

1413
use crate::app_config::AppConfig;
@@ -47,16 +46,18 @@ impl Database {
4746
}
4847
}
4948

50-
pub async fn apply_migrations(db: &Database, web_root: &Path) -> anyhow::Result<()> {
51-
let migrations_dir = web_root.join(MIGRATIONS_DIR);
49+
pub async fn apply_migrations(db: &Database) -> anyhow::Result<()> {
50+
let migrations_dir = std::env::current_dir()
51+
.unwrap_or_default()
52+
.join(MIGRATIONS_DIR);
5253
if !migrations_dir.exists() {
5354
log::info!(
5455
"Not applying database migrations because '{}' does not exist",
55-
MIGRATIONS_DIR
56+
migrations_dir.display()
5657
);
5758
return Ok(());
5859
}
59-
log::info!("Applying migrations from '{MIGRATIONS_DIR}'");
60+
log::info!("Applying migrations from '{}'", migrations_dir.display());
6061
let migrator = Migrator::new(migrations_dir)
6162
.await
6263
.with_context(|| migration_err("preparing the database migration"))?;

src/webserver/database/sql_pseudofunctions.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ pub(super) enum StmtParam {
2626
BasicAuthUsername,
2727
HashPassword(Box<StmtParam>),
2828
RandomString(usize),
29+
CurrentWorkingDir,
2930
}
3031

3132
pub(super) fn func_call_to_param(func_name: &str, arguments: &mut [FunctionArg]) -> StmtParam {
@@ -41,6 +42,7 @@ pub(super) fn func_call_to_param(func_name: &str, arguments: &mut [FunctionArg])
4142
.map_or_else(StmtParam::Error, StmtParam::HashPassword),
4243
"random_string" => extract_integer("random_string", arguments)
4344
.map_or_else(StmtParam::Error, StmtParam::RandomString),
45+
"current_working_directory" => StmtParam::CurrentWorkingDir,
4446
unknown_name => StmtParam::Error(format!(
4547
"Unknown function {unknown_name}({})",
4648
FormatArguments(arguments)
@@ -72,6 +74,7 @@ pub(super) fn extract_req_param<'a>(
7274
StmtParam::HashPassword(inner) => extract_req_param(inner, request)?
7375
.map_or(Ok(None), |x| hash_password(&x).map(Cow::Owned).map(Some))?,
7476
StmtParam::RandomString(len) => Some(Cow::Owned(random_string(*len))),
77+
StmtParam::CurrentWorkingDir => cwd()?,
7578
})
7679
}
7780

@@ -118,3 +121,9 @@ fn extract_basic_auth(request: &RequestInfo) -> anyhow::Result<&Basic> {
118121
})
119122
.with_context(|| "Expected the user to be authenticated with HTTP basic auth")
120123
}
124+
125+
fn cwd() -> anyhow::Result<Option<Cow<'static, str>>> {
126+
let cwd = std::env::current_dir()
127+
.with_context(|| "unable to access the current working directory")?;
128+
Ok(Some(Cow::Owned(cwd.to_string_lossy().to_string())))
129+
}

0 commit comments

Comments
 (0)