diff --git a/DOCUMENTATION/DEVELOPERS/database/database.pdf b/DOCUMENTATION/DEVELOPERS/database/database.pdf
deleted file mode 100644
index f92649aaa0..0000000000
Binary files a/DOCUMENTATION/DEVELOPERS/database/database.pdf and /dev/null differ
diff --git a/bin/generate_entity_diagrams b/bin/generate_entity_diagrams
index aec74527e0..e78e04f9c4 100755
--- a/bin/generate_entity_diagrams
+++ b/bin/generate_entity_diagrams
@@ -1,4 +1,4 @@
-#!/usr/local/bin/php
+#!/usr/bin/env php
$table, 'type' => '']];
foreach ($schema['fields'] as $name => $opts) {
$fields[] = [
@@ -39,14 +48,11 @@ foreach ($files as $file) {
];
}
- if (isset($schema['foreign keys'])) {
- foreach ($schema['foreign keys'] as $name => $map) {
- // Patern matching like above would be nice
- list($foreign_table,
- $keys) = $map;
- $local_key = array_keys($keys)[0];
- $foreign_key = $keys[$local_key];
- $edges[] = "{$table}:{$local_key} -- {$foreign_table}:{$foreign_key}";
+ foreach ($schema['fields'] as $field => $opts) {
+ if (isset($opts['foreign key'])) {
+ [$foreign_entity, $foreign_key] = explode('.', $opts['target']);
+ $foreign_table = Formatting::camelCaseToSnakeCase(preg_replace('/GSActor/', 'gsactor', $foreign_entity));
+ $edges[] = "{$table}:{$field} -- {$foreign_table}:{$foreign_key}";
}
}
@@ -59,12 +65,12 @@ foreach ($files as $file) {
F\map($fields, $cell)),
];
- $tables[] = Common::indent("{$table} [shape=none, label=<\n" . Common::indent(H::html($html)) . "\n>]");
+ $tables[] = Formatting::indent("{$table} [shape=none, label=<\n" . Formatting::indent(H::html($html)) . "\n>]");
}
$replace = [
- '/%tables%/' => Common::indent(implode("\n", $tables)),
- '/%edges%/' => Common::indent(implode("\n", $edges)),
+ '/%tables%/' => Formatting::indent(implode("\n", $tables)),
+ '/%edges%/' => Formatting::indent(implode("\n", $edges)),
// '/_/' => '\textunderscore ',
];
@@ -73,7 +79,7 @@ foreach ($replace as $from => $to) {
$out = preg_replace($from, $to, $out);
}
-$path = dirname(__DIR__) . '/DOCUMENTATION/database';
+$path = dirname(__DIR__) . '/docs/developer/src/database';
$outfile = $path . '/database.dot';
file_put_contents($outfile, $out);
diff --git a/docs/developer/src/SUMMARY.md b/docs/developer/src/SUMMARY.md
index 07333c23a3..c3145bb6c0 100644
--- a/docs/developer/src/SUMMARY.md
+++ b/docs/developer/src/SUMMARY.md
@@ -2,6 +2,7 @@
- [High level view](./high_level.md)
- [Architecture and Paradigms](./architecture.md)
+- [Database](./database.md)
- [Plugins](./plugins.md)
- [Event Handlers](./plugins/no_docker_shell.md)
- [Installation](./plugins/docker_web.md)
diff --git a/docs/developer/src/database.md b/docs/developer/src/database.md
new file mode 100644
index 0000000000..8e972133a5
--- /dev/null
+++ b/docs/developer/src/database.md
@@ -0,0 +1,3 @@
+# Database
+
+Checkout a visual diagram of the database tables at docs/developer/src/database/database.pdf
diff --git a/docs/developer/src/database/database.dot b/docs/developer/src/database/database.dot
new file mode 100644
index 0000000000..645c1053c6
--- /dev/null
+++ b/docs/developer/src/database/database.dot
@@ -0,0 +1,1525 @@
+
+graph database {
+
+ activity [shape=none, label=<
+
+
+
+ activity
+ |
+
+
+
+ id: serial
+ |
+
+
+
+ gsactor_id: int
+ |
+
+
+
+ verb: varchar(32)
+ |
+
+
+
+ object_type: varchar(32)
+ |
+
+
+
+ object_id: int
+ |
+
+
+
+ is_local: bool
+ |
+
+
+
+ source: varchar(32)
+ |
+
+
+
+ created: datetime
+ |
+
+
+ >]
+ attachment [shape=none, label=<
+
+
+
+ attachment
+ |
+
+
+
+ id: serial
+ |
+
+
+
+ remote_url: text
+ |
+
+
+
+ remote_url_hash: varchar(64)
+ |
+
+
+
+ file_hash: varchar(64)
+ |
+
+
+
+ gsactor_id: int
+ |
+
+
+
+ mimetype: varchar(50)
+ |
+
+
+
+ title: text
+ |
+
+
+
+ filename: varchar(191)
+ |
+
+
+
+ is_local: bool
+ |
+
+
+
+ source: int
+ |
+
+
+
+ scope: int
+ |
+
+
+
+ size: int
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ attachment_thumbnail [shape=none, label=<
+
+
+
+ attachment_thumbnail
+ |
+
+
+
+ attachment_id: int
+ |
+
+
+
+ width: int
+ |
+
+
+
+ height: int
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ attachment_to_note [shape=none, label=<
+
+
+
+ attachment_to_note
+ |
+
+
+
+ attachment_id: int
+ |
+
+
+
+ note_id: int
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ avatar [shape=none, label=<
+
+
+
+ avatar
+ |
+
+
+
+ gsactor_id: int
+ |
+
+
+
+ attachment_id: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ confirm_address [shape=none, label=<
+
+
+
+ confirm_address
+ |
+
+
+
+ code: varchar(32)
+ |
+
+
+
+ user_id: int
+ |
+
+
+
+ address: varchar(191)
+ |
+
+
+
+ address_extra: varchar(191)
+ |
+
+
+
+ address_type: varchar(8)
+ |
+
+
+
+ claimed: datetime
+ |
+
+
+
+ sent: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ conversation [shape=none, label=<
+
+
+
+ conversation
+ |
+
+
+
+ id: serial
+ |
+
+
+
+ note_id: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ cover [shape=none, label=<
+
+
+
+ cover
+ |
+
+
+
+ gsactor_id: int
+ |
+
+
+
+ attachment_id: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ follow [shape=none, label=<
+
+
+
+ follow
+ |
+
+
+
+ follower: int
+ |
+
+
+
+ followed: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ follow_queue [shape=none, label=<
+
+
+
+ follow_queue
+ |
+
+
+
+ follower: int
+ |
+
+
+
+ followed: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+ >]
+ gsactor [shape=none, label=<
+
+
+
+ gsactor
+ |
+
+
+
+ id: serial
+ |
+
+
+
+ nickname: varchar(64)
+ |
+
+
+
+ fullname: text
+ |
+
+
+
+ roles: int
+ |
+
+
+
+ homepage: text
+ |
+
+
+
+ bio: text
+ |
+
+
+
+ location: text
+ |
+
+
+
+ lat: numeric
+ |
+
+
+
+ lon: numeric
+ |
+
+
+
+ location_id: int
+ |
+
+
+
+ location_service: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ gsactor_block [shape=none, label=<
+
+
+
+ gsactor_block
+ |
+
+
+
+ blocker: int
+ |
+
+
+
+ blocked: int
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ gsactor_circle [shape=none, label=<
+
+
+
+ gsactor_circle
+ |
+
+
+
+ tagger: int
+ |
+
+
+
+ tag: varchar(64)
+ |
+
+
+
+ description: text
+ |
+
+
+
+ private: bool
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ gsactor_tag [shape=none, label=<
+
+
+
+ gsactor_tag
+ |
+
+
+
+ tagger: int
+ |
+
+
+
+ tagged: int
+ |
+
+
+
+ tag: varchar(64)
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ gsactor_tag_follow [shape=none, label=<
+
+
+
+ gsactor_tag_follow
+ |
+
+
+
+ gsactor_id: int
+ |
+
+
+
+ gsactor_tag: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ group [shape=none, label=<
+
+
+
+ group
+ |
+
+
+
+ id: serial
+ |
+
+
+
+ gsactor_id: int
+ |
+
+
+
+ nickname: varchar(64)
+ |
+
+
+
+ fullname: varchar(191)
+ |
+
+
+
+ homepage: varchar(191)
+ |
+
+
+
+ description: text
+ |
+
+
+
+ is_local: bool
+ |
+
+
+
+ location: varchar(191)
+ |
+
+
+
+ original_logo: varchar(191)
+ |
+
+
+
+ homepage_logo: varchar(191)
+ |
+
+
+
+ stream_logo: varchar(191)
+ |
+
+
+
+ mini_logo: varchar(191)
+ |
+
+
+
+ uri: varchar(191)
+ |
+
+
+
+ mainpage: varchar(191)
+ |
+
+
+
+ join_policy: int
+ |
+
+
+
+ force_scope: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ group_alias [shape=none, label=<
+
+
+
+ group_alias
+ |
+
+
+
+ alias: varchar(64)
+ |
+
+
+
+ group_id: int
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ group_block [shape=none, label=<
+
+
+
+ group_block
+ |
+
+
+
+ group_id: int
+ |
+
+
+
+ blocked_gsactor: int
+ |
+
+
+
+ blocker_user: int
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ group_inbox [shape=none, label=<
+
+
+
+ group_inbox
+ |
+
+
+
+ group_id: int
+ |
+
+
+
+ activity_id: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+ >]
+ group_join_queue [shape=none, label=<
+
+
+
+ group_join_queue
+ |
+
+
+
+ gsactor_id: int
+ |
+
+
+
+ group_id: int
+ |
+
+
+ >]
+ group_member [shape=none, label=<
+
+
+
+ group_member
+ |
+
+
+
+ group_id: int
+ |
+
+
+
+ gsactor_id: int
+ |
+
+
+
+ is_admin: bool
+ |
+
+
+
+ uri: varchar(191)
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ invitation [shape=none, label=<
+
+
+
+ invitation
+ |
+
+
+
+ code: varchar(32)
+ |
+
+
+
+ user_id: int
+ |
+
+
+
+ address: varchar(191)
+ |
+
+
+
+ address_type: varchar(8)
+ |
+
+
+
+ registered_user_id: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+ >]
+ local_group [shape=none, label=<
+
+
+
+ local_group
+ |
+
+
+
+ group_id: int
+ |
+
+
+
+ nickname: varchar(64)
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: datetime
+ |
+
+
+ >]
+ local_user [shape=none, label=<
+
+
+
+ local_user
+ |
+
+
+
+ id: int
+ |
+
+
+
+ nickname: varchar(64)
+ |
+
+
+
+ password: varchar(191)
+ |
+
+
+
+ outgoing_email: varchar(191)
+ |
+
+
+
+ incoming_email: varchar(191)
+ |
+
+
+
+ is_email_verified: bool
+ |
+
+
+
+ language: varchar(50)
+ |
+
+
+
+ timezone: varchar(50)
+ |
+
+
+
+ phone_number: phone_number
+ |
+
+
+
+ sms_carrier: int
+ |
+
+
+
+ sms_email: varchar(191)
+ |
+
+
+
+ uri: varchar(191)
+ |
+
+
+
+ auto_follow_back: bool
+ |
+
+
+
+ follow_policy: int
+ |
+
+
+
+ is_stream_private: bool
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ location_service [shape=none, label=<
+
+
+
+ location_service
+ |
+
+
+
+ id: int
+ |
+
+
+
+ description: varchar(191)
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ note [shape=none, label=<
+
+
+
+ note
+ |
+
+
+
+ id: serial
+ |
+
+
+
+ gsactor_id: int
+ |
+
+
+
+ content: text
+ |
+
+
+
+ rendered: text
+ |
+
+
+
+ reply_to: int
+ |
+
+
+
+ is_local: bool
+ |
+
+
+
+ source: varchar(32)
+ |
+
+
+
+ conversation: int
+ |
+
+
+
+ repeat_of: int
+ |
+
+
+
+ scope: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ activity_location [shape=none, label=<
+
+
+
+ activity_location
+ |
+
+
+
+ note_id: int
+ |
+
+
+
+ lat: numeric
+ |
+
+
+
+ lon: numeric
+ |
+
+
+
+ location_id: int
+ |
+
+
+
+ location_service: int
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ note_source [shape=none, label=<
+
+
+
+ note_source
+ |
+
+
+
+ code: varchar(32)
+ |
+
+
+
+ name: varchar(191)
+ |
+
+
+
+ url: varchar(191)
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ note_tag [shape=none, label=<
+
+
+
+ note_tag
+ |
+
+
+
+ tag: varchar(64)
+ |
+
+
+
+ note_id: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+ >]
+ notification [shape=none, label=<
+
+
+
+ notification
+ |
+
+
+
+ activity_id: int
+ |
+
+
+
+ gsactor_id: int
+ |
+
+
+
+ reason: varchar(191)
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ profile_color [shape=none, label=<
+
+
+
+ profile_color
+ |
+
+
+
+ gsactor_id: int
+ |
+
+
+
+ color: text
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ related_group [shape=none, label=<
+
+
+
+ related_group
+ |
+
+
+
+ group_id: int
+ |
+
+
+
+ related_group_id: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+ >]
+ rememberme_token [shape=none, label=<
+
+
+
+ rememberme_token
+ |
+
+
+
+ series: char
+ |
+
+
+
+ value: char
+ |
+
+
+
+ lastused: datetime
+ |
+
+
+
+ class: varchar(100)
+ |
+
+
+
+ username: varchar(64)
+ |
+
+
+ >]
+ reserved_nickname [shape=none, label=<
+
+
+
+ reserved_nickname
+ |
+
+
+
+ nickname: varchar(64)
+ |
+
+
+
+ created: datetime
+ |
+
+
+ >]
+ sms_carrier [shape=none, label=<
+
+
+
+ sms_carrier
+ |
+
+
+
+ id: int
+ |
+
+
+
+ name: varchar(64)
+ |
+
+
+
+ email_pattern: varchar(191)
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ user_location_prefs [shape=none, label=<
+
+
+
+ user_location_prefs
+ |
+
+
+
+ user_id: int
+ |
+
+
+
+ share_location: bool
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ user_notification_prefs [shape=none, label=<
+
+
+
+ user_notification_prefs
+ |
+
+
+
+ user_id: int
+ |
+
+
+
+ transport: varchar(191)
+ |
+
+
+
+ target_gsactor_id: int
+ |
+
+
+
+ activity_by_followed: bool
+ |
+
+
+
+ mention: bool
+ |
+
+
+
+ reply: bool
+ |
+
+
+
+ follow: bool
+ |
+
+
+
+ favorite: bool
+ |
+
+
+
+ nudge: bool
+ |
+
+
+
+ dm: bool
+ |
+
+
+
+ post_on_status_change: bool
+ |
+
+
+
+ enable_posting: bool
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+ user_url_shortener_prefs [shape=none, label=<
+
+
+
+ user_url_shortener_prefs
+ |
+
+
+
+ user_id: int
+ |
+
+
+
+ url_shortening_service: varchar(50)
+ |
+
+
+
+ max_url_length: int
+ |
+
+
+
+ max_notice_length: int
+ |
+
+
+
+ created: datetime
+ |
+
+
+
+ modified: timestamp
+ |
+
+
+ >]
+
+ attachment:gsactor_id -- gsactor:id
+ attachment_thumbnail:attachment_id -- attachment:id
+ attachment_to_note:attachment_id -- attachment:id
+ attachment_to_note:note_id -- note:id
+ avatar:gsactor_id -- gsactor:id
+ avatar:attachment_id -- attachment:id
+ confirm_address:user_id -- local_user:id
+ conversation:note_id -- note:id
+ cover:gsactor_id -- gsactor:id
+ cover:attachment_id -- attachment:id
+ follow:follower -- gsactor:id
+ follow:followed -- gsactor:id
+ follow_queue:follower -- gsactor:id
+ follow_queue:followed -- gsactor:id
+ gsactor_block:blocker -- gsactor:id
+ gsactor_block:blocked -- gsactor:id
+ gsactor_circle:tagger -- gsactor:id
+ gsactor_tag:tagger -- gsactor:id
+ gsactor_tag:tagged -- gsactor:id
+ gsactor_tag_follow:gsactor_id -- gsactor:id
+ group:gsactor_id -- gsactor:id
+ group_alias:group_id -- group:id
+ group_block:group_id -- group:id
+ group_block:blocked_gsactor -- gsactor:id
+ group_block:blocker_user -- local_user:id
+ group_inbox:group_id -- group:id
+ group_inbox:activity_id -- activity:id
+ group_join_queue:gsactor_id -- gsactor:id
+ group_join_queue:group_id -- group:id
+ group_member:group_id -- group:id
+ group_member:gsactor_id -- gsactor:id
+ invitation:user_id -- local_user:id
+ invitation:registered_user_id -- local_user:id
+ local_group:group_id -- group:id
+ local_user:id -- gsactor:id
+ local_user:sms_carrier -- sms_carrier:id
+ note:gsactor_id -- gsactor:id
+ note:reply_to -- note:id
+ note:source -- note_source:code
+ note:conversation -- conversation:id
+ note:repeat_of -- note:id
+ activity_location:note_id -- note:id
+ note_tag:note_id -- note:id
+ notification:activity_id -- activity:id
+ notification:gsactor_id -- gsactor:id
+ profile_color:gsactor_id -- gsactor:id
+ related_group:group_id -- group:id
+ related_group:related_group_id -- group:id
+ user_location_prefs:user_id -- local_user:id
+ user_notification_prefs:user_id -- local_user:id
+ user_notification_prefs:target_gsactor_id -- gsactor:id
+ user_url_shortener_prefs:user_id -- local_user:id
+
+}
diff --git a/docs/developer/src/database/database.pdf b/docs/developer/src/database/database.pdf
new file mode 100644
index 0000000000..1c2502883b
Binary files /dev/null and b/docs/developer/src/database/database.pdf differ