{"id":19502493,"url":"https://github.com/shuber/postgres-twitter","last_synced_at":"2025-02-25T21:42:27.173Z","repository":{"id":31739723,"uuid":"35305748","full_name":"shuber/postgres-twitter","owner":"shuber","description":"Experimental build of a simple \"twitter\" app in Postgres","archived":false,"fork":false,"pushed_at":"2015-06-11T02:36:26.000Z","size":392,"stargazers_count":58,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-08T10:29:53.561Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PLpgSQL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shuber.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-08T22:52:12.000Z","updated_at":"2024-11-05T02:35:40.000Z","dependencies_parsed_at":"2022-08-29T16:00:38.472Z","dependency_job_id":null,"html_url":"https://github.com/shuber/postgres-twitter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuber%2Fpostgres-twitter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuber%2Fpostgres-twitter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuber%2Fpostgres-twitter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shuber%2Fpostgres-twitter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shuber","download_url":"https://codeload.github.com/shuber/postgres-twitter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240754292,"owners_count":19852185,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T22:16:34.519Z","updated_at":"2025-02-25T21:42:27.091Z","avatar_url":"https://github.com/shuber.png","language":"PLpgSQL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Postgres Twitter\n\nThis is an experimental build of a simple \"twitter\" application in Postgres. The goal is to push as much logic into the database as possible. This includes contraints, validations, functions, and triggers!\n\n## Schema\n\n\u003cimg src=\"https://raw.githubusercontent.com/shuber/postgres-twitter/master/schema.png\" /\u003e\n\n## Development\n\n* I'm using the [dbext] VIM plugin for [splitscreen] SQL and executed results.\n* I use the binding `\u003cleader\u003esee` to execute all statements in the buffer. (Sql Execute Everything)\n\n[dbext]: https://github.com/vim-scripts/dbext.vim\n[splitscreen]: https://www.dropbox.com/s/220z2nd5qdizho0/Screenshot%202015-05-08%2023.55.47.png?dl=0\n\n\n## Organization\n\nThe `compile` executable combines all files under sql/ into `compiled.sql` or `development.sql`.\n\n    bin/\n      compile\n    sql/\n      000_development.sql\n      001_schemas.sql\n      002_extensions.sql\n      003_functions.sql\n      004_trigger_functions.sql\n      005_behaviors.sql\n      006_tables.sql\n      007_views.sql\n      008_constraints.sql\n      009_indexes.sql\n      010_triggers.sql\n      999_development.sql\n    test/\n\n\n## Todo\n\n* [ ] seed database from twitter stream\n* [x] favorites\n* [x] followers\n* [x] mentions\n* [x] replies\n* [x] retweets\n* [x] tags\n* [x] tweets\n* [x] users\n\n\n## Sample Input\n\n    INSERT INTO users (username) VALUES\n      ('bob'),\n      ('doug'),\n      ('jane'),\n      ('steve'),\n      ('tom');\n\n    INSERT INTO tweets (post, user_id) VALUES\n      ('My first tweet!', random_user_id()),\n      ('Another tweet with a tag! #hello-world @missing', random_user_id()),\n      ('My second tweet! #hello-world #hello-world-again', random_user_id()),\n      ('Is anyone else hungry? #imHUNGRY #gimmefood @TOM @jane', random_user_id()),\n      ('@steve hola!', random_user_id()),\n      ('@bob I am! #imhungry #metoo #gimmefood #now', random_user_id());\n\n    INSERT INTO favorites (user_id, tweet_id)\n    SELECT id as user_id, random_tweet_id() as tweet_id\n    FROM users;\n\n    INSERT INTO followers (follower_id, user_id)\n    SELECT id as follower_id, random_user_id(id) as user_id\n    FROM users;\n\n    INSERT INTO replies (tweet_id, reply_id)\n    SELECT id as tweet_id, random_tweet_id(id) as reply_id\n    FROM tweets\n    LIMIT 2;\n\n    INSERT INTO retweets (tweet_id, retweet_id)\n    SELECT id as tweet_id, random_tweet_id(id) as retweet_id\n    FROM tweets\n    LIMIT 2;\n\n\n## Sample Queries\n\n    SELECT id, username, followers, following, favorites, mentions, tweets FROM users;\n    SELECT * FROM mentions;\n\n    -------------------------------------------------------------------------------\n\n    SELECT username, tweets.favorites, replies, retweets, tweets.mentions, tags\n    FROM tweets JOIN users on tweets.user_id = users.id;\n\n    DELETE FROM tweets\n    WHERE id IN (\n      SELECT t.id\n      FROM tweets t\n      ORDER BY random()\n      LIMIT 1\n    );\n\n    UPDATE tweets\n    SET post = 'replaced!'\n    WHERE id IN (\n      SELECT t.id\n      FROM tweets t\n      ORDER BY random()\n      LIMIT 1\n    );\n\n    SELECT username, tweets.favorites, replies, retweets, tweets.mentions, tags\n    FROM tweets JOIN users on tweets.user_id = users.id;\n\n    -------------------------------------------------------------------------------\n\n    SELECT * FROM taggings;\n    SELECT id, name, tweets FROM tags;\n\n\n## Sample Output\n\n    Connection: T(PGSQL)  D(twitter)  U(shuber)   at 12:52\n                      id                  | username | followers | following | favorites | mentions | tweets \n    --------------------------------------+----------+-----------+-----------+-----------+----------+--------\n     267ce9ac-c3df-4bf4-bbed-3aee28094a52 | doug     |         2 |         1 |         1 |        0 |      1\n     46c226b4-f26f-412c-a72f-9fe1b35da997 | bob      |         0 |         1 |         1 |        1 |      1\n     9d2860c9-a713-43e5-a384-c1b24b3d1c4d | tom      |         2 |         1 |         1 |        1 |      1\n     da1b62ea-c0bc-4f29-9d27-212144bc29c0 | jane     |         0 |         1 |         1 |        1 |      3\n     7bba5bea-d98b-4079-abea-fed05034dc6a | steve    |         1 |         1 |         1 |        1 |      0\n    (5 rows)\n                   user_id                |               tweet_id               \n    --------------------------------------+--------------------------------------\n     da1b62ea-c0bc-4f29-9d27-212144bc29c0 | 2d872de0-46cc-44aa-9aec-015fd5291c72\n     9d2860c9-a713-43e5-a384-c1b24b3d1c4d | 2d872de0-46cc-44aa-9aec-015fd5291c72\n     7bba5bea-d98b-4079-abea-fed05034dc6a | 1bab8cad-9cac-473d-a689-fbc710aaaea6\n     46c226b4-f26f-412c-a72f-9fe1b35da997 | 3bc21b9d-c778-4c64-84b8-798fd65072d8\n    (4 rows)\n     username | favorites | replies | retweets |  mentions  |              tags               \n    ----------+-----------+---------+----------+------------+---------------------------------\n     tom      |         1 |       0 |        0 | {}         | {hello-world,hello-world-again}\n     jane     |         2 |       0 |        0 | {bob}      | {gimmefood,imhungry,metoo,now}\n     doug     |         0 |       1 |        0 | {}         | {}\n     jane     |         0 |       1 |        0 | {steve}    | {}\n     jane     |         1 |       0 |        1 | {jane,tom} | {gimmefood,imhungry}\n     bob      |         1 |       0 |        1 | {missing}  | {hello-world}\n    (6 rows)\n     username | favorites | replies | retweets |  mentions  |              tags               \n    ----------+-----------+---------+----------+------------+---------------------------------\n     tom      |         1 |       0 |        0 | {}         | {hello-world,hello-world-again}\n     doug     |         0 |       1 |        0 | {}         | {}\n     jane     |         1 |       0 |        1 | {jane,tom} | {gimmefood,imhungry}\n     bob      |         1 |       0 |        1 | {missing}  | {hello-world}\n     jane     |         2 |       0 |        0 | {}         | {}\n    (5 rows)\n                    tag_id                |               tweet_id               \n    --------------------------------------+--------------------------------------\n     579e5a0f-5835-46ac-aced-528f8cd6e913 | 1d572544-8a84-4053-aef5-238260be3fa3\n     579e5a0f-5835-46ac-aced-528f8cd6e913 | 37421d41-416e-463d-9ad5-b9570f9356e8\n     0d86a554-0db2-4f60-8833-3d6bd6ed58af | 37421d41-416e-463d-9ad5-b9570f9356e8\n     c2620f3c-5a5c-4fa5-88f4-f01e2e12173e | 2d872de0-46cc-44aa-9aec-015fd5291c72\n     3efbea1c-3002-4b87-917b-d3ead6483983 | 2d872de0-46cc-44aa-9aec-015fd5291c72\n    (5 rows)\n                      id                  |       name        | tweets \n    --------------------------------------+-------------------+--------\n     579e5a0f-5835-46ac-aced-528f8cd6e913 | hello-world       |      2\n     0d86a554-0db2-4f60-8833-3d6bd6ed58af | hello-world-again |      1\n     c2620f3c-5a5c-4fa5-88f4-f01e2e12173e | gimmefood         |      1\n     3efbea1c-3002-4b87-917b-d3ead6483983 | imhungry          |      1\n    (4 rows)\n\n\n## Ideas for API\n\n#### The `random` schema\n\nThis is mostly for development. This object contains methods to return a random record from various tables. Also add `_id` suffixed versions of the methods to return a random record's primary key.\n\n* `random.tag()`\n* `random.tweet()`\n* `random.user()`\n\n#### The `tweets` schema\n\nPublic API for interacting with tweets\n\n* `tweets.create`\n* `tweets.delete`\n* `tweets.find`\n* `tweets.for_user`\n* `tweets.update`\n\nPublic API for interacting with tags\n\n* `tags.find_or_create(name text)`\n* `tags.listen(names text[])`\n* `tags.tweets(names text[])`\n\nOr maybe put everything under the `api` schema\n\n* `api.create_reply(tweet_id uuid, post text, user_id uuid)`\n* `api.create_retweet(tweet_id uuid, post text, user_id uuid)`\n* `api.create_tweet(post text, user_id uuid)`\n* `api.delete_tweet(tweet_id uuid)`\n* `api.favorite_tweet(tweet_id uuid, user_id uuid)`\n* `api.unfavorite_tweet(tweet_id uuid, user_id uuid)`\n* `api.follow_user(user_id uuid, follower_id uuid)`\n* `api.unfollow_user(user_id uuid, follower_id uuid)`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshuber%2Fpostgres-twitter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshuber%2Fpostgres-twitter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshuber%2Fpostgres-twitter/lists"}