diff --git a/content/language/internal/_dm_db_close.md b/content/language/internal/_dm_db_close.md
new file mode 100644
index 000000000..8abd5b7b2
--- /dev/null
+++ b/content/language/internal/_dm_db_close.md
@@ -0,0 +1,17 @@
++++
+title = "_dm_db_close"
+[[extra.args]]
+name = "db_obj"
+description = "An internal database object, db_conn or db_query"
+[extra.return]
+type = "num" # AUTOGEN SKIP
+description = "`TRUE` if the object was closed, otherwise `FALSE`"
+
+[extra]
+od_unimplemented = true # AUTOGEN FIELD
++++
+
+"Closes" the [`db_conn`](./_dm_db_new_con.md) or [`db_query`](./_dm_db_new_query.md), resetting the object to its initial state.
+
+It's important to ensure that `db_conn` instances always close their connection at the end of their lifetime,
+as failing to do so can cause hanging connections that are impossible to close.
\ No newline at end of file
diff --git a/content/language/internal/_dm_db_columns.md b/content/language/internal/_dm_db_columns.md
new file mode 100644
index 000000000..0a9a89c63
--- /dev/null
+++ b/content/language/internal/_dm_db_columns.md
@@ -0,0 +1,52 @@
++++
+title = "_dm_db_columns"
+[[extra.args]]
+name = "db_query"
+description = "A database query"
+[[extra.args]]
+name = "column_type"
+description = "Path that represents column data"
+[extra.return]
+type = "list" # AUTOGEN SKIP
+description = "An associative list of text keys to instance values"
+
+[extra]
+od_unimplemented = true # AUTOGEN FIELD
++++
+
+Once a query is [executed](./_dm_db_execute.md), the `db_query` can be used to create a list of names along with their column data, which is useful for iterating over a set of rows.
+
+Each entry will have the name of the column as the key and an instance of the provided path as the value.
+For example, the query:
+```sql
+SELECT `first_name`, `last_name`, `dob` IN `my_table`;
+```
+will create this list:
+```dm
+list(
+ "first_name" = new /column(...),
+ "last_name" = new /column(...),
+ "dob" = new /column(...),
+)
+```
+
+Each database instance is created with **index-based** arguments.
+The arguments that are provided will differ based on the database driver.
+
+## MySql
+```dm
+/column/New(
+ name, // column name
+ table, // also column name
+ position, // column index, 0-index (BYOND is 1-index)
+ type, // appears to always be 0
+ flag, // column definition flags
+ length, // appears to always be a huge number
+ max_length // appears to always be a huge number
+)
+```
+
+## SQLite
+```dm
+// TODO
+```
\ No newline at end of file
diff --git a/content/language/internal/_dm_db_connect.md b/content/language/internal/_dm_db_connect.md
new file mode 100644
index 000000000..98fa9afca
--- /dev/null
+++ b/content/language/internal/_dm_db_connect.md
@@ -0,0 +1,48 @@
++++
+title = "_dm_db_connect"
+[[extra.args]]
+name = "db_conn"
+description = "A database connection"
+[[extra.args]]
+name = "dsn"
+description = "The data source name (DSN) of the connection"
+[[extra.args]]
+name = "username"
+description = "Username for login credentials"
+[[extra.args]]
+name = "password"
+description = "Password for login credentials"
+[[extra.args]]
+name = "cursor_type"
+description = "Cursor type that the query will use"
+[[extra.args]]
+name = "?"
+description = "The purpose of this argument is unknown"
+[extra.return]
+type = "num" # AUTOGEN SKIP
+description = "`TRUE` if a connection was established successfully, otherwise `FALSE`"
+
+[extra]
+od_unimplemented = true # AUTOGEN FIELD
++++
+
+Establishes a remote connection to a database.
+
+The format for a DSN in BYOND is:
+```
+dbi:[driver]:[identifier]:[address]:[port]
+dbi:mysql:my_database:192.168.0.1:3306
+```
+
+Database drivers currently supported by BYOND:
+- MySQL (`mysql`)
+- SQLite (`unknown identifier`)
+
+{% parity() %}
+It is currently unknown if the database changes the values for `cursor_type`.
+{% end %}
+
+`cursor_type` changes how the query is handled:
+- `0` uses the database's default cursor behaviour.
+- `1` uses client cursor.
+- `2` uses server cursor.
\ No newline at end of file
diff --git a/content/language/internal/_dm_db_error_msg.md b/content/language/internal/_dm_db_error_msg.md
new file mode 100644
index 000000000..3f7287dc5
--- /dev/null
+++ b/content/language/internal/_dm_db_error_msg.md
@@ -0,0 +1,14 @@
++++
+title = "_dm_db_error_msg"
+[[extra.args]]
+name = "db_obj"
+description = "An internal database object, db_conn or db_query"
+[extra.return]
+type = "text" # AUTOGEN SKIP
+description = "The error given by the database object"
+
+[extra]
+od_unimplemented = true # AUTOGEN FIELD
++++
+
+If the provided object did not create an error during its previous action, the error message will be empty text. \(`""`\)
\ No newline at end of file
diff --git a/content/language/internal/_dm_db_execute.md b/content/language/internal/_dm_db_execute.md
new file mode 100644
index 000000000..53ef0a9a9
--- /dev/null
+++ b/content/language/internal/_dm_db_execute.md
@@ -0,0 +1,35 @@
++++
+title = "_dm_db_execute"
+[[extra.args]]
+name = "db_query"
+description = "A database query"
+[[extra.args]]
+name = "query"
+description = "The query being sent to the database"
+[[extra.args]]
+name = "db_conn"
+description = "A database connection"
+[[extra.args]]
+name = "cursor_type"
+description = "Cursor type that the query will use"
+[[extra.args]]
+name = "?"
+description = "The purpose of this argument is unknown"
+[extra.return]
+type = "num" # AUTOGEN SKIP
+description = "`TRUE` if the query executed successfully, otherwise `FALSE`"
+
+[extra]
+od_unimplemented = true # AUTOGEN FIELD
++++
+
+Performs a query on a [`db_conn`](./_dm_db_new_con.md) and stores the result in a [`db_query`](./_dm_db_new_query.md).
+
+{% parity() %}
+It is currently unknown if the database changes the values for `cursor_type`.
+{% end %}
+
+`cursor_type` changes how the query is handled:
+- `0` uses the database's default cursor behaviour.
+- `1` uses client cursor.
+- `2` uses server cursor.
\ No newline at end of file
diff --git a/content/language/internal/_dm_db_is_connected.md b/content/language/internal/_dm_db_is_connected.md
new file mode 100644
index 000000000..aedc427cf
--- /dev/null
+++ b/content/language/internal/_dm_db_is_connected.md
@@ -0,0 +1,12 @@
++++
+title = "_dm_db_is_connected"
+[[extra.args]]
+name = "db_conn"
+description = "A database connection"
+[extra.return]
+type = "num" # AUTOGEN SKIP
+description = "`TRUE` if a database connection is open, otherwise `FALSE`"
+
+[extra]
+od_unimplemented = true # AUTOGEN FIELD
++++
\ No newline at end of file
diff --git a/content/language/internal/_dm_db_new_con.md b/content/language/internal/_dm_db_new_con.md
new file mode 100644
index 000000000..5591f40dc
--- /dev/null
+++ b/content/language/internal/_dm_db_new_con.md
@@ -0,0 +1,15 @@
++++
+title = "_dm_db_new_con"
+[extra.return]
+type = "db_conn" # AUTOGEN SKIP
+description = "A new connection object"
+
+[extra]
+od_unimplemented = true # AUTOGEN FIELD
++++
+Creates and returns an internal object we call a `db_conn`.
+
+`db_conn` is a special data type, different from a {{ datum() }} but still treated as an object.
+It is used to perform database operations.
+
+{{ database() }} also internally creates a `db_conn`.
\ No newline at end of file
diff --git a/content/language/internal/_dm_db_new_query.md b/content/language/internal/_dm_db_new_query.md
new file mode 100644
index 000000000..e380cb62e
--- /dev/null
+++ b/content/language/internal/_dm_db_new_query.md
@@ -0,0 +1,13 @@
++++
+title = "_dm_db_new_query"
+[extra.return]
+type = "db_query" # AUTOGEN SKIP
+description = "A new query object"
+
+[extra]
+od_unimplemented = true # AUTOGEN FIELD
++++
+Creates and returns an internal object we call a `db_query`.
+
+`db_query` is a special data type, different from a {{ datum() }} but still treated as an object.
+It is used to store the results of a [query](./_dm_db_execute.md).
\ No newline at end of file
diff --git a/content/language/internal/_dm_db_next_row.md b/content/language/internal/_dm_db_next_row.md
new file mode 100644
index 000000000..30c28d7d0
--- /dev/null
+++ b/content/language/internal/_dm_db_next_row.md
@@ -0,0 +1,27 @@
++++
+title = "_dm_db_next_row"
+[[extra.args]]
+name = "db_query"
+description = "A database query"
+[[extra.args]]
+name = "items"
+description = "Container for the row items"
+[[extra.args]]
+name = "conversions"
+description = "A list"
+[extra.return]
+type = "num" # AUTOGEN SKIP
+description = "`TRUE` if another row was selected, otherwise `FALSE`"
+
+[extra]
+od_unimplemented = true # AUTOGEN FIELD
++++
+
+{% parity() %}
+Behaviour of `conversions` is currently unknown.
+{% end %}
+
+If possible, inserts the values of the next row into `items`.
+
+Calling this proc repeatedly will continue stepping through rows until there are no more rows in the selection.
+It is not possible to step backwards.
diff --git a/content/language/internal/_dm_db_quote.md b/content/language/internal/_dm_db_quote.md
new file mode 100644
index 000000000..b03833388
--- /dev/null
+++ b/content/language/internal/_dm_db_quote.md
@@ -0,0 +1,15 @@
++++
+title = "_dm_db_quote"
+[[extra.args]]
+name = "db_conn"
+description = "A database connection"
+[extra.return]
+type = "text" # AUTOGEN SKIP
+description = "Sanitized form of the input text"
+
+[extra]
+od_unimplemented = true # AUTOGEN FIELD
++++
+
+Asks the connection to escape the provided text (Ex: `this 'dangerous' text` to `this \\'dangerous\\' text`).
+Very important for treating user input, as it can prevent [malicious attacks](https://en.wikipedia.org/wiki/SQL_injection) on databases.
\ No newline at end of file
diff --git a/content/language/internal/_dm_db_row_count.md b/content/language/internal/_dm_db_row_count.md
new file mode 100644
index 000000000..294cbe6d7
--- /dev/null
+++ b/content/language/internal/_dm_db_row_count.md
@@ -0,0 +1,14 @@
++++
+title = "_dm_db_row_count"
+[[extra.args]]
+name = "db_query"
+description = "A database query"
+[extra.return]
+type = "num, null" # AUTOGEN SKIP
+description = "The number of rows, or `null` if not applicable"
+
+[extra]
+od_unimplemented = true # AUTOGEN FIELD
++++
+
+Returns the number of rows that were **found** by the query's execution.
\ No newline at end of file
diff --git a/content/language/internal/_dm_db_rows_affected.md b/content/language/internal/_dm_db_rows_affected.md
new file mode 100644
index 000000000..31730391b
--- /dev/null
+++ b/content/language/internal/_dm_db_rows_affected.md
@@ -0,0 +1,14 @@
++++
+title = "_dm_db_rows_affected"
+[[extra.args]]
+name = "db_query"
+description = "A database query"
+[extra.return]
+type = "num, null" # AUTOGEN SKIP
+description = "The number of rows, or `null` if not applicable"
+
+[extra]
+od_unimplemented = true # AUTOGEN FIELD
++++
+
+Returns the number of rows that were **altered** by the query's execution.
\ No newline at end of file
diff --git a/content/language/internal/_index.md b/content/language/internal/_index.md
new file mode 100644
index 000000000..d764dea5c
--- /dev/null
+++ b/content/language/internal/_index.md
@@ -0,0 +1,9 @@
++++
+title = "Internal Procs"
+weight = 0
+page_template = "proc.html"
++++
+{% parity() %}
+Because these are meant for internal use and undocumented,
+OpenDream's implementation of these procs may vary in accuracy.
+{% end %}
\ No newline at end of file
diff --git a/content/language/proc/_dm_db_close.md b/content/language/proc/_dm_db_close.md
deleted file mode 100644
index 8d58cbd75..000000000
--- a/content/language/proc/_dm_db_close.md
+++ /dev/null
@@ -1,7 +0,0 @@
-+++
-title = "_dm_db_close"
-render = false
-
-[extra]
-od_unimplemented = true # AUTOGEN FIELD
-+++
\ No newline at end of file
diff --git a/content/language/proc/_dm_db_columns.md b/content/language/proc/_dm_db_columns.md
deleted file mode 100644
index ee79df2d8..000000000
--- a/content/language/proc/_dm_db_columns.md
+++ /dev/null
@@ -1,7 +0,0 @@
-+++
-title = "_dm_db_columns"
-render = false
-
-[extra]
-od_unimplemented = true # AUTOGEN FIELD
-+++
\ No newline at end of file
diff --git a/content/language/proc/_dm_db_connect.md b/content/language/proc/_dm_db_connect.md
deleted file mode 100644
index f5258fa41..000000000
--- a/content/language/proc/_dm_db_connect.md
+++ /dev/null
@@ -1,7 +0,0 @@
-+++
-title = "_dm_db_connect"
-render = false
-
-[extra]
-od_unimplemented = true # AUTOGEN FIELD
-+++
\ No newline at end of file
diff --git a/content/language/proc/_dm_db_error_msg.md b/content/language/proc/_dm_db_error_msg.md
deleted file mode 100644
index c437e83b8..000000000
--- a/content/language/proc/_dm_db_error_msg.md
+++ /dev/null
@@ -1,7 +0,0 @@
-+++
-title = "_dm_db_error_msg"
-render = false
-
-[extra]
-od_unimplemented = true # AUTOGEN FIELD
-+++
\ No newline at end of file
diff --git a/content/language/proc/_dm_db_execute.md b/content/language/proc/_dm_db_execute.md
deleted file mode 100644
index dec3b3f5e..000000000
--- a/content/language/proc/_dm_db_execute.md
+++ /dev/null
@@ -1,7 +0,0 @@
-+++
-title = "_dm_db_execute"
-render = false
-
-[extra]
-od_unimplemented = true # AUTOGEN FIELD
-+++
\ No newline at end of file
diff --git a/content/language/proc/_dm_db_is_connected.md b/content/language/proc/_dm_db_is_connected.md
deleted file mode 100644
index 9af83509f..000000000
--- a/content/language/proc/_dm_db_is_connected.md
+++ /dev/null
@@ -1,7 +0,0 @@
-+++
-title = "_dm_db_is_connected"
-render = false
-
-[extra]
-od_unimplemented = true # AUTOGEN FIELD
-+++
\ No newline at end of file
diff --git a/content/language/proc/_dm_db_new_con.md b/content/language/proc/_dm_db_new_con.md
deleted file mode 100644
index 6cfb9aea8..000000000
--- a/content/language/proc/_dm_db_new_con.md
+++ /dev/null
@@ -1,7 +0,0 @@
-+++
-title = "_dm_db_new_con"
-render = false
-
-[extra]
-od_unimplemented = true # AUTOGEN FIELD
-+++
\ No newline at end of file
diff --git a/content/language/proc/_dm_db_new_query.md b/content/language/proc/_dm_db_new_query.md
deleted file mode 100644
index f8775fa19..000000000
--- a/content/language/proc/_dm_db_new_query.md
+++ /dev/null
@@ -1,7 +0,0 @@
-+++
-title = "_dm_db_new_query"
-render = false
-
-[extra]
-od_unimplemented = true # AUTOGEN FIELD
-+++
\ No newline at end of file
diff --git a/content/language/proc/_dm_db_next_row.md b/content/language/proc/_dm_db_next_row.md
deleted file mode 100644
index b7e90f4b3..000000000
--- a/content/language/proc/_dm_db_next_row.md
+++ /dev/null
@@ -1,7 +0,0 @@
-+++
-title = "_dm_db_next_row"
-render = false
-
-[extra]
-od_unimplemented = true # AUTOGEN FIELD
-+++
\ No newline at end of file
diff --git a/content/language/proc/_dm_db_quote.md b/content/language/proc/_dm_db_quote.md
deleted file mode 100644
index 102a1b0c2..000000000
--- a/content/language/proc/_dm_db_quote.md
+++ /dev/null
@@ -1,7 +0,0 @@
-+++
-title = "_dm_db_quote"
-render = false
-
-[extra]
-od_unimplemented = true # AUTOGEN FIELD
-+++
\ No newline at end of file
diff --git a/content/language/proc/_dm_db_row_count.md b/content/language/proc/_dm_db_row_count.md
deleted file mode 100644
index 9e2ad88c8..000000000
--- a/content/language/proc/_dm_db_row_count.md
+++ /dev/null
@@ -1,7 +0,0 @@
-+++
-title = "_dm_db_row_count"
-render = false
-
-[extra]
-od_unimplemented = true # AUTOGEN FIELD
-+++
\ No newline at end of file
diff --git a/content/language/proc/_dm_db_rows_affected.md b/content/language/proc/_dm_db_rows_affected.md
deleted file mode 100644
index f979c4f7c..000000000
--- a/content/language/proc/_dm_db_rows_affected.md
+++ /dev/null
@@ -1,7 +0,0 @@
-+++
-title = "_dm_db_rows_affected"
-render = false
-
-[extra]
-od_unimplemented = true # AUTOGEN FIELD
-+++
\ No newline at end of file
diff --git a/tools/OpenDreamDocumentationTool/OpenDreamDocumentationTool/OpenDreamDocumentationTool.csproj b/tools/OpenDreamDocumentationTool/OpenDreamDocumentationTool/OpenDreamDocumentationTool.csproj
index 860c7b09b..10bc04861 100644
--- a/tools/OpenDreamDocumentationTool/OpenDreamDocumentationTool/OpenDreamDocumentationTool.csproj
+++ b/tools/OpenDreamDocumentationTool/OpenDreamDocumentationTool/OpenDreamDocumentationTool.csproj
@@ -1,7 +1,7 @@
Exe
- net9.0
+ net10.0
enable
enable
diff --git a/tools/OpenDreamDocumentationTool/OpenDreamDocumentationTool/Program.cs b/tools/OpenDreamDocumentationTool/OpenDreamDocumentationTool/Program.cs
index 669946c73..8e139c990 100644
--- a/tools/OpenDreamDocumentationTool/OpenDreamDocumentationTool/Program.cs
+++ b/tools/OpenDreamDocumentationTool/OpenDreamDocumentationTool/Program.cs
@@ -110,6 +110,11 @@ public static void Main(string[] args) {
continue;
}
+ if (file.Contains("language/internal")) {
+ pathToFile["internalProcs"] = file;
+ continue;
+ }
+
if (!pageTitle.StartsWith('/')) {
continue;
}
@@ -120,10 +125,13 @@ public static void Main(string[] args) {
ParseAstStatements(astFile.BlockInner.Statements);
var globalProcs = pathToFile["globalProcs"];
+ var internalProcs = pathToFile["internalProcs"];
+
foreach (var pair in Procs) {
var proc = pair.Value;
+ var usedPath = !proc.Name.StartsWith("_dm_") ? globalProcs : internalProcs;
- var newProcPage = globalProcs.Replace("_index.md", $"{proc.Name.ToLower()}.md");
+ var newProcPage = usedPath.Replace("_index.md", $"{proc.Name.ToLower()}.md");
ProcessPage(newProcPage, proc, ProcessProc);
}