Skip to content

Commit

Permalink
initial commit: add docs site
Browse files Browse the repository at this point in the history
  • Loading branch information
tconbeer committed Sep 6, 2022
0 parents commit 8a5e4ed
Show file tree
Hide file tree
Showing 38 changed files with 30,159 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Dependencies
/node_modules

# Production
/build

# Generated files
.docusaurus
.cache-loader

# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# sqlfmt-docs

This is the documentation for [sqlfmt](https://github.com/tconbeer/sqlfmt), the dbt SQL autoformatter. It is hosted at https://docs.sqlfmt.com.

This website is built using [Docusaurus 2](https://docusaurus.io/).

### Installation

```
$ yarn
```

### Local Development

```
$ yarn start
```

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

### Build

```
$ yarn build
```

This command generates static content into the `build` directory and can be served using any static contents hosting service.

### Deployment

```
$ yarn deploy
```
3 changes: 3 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};
44 changes: 44 additions & 0 deletions blog/2029-05-29-long-blog-post.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
slug: long-blog-post
title: Long Blog Post
authors: ted
tags: [hello, docusaurus]
---

This is the summary of a very long blog post,

Use a `<!--` `truncate` `-->` comment to limit blog post size in the list view.

<!--truncate-->

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet
5 changes: 5 additions & 0 deletions blog/authors.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ted:
name: Ted Conbeer
title: Creator of sqlfmt
url: https://github.com/tconbeer
image_url: https://github.com/tconbeer.png
4 changes: 4 additions & 0 deletions docs/api/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "API Reference",
"position": 99
}
188 changes: 188 additions & 0 deletions docs/api/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# API Reference

The public API is defined in the `sqlfmt.api` module. Any breaking changes to the public API will be limited to new minor versions (`0.x.0`) and documented in the [CHANGELOG](https://github.com/tconbeer/sqlfmt/tree/main/CHANGELOG.md).

## `api.Mode`

`Mode` is an object (a dataclass) that encompasses all configuration for sqlfmt.

All of the other API functions expect a `Mode` as an argument. A `Mode` with
the default configuration can be instantiated with no arguments
(e.g., `mode = Mode()`). For more information on each option, see `sqlfmt --help`
(or the source in the `sqlfmt.cli` module).

```py
@dataclass
class Mode:
"""
A Mode is a container for all sqlfmt config, including formatting config and
report config
"""

SQL_EXTENSIONS: List[str] = field(default_factory=lambda: [".sql", ".sql.jinja"])
dialect_name: str = "polyglot"
line_length: int = 88
check: bool = False
diff: bool = False
exclude: List[str] = field(default_factory=list)
single_process: bool = False
no_jinjafmt: bool = False
reset_cache: bool = False
verbose: bool = False
quiet: bool = False
no_progressbar: bool = False
no_color: bool = False
force_color: bool = False
```

## `api.format_string`

The simplest way to format a query is to pass that query as a string to `api.format_string`.


```py
def format_string(source_string: str, mode: Mode) -> str:
"""
Takes a raw query string and a Mode as input, returns the formatted query
as a string, or raises a SqlfmtError if the string cannot be formatted
"""
```

Example:
```py
from sqlfmt.api import format_string
from sqfmt.mode import Mode
from sqlfmt.exception import SqlfmtError

mode = Mode()
query = "select 1"

try:
formatted_query = format_string(query, mode)
except SqlfmtError as e:
print(f"Oops!\n\n{e}")

assert formatted_query == "select 1\n"
```

## `api.run`

The CLI uses `api.run` to modify files on disk and produce the report that
gets printed to `stderr`. `api.run` catches `SqlfmtError` exceptions.

```py
def run(
files: Collection[Path],
mode: Mode,
callback: Optional[Callable[[Awaitable[SqlFormatResult]], None]] = None,
) -> Report:
"""
Runs sqlfmt on all files in Collection of Paths (files), using the specified Mode.
Modifies SQL files in place, by default. Check or diff Mode do not modify files,
they only create a Report.
If a callback is provided, will execute the callback after each file is formatted.
Returns a Report that can be queried or printed.
"""
```

Example:

```py
from pathlib import Path

from sqlfmt.api import run
from sqlfmt.mode import Mode

mode = Mode()

# these files need to exist
files = [
Path("/home/me/sql/one.sql"),
Path("/home/me/sql/two.sql"),
]

report = run(files, mode)
report.display_report()
```

## `api.get_matching_paths`

`api.run` expects a unique Collection of Paths that enumerates every individual file
to be formatted. To generate that Collection, you can use `api.get_matching_paths`:

```py
def get_matching_paths(paths: Iterable[Path], mode: Mode) -> Set[Path]:
"""
Takes an Iterable of Paths (files or directories) and a Mode as an input, and
returns a Set of unique paths to individual files that match the input paths
(or are contained in its directories) and are not excluded by the mode's exclude glob
"""
```

Example:

```py
from Pathlib import Path

from sqlfmt.api import run, get_matching_paths
from sqlfmt.mode import Mode

mode = Mode(exclude=["./do_not_format/**/*.sql"])

this_dir = Path(__file__).parent

# all SQL files nested under this directory, except
# those in the `do_not_format` directory
files = get_matching_paths([this_dir], mode)
report = run(files, mode)

report.display_report()
```

## `api.initialize_progress_bar`

The CLI uses `tqdm` to show a progess bar for long runs. Since by default `api.run`
uses multiple processes, we update the progress bar using a callback supplied
to `api.run`. This function is a convenience function to initialize the progress bar.

```py
def initialize_progress_bar(
total: int, mode: Mode, force_progress_bar: bool = False
) -> Tuple[tqdm, Callable[[Awaitable[SqlFormatResult]], None]]:
"""
Return a callable that can be used with api.run to display a progress bar
that updates after each file is formatted.
Pass force_progress_bar to enable the progress bar, even on non-TTY
terminals (this is handy for testing the progress bar).
"""
```

Example:

```py
from pathlib import Path

from sqlfmt.api import run, initialize_progress_bar
from sqlfmt.mode import Mode

mode = Mode()

# these files need to exist
files = [
Path("/home/me/sql/one.sql"),
Path("/home/me/sql/two.sql"),
]

progress_bar, progress_callback = api.initialize_progress_bar(
total=len(files), mode=mode
)

report = run(files, mode, callback=progress_callback)

progress_bar.close()
report.display_report()
```
4 changes: 4 additions & 0 deletions docs/dialects/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "SQL Dialects",
"position": 2
}
34 changes: 34 additions & 0 deletions docs/dialects/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Using sqlfmt with Different SQL Dialects

sqlfmt's rules are simple, which means it does not have to parse every single token in your query. This allows nearly all SQL dialects to be formatted using sqlfmt's default "polyglot" dialect.

## Polyglot

Using the polyglot dialect requires no configuration. The following dialects are supported by polyglot:

- PostgreSQL
- Snowflake SQL
- BigQuery Standard SQL
- Redshift
- MySQL
- SparkSQL
- DuckDB

Many other dialects will also work just fine, especially if they adhere closely to standard/ANSI SQL. If you dialect isn't formatting properly, please [open an issue](https://github.com/tconbeer/sqlfmt/issues/new/choose).

## ClickHouse

ClickHouse is case-sensitive where other dialects are not. By default, sqlfmt will lowercase all SQL keywords, database identifiers, aliases, etc. (basically anything that isn't quoted). This is bad for ClickHouse. To prevent the lowercasing of function names, database identifiers, and aliases, use the `--dialect clickhouse` option when running sqlfmt. For example,

```bash
$ sqlfmt . --dialect clickhouse
```

This can also be configured using the `pyproject.toml` file:

```toml
[tool.sqlfmt]
dialect = "clickhouse"
```

Note that with this option, sqlfmt will not lowercase **most** non-reserved keywords, even common ones like `sum` or `count`. See (and please join) [this discussion](https://github.com/tconbeer/sqlfmt/discussions/229) for more on this topic.
8 changes: 8 additions & 0 deletions docs/getting-started/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"label": "Getting Started",
"position": 1,
"link": {
"type": "generated-index",
"description": "If you have run a Python CLI app (like dbt core), it will only take you a few minutes to get started with sqlfmt."
}
}
34 changes: 34 additions & 0 deletions docs/getting-started/configuring-sqlfmt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
sidebar_position: 2
---

# Configuring sqlfmt

:::tip
You probably don't need to configure sqlfmt at all! sqlfmt supports nearly all SQL dialects without configuration, and doesn't require a jinja templater.
:::

sqlfmt's style is not configurable, except for the line length (the default is 88). To set the line length, use the `-l` or `--line-length` option. For example, to run sqlfmt with a line length of 99:

```bash
sqlfmt -l 99 .
```

sqlfmt's operation, however, is highly configurable using options at the command line. For a full list of options, type:
```bash
sqlfmt --help
```

## Using a `pyproject.toml` File

Any command-line option for sqlfmt can also be set in a `pyproject.toml` file, under a `[tool.sqlfmt]` section header. Options passed at the command line will override the settings in the config file.

sqlfmt will search for the `pyproject.toml` file using the `files` passed to it as arguments. It starts in the lowest (most specific) common parent directory to all the `files` and recurses up to the root directory. It will load settings from the first `pyproject.toml` file it finds in this search.

Example of a `pyproject.toml` file to run sqlfmt in `check` mode with a line length of 99:

```toml title=pyproject.toml
[tool.sqlfmt]
line_length = 99
check = true
```
Loading

0 comments on commit 8a5e4ed

Please sign in to comment.