Skip to content

Commit

Permalink
new sqlpage.current_working_directory() function
Browse files Browse the repository at this point in the history
  • Loading branch information
lovasoa committed Sep 17, 2023
1 parent a897a13 commit 69a1aab
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 36 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CHANGELOG.md

## 0.10.4 (unreleased)
## 0.11.0 (unreleased)
- Better support for connection options in mssql.
- New icons (see https://tabler-icons.io/changelog)
- New version of the CSS library (see https://preview.tabler.io/changelog.html)
Expand All @@ -10,6 +10,7 @@
SQLPage is now running on http://127.0.0.1:8080/
You can write your code in .sql files in /path/to/your/website/directory.
```
- New `sqlpage.current_working_directory` function to get the [current working directory](https://en.wikipedia.org/wiki/Working_directory) of the SQLPage process.
## 0.10.3 (2023-09-14)
Expand Down
1 change: 1 addition & 0 deletions examples/official-site/components.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT 'redirect' as component, 'documentation.sql' as link;
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ INSERT INTO example(component, description, properties) VALUES
"component": "shell",
"title": "SQLPage documentation",
"link": "/",
"menu_item": "index",
"menu_item": ["index", "blog", "components", "functions"],
"language": "en-US",
"description": "Documentation for the SQLPage low-code web application framework.",
"font": "Poppins",
Expand Down
102 changes: 79 additions & 23 deletions examples/official-site/sqlpage/migrations/08_functions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ CREATE TABLE IF NOT EXISTS sqlpage_function_parameters (
"description_md" TEXT,
"type" TEXT
);
INSERT INTO sqlpage_functions ("name", "return_type", "introduced_in_version", "icon", "description_md")
INSERT INTO sqlpage_functions (
"name",
"return_type",
"introduced_in_version",
"icon",
"description_md"
)
VALUES (
'cookie',
'TEXT',
Expand Down Expand Up @@ -45,7 +51,12 @@ VALUES (
'The name of the cookie to read.',
'TEXT'
);
INSERT INTO sqlpage_functions ("name", "introduced_in_version", "icon", "description_md")
INSERT INTO sqlpage_functions (
"name",
"introduced_in_version",
"icon",
"description_md"
)
VALUES (
'header',
'0.7.2',
Expand Down Expand Up @@ -76,7 +87,13 @@ VALUES (
'The name of the HTTP header to read.',
'TEXT'
);
INSERT INTO sqlpage_functions ("name", "return_type", "introduced_in_version", "icon", "description_md")
INSERT INTO sqlpage_functions (
"name",
"return_type",
"introduced_in_version",
"icon",
"description_md"
)
VALUES (
'basic_auth_username',
'TEXT',
Expand Down Expand Up @@ -112,7 +129,12 @@ SELECT ''authentication'' AS component,
```
'
);
INSERT INTO sqlpage_functions ("name", "introduced_in_version", "icon", "description_md")
INSERT INTO sqlpage_functions (
"name",
"introduced_in_version",
"icon",
"description_md"
)
VALUES (
'hash_password',
'0.7.2',
Expand Down Expand Up @@ -145,13 +167,17 @@ VALUES (
'The password to hash.',
'TEXT'
);

INSERT INTO sqlpage_functions ("name", "introduced_in_version", "icon", "description_md")
INSERT INTO sqlpage_functions (
"name",
"introduced_in_version",
"icon",
"description_md"
)
VALUES (
'random_string',
'0.7.2',
'arrows-shuffle',
'Returns a cryptographically secure random string of the given length.
'random_string',
'0.7.2',
'arrows-shuffle',
'Returns a cryptographically secure random string of the given length.
### Example
Expand All @@ -165,18 +191,48 @@ RETURNING
session_token AS value;
```
'
);
);
INSERT INTO sqlpage_function_parameters (
"function",
"index",
"name",
"description_md",
"type"
)
"function",
"index",
"name",
"description_md",
"type"
)
VALUES (
'random_string',
1,
'length',
'The length of the string to generate.',
'INTEGER'
);
'random_string',
1,
'length',
'The length of the string to generate.',
'INTEGER'
);
INSERT INTO sqlpage_functions (
"name",
"introduced_in_version",
"icon",
"description_md"
)
VALUES (
'current_working_directory',
'0.11.0',
'folder-question',
'Returns the [current working directory](https://en.wikipedia.org/wiki/Working_directory) of the SQLPage server process.
### Example
```sql
SELECT ''text'' AS component;
SELECT ''Currently running from '' AS contents;
SELECT sqlpage.current_working_directory() as contents, true as code;
```
#### Result
Currently running from `/home/user/my_sqlpage_website`
#### Notes
The current working directory is the directory from which the SQLPage server process was started.
By default, this is also the directory from which `.sql` files are loaded and served.
However, this can be changed by setting the `web_root` [configuration option](https://github.com/lovasoa/SQLpage/blob/main/configuration.md).
');
16 changes: 11 additions & 5 deletions index.sql
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,17 @@ SELECT 'text' as component, -- We can switch to another component at any time ju
-- We are now inside the text component. Each row that will be returned by our SELECT queries will be a span of text
-- The text component has a property called "contents" that can be that we use to set the contents of our block of text
-- and a property called "center" that we use to center the text
SELECT 'In order to get started ' as contents;
select 'visit SQLPage''s website' as contents,
SELECT 'In order to get started, visit ' as contents;
select 'SQLPage''s website' as contents,
'https://sql.ophir.dev/your-first-sql-website/' as link,
true as italics;
SELECT '. You can replace this page''s contents by creating a file named ' as contents;
SELECT 'index.sql' as contents, true as italics;
SELECT ' in the folder where sqlpage is running. ' as contents;
SELECT 'Alternatively, you can create a table called sqlpage_files in your database with the following columns: path, contents, and last_modified.' as contents;
SELECT 'index.sql' as contents, 1 as code;
SELECT ' in the folder where sqlpage is running (current working directory: ' as contents;
SELECT sqlpage.current_working_directory() as contents, 1 as code;
SELECT ').' as contents;
SELECT 'You can customize your server''s [configuration](https://github.com/lovasoa/SQLpage/blob/main/configuration.md)
by creating a file in `' || sqlpage.current_working_directory() || '/sqlpage/sqlpage.json`.' as contents_md;

SELECT '
Alternatively, you can create a table called `sqlpage_files` in your database with the following columns: `path`, `contents`, and `last_modified`.' as contents_md;
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ async fn start() -> anyhow::Result<()> {
let app_config = app_config::load()?;
log::debug!("Starting with the following configuration: {app_config:?}");
let state = AppState::init(&app_config).await?;
webserver::apply_migrations(&state.db, &app_config.web_root).await?;
webserver::apply_migrations(&state.db).await?;
let listen_on = app_config.listen_on;
log::info!("Starting server on {}", listen_on);
let config = Config { listen_on };
Expand Down
11 changes: 6 additions & 5 deletions src/webserver/database/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use futures_util::StreamExt;
use serde_json::Value;
use std::borrow::Cow;
use std::fmt::{Display, Formatter};
use std::path::Path;
use std::time::Duration;

use crate::app_config::AppConfig;
Expand Down Expand Up @@ -47,16 +46,18 @@ impl Database {
}
}

pub async fn apply_migrations(db: &Database, web_root: &Path) -> anyhow::Result<()> {
let migrations_dir = web_root.join(MIGRATIONS_DIR);
pub async fn apply_migrations(db: &Database) -> anyhow::Result<()> {
let migrations_dir = std::env::current_dir()
.unwrap_or_default()
.join(MIGRATIONS_DIR);
if !migrations_dir.exists() {
log::info!(
"Not applying database migrations because '{}' does not exist",
MIGRATIONS_DIR
migrations_dir.display()
);
return Ok(());
}
log::info!("Applying migrations from '{MIGRATIONS_DIR}'");
log::info!("Applying migrations from '{}'", migrations_dir.display());
let migrator = Migrator::new(migrations_dir)
.await
.with_context(|| migration_err("preparing the database migration"))?;
Expand Down
9 changes: 9 additions & 0 deletions src/webserver/database/sql_pseudofunctions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub(super) enum StmtParam {
BasicAuthUsername,
HashPassword(Box<StmtParam>),
RandomString(usize),
CurrentWorkingDir,
}

pub(super) fn func_call_to_param(func_name: &str, arguments: &mut [FunctionArg]) -> StmtParam {
Expand All @@ -41,6 +42,7 @@ pub(super) fn func_call_to_param(func_name: &str, arguments: &mut [FunctionArg])
.map_or_else(StmtParam::Error, StmtParam::HashPassword),
"random_string" => extract_integer("random_string", arguments)
.map_or_else(StmtParam::Error, StmtParam::RandomString),
"current_working_directory" => StmtParam::CurrentWorkingDir,
unknown_name => StmtParam::Error(format!(
"Unknown function {unknown_name}({})",
FormatArguments(arguments)
Expand Down Expand Up @@ -72,6 +74,7 @@ pub(super) fn extract_req_param<'a>(
StmtParam::HashPassword(inner) => extract_req_param(inner, request)?
.map_or(Ok(None), |x| hash_password(&x).map(Cow::Owned).map(Some))?,
StmtParam::RandomString(len) => Some(Cow::Owned(random_string(*len))),
StmtParam::CurrentWorkingDir => cwd()?,
})
}

Expand Down Expand Up @@ -118,3 +121,9 @@ fn extract_basic_auth(request: &RequestInfo) -> anyhow::Result<&Basic> {
})
.with_context(|| "Expected the user to be authenticated with HTTP basic auth")
}

fn cwd() -> anyhow::Result<Option<Cow<'static, str>>> {
let cwd = std::env::current_dir()
.with_context(|| "unable to access the current working directory")?;
Ok(Some(Cow::Owned(cwd.to_string_lossy().to_string())))
}

0 comments on commit 69a1aab

Please sign in to comment.