{"action":"closed","number":211,"pull_request":{"url":"https://api.github.com/repos/SnowflakePowered/snowflake/pulls/211","id":61511115,"html_url":"https://github.com/SnowflakePowered/snowflake/pull/211","diff_url":"https://github.com/SnowflakePowered/snowflake/pull/211.diff","patch_url":"https://github.com/SnowflakePowered/snowflake/pull/211.patch","issue_url":"https://api.github.com/repos/SnowflakePowered/snowflake/issues/211","number":211,"state":"closed","locked":false,"title":"BREAKING: Database rewrite and restructuring (Fixes #209)","user":{"login":"RonnChyran","id":1000503,"avatar_url":"https://avatars.githubusercontent.com/u/1000503?v=3","gravatar_id":"","url":"https://api.github.com/users/RonnChyran","html_url":"https://github.com/RonnChyran","followers_url":"https://api.github.com/users/RonnChyran/followers","following_url":"https://api.github.com/users/RonnChyran/following{/other_user}","gists_url":"https://api.github.com/users/RonnChyran/gists{/gist_id}","starred_url":"https://api.github.com/users/RonnChyran/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RonnChyran/subscriptions","organizations_url":"https://api.github.com/users/RonnChyran/orgs","repos_url":"https://api.github.com/users/RonnChyran/repos","events_url":"https://api.github.com/users/RonnChyran/events{/privacy}","received_events_url":"https://api.github.com/users/RonnChyran/received_events","type":"User","site_admin":false},"body":"This PR overhauls every database used by Snowflake to be backed by Dapper instead of using raw query objects. This PR also removes any `Thread.Sleep()` hacks to prevent threaded access of Sqlite, which is now mitigated correctly by Dapper.\r\n\r\n**SqliteKeyValueStore : ISimpleKeyValueStore**\r\nThis class provides a **synchronous** Key/Value store based off Akavache's method signatures. It does not use in-memory caching, and writes directly to and from the Sqlite database, and is essentially a string key value store. All objects are serialized with type information into JSON using JSON.NET, and deserialized on retrieval. This provides relatively fast access of about 250ms-500ms per record retrieval, which could be improved with transparent in-memory-caching in the future.\r\n\r\n**BaseDatabase -> SqliteDatabase**\r\nThis helper class has been renamed to better reflect it's usage, and moved to the Snowflake.Utility.dll assembly.\r\n\r\n**IControllerPortsDatabase -> IControllerPortStore**\r\n`IControllerPortsDatabase` and it's concrete implementation have been renamed to `IControllerPortStore`, and `ControllerPortStore` accordingly, without a change in API. It has been ported to use a `SqliteKeyValueStore` in the background to retrieve port data rather than database access queries.This breaks existing schema, so the database must be recreated.\r\n\r\n**IPlatformPreferenceDatabase -> IPlatformPreferenceStore**\r\n`IPlatformPreferenceDatabase` and it's concrete implementation have been renamed to `IPlatformPreferenceStore` and it's concrete implementation accordingly.  It has been ported to use a `SqliteKeyValueStore` in the background to retrieve preference data rather than database access queries. This breaks existing schema, so the database must be recreated.\r\n\r\n**IGamepadAbstractionDatabase -> IGamepadAbstractionStore**\r\n`IGamepadAbstractionDatabase` and it's concrete implementation have been renamed to `IGamepadAbstractionStore` and it's concrete implementation accordingly.  It has been ported to use a `SqliteKeyValueStore` in the background to retrieve GamepadAbstraction data rather than database access queries. This breaks existing schema, so the database must be recreated.\r\n\r\n**IGameDatabase -> IGameLibrary**\r\n`IGameDatabase` and it's concrete implementation have been renamed to `IGameLibrary`, and it's concrete implementation accordingly. Database access logic has been moved to `SqliteGameDatabase`, which is a cleaner implementation that accesses Sqlite using Dapper.net, while also removing any hacks and `DataRow` usage. The schema **does not** change with this change and still follows the Stone specification.","created_at":"2016-03-03T05:03:42Z","updated_at":"2016-03-11T00:01:29Z","closed_at":"2016-03-11T00:01:29Z","merged_at":"2016-03-11T00:01:29Z","merge_commit_sha":"6530629b56908096a09d1edd434fe0747e1afad1","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/SnowflakePowered/snowflake/pulls/211/commits","review_comments_url":"https://api.github.com/repos/SnowflakePowered/snowflake/pulls/211/comments","review_comment_url":"https://api.github.com/repos/SnowflakePowered/snowflake/pulls/comments{/number}","comments_url":"https://api.github.com/repos/SnowflakePowered/snowflake/issues/211/comments","statuses_url":"https://api.github.com/repos/SnowflakePowered/snowflake/statuses/810ef687e6dff1767659de0d30a533b9a6544c20","head":{"label":"RonnChyran:new-database","ref":"new-database","sha":"810ef687e6dff1767659de0d30a533b9a6544c20","user":{"login":"RonnChyran","id":1000503,"avatar_url":"https://avatars.githubusercontent.com/u/1000503?v=3","gravatar_id":"","url":"https://api.github.com/users/RonnChyran","html_url":"https://github.com/RonnChyran","followers_url":"https://api.github.com/users/RonnChyran/followers","following_url":"https://api.github.com/users/RonnChyran/following{/other_user}","gists_url":"https://api.github.com/users/RonnChyran/gists{/gist_id}","starred_url":"https://api.github.com/users/RonnChyran/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RonnChyran/subscriptions","organizations_url":"https://api.github.com/users/RonnChyran/orgs","repos_url":"https://api.github.com/users/RonnChyran/repos","events_url":"https://api.github.com/users/RonnChyran/events{/privacy}","received_events_url":"https://api.github.com/users/RonnChyran/received_events","type":"User","site_admin":false},"repo":{"id":29939948,"name":"snowflake","full_name":"RonnChyran/snowflake","owner":{"login":"RonnChyran","id":1000503,"avatar_url":"https://avatars.githubusercontent.com/u/1000503?v=3","gravatar_id":"","url":"https://api.github.com/users/RonnChyran","html_url":"https://github.com/RonnChyran","followers_url":"https://api.github.com/users/RonnChyran/followers","following_url":"https://api.github.com/users/RonnChyran/following{/other_user}","gists_url":"https://api.github.com/users/RonnChyran/gists{/gist_id}","starred_url":"https://api.github.com/users/RonnChyran/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RonnChyran/subscriptions","organizations_url":"https://api.github.com/users/RonnChyran/orgs","repos_url":"https://api.github.com/users/RonnChyran/repos","events_url":"https://api.github.com/users/RonnChyran/events{/privacy}","received_events_url":"https://api.github.com/users/RonnChyran/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/RonnChyran/snowflake","description":"Stone-compliant Extensible Emulator Frontend written in C# and Javascript","fork":true,"url":"https://api.github.com/repos/RonnChyran/snowflake","forks_url":"https://api.github.com/repos/RonnChyran/snowflake/forks","keys_url":"https://api.github.com/repos/RonnChyran/snowflake/keys{/key_id}","collaborators_url":"https://api.github.com/repos/RonnChyran/snowflake/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/RonnChyran/snowflake/teams","hooks_url":"https://api.github.com/repos/RonnChyran/snowflake/hooks","issue_events_url":"https://api.github.com/repos/RonnChyran/snowflake/issues/events{/number}","events_url":"https://api.github.com/repos/RonnChyran/snowflake/events","assignees_url":"https://api.github.com/repos/RonnChyran/snowflake/assignees{/user}","branches_url":"https://api.github.com/repos/RonnChyran/snowflake/branches{/branch}","tags_url":"https://api.github.com/repos/RonnChyran/snowflake/tags","blobs_url":"https://api.github.com/repos/RonnChyran/snowflake/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/RonnChyran/snowflake/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/RonnChyran/snowflake/git/refs{/sha}","trees_url":"https://api.github.com/repos/RonnChyran/snowflake/git/trees{/sha}","statuses_url":"https://api.github.com/repos/RonnChyran/snowflake/statuses/{sha}","languages_url":"https://api.github.com/repos/RonnChyran/snowflake/languages","stargazers_url":"https://api.github.com/repos/RonnChyran/snowflake/stargazers","contributors_url":"https://api.github.com/repos/RonnChyran/snowflake/contributors","subscribers_url":"https://api.github.com/repos/RonnChyran/snowflake/subscribers","subscription_url":"https://api.github.com/repos/RonnChyran/snowflake/subscription","commits_url":"https://api.github.com/repos/RonnChyran/snowflake/commits{/sha}","git_commits_url":"https://api.github.com/repos/RonnChyran/snowflake/git/commits{/sha}","comments_url":"https://api.github.com/repos/RonnChyran/snowflake/comments{/number}","issue_comment_url":"https://api.github.com/repos/RonnChyran/snowflake/issues/comments{/number}","contents_url":"https://api.github.com/repos/RonnChyran/snowflake/contents/{+path}","compare_url":"https://api.github.com/repos/RonnChyran/snowflake/compare/{base}...{head}","merges_url":"https://api.github.com/repos/RonnChyran/snowflake/merges","archive_url":"https://api.github.com/repos/RonnChyran/snowflake/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/RonnChyran/snowflake/downloads","issues_url":"https://api.github.com/repos/RonnChyran/snowflake/issues{/number}","pulls_url":"https://api.github.com/repos/RonnChyran/snowflake/pulls{/number}","milestones_url":"https://api.github.com/repos/RonnChyran/snowflake/milestones{/number}","notifications_url":"https://api.github.com/repos/RonnChyran/snowflake/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/RonnChyran/snowflake/labels{/name}","releases_url":"https://api.github.com/repos/RonnChyran/snowflake/releases{/id}","deployments_url":"https://api.github.com/repos/RonnChyran/snowflake/deployments","created_at":"2015-01-27T23:15:04Z","updated_at":"2016-01-18T03:05:30Z","pushed_at":"2016-03-10T23:19:28Z","git_url":"git://github.com/RonnChyran/snowflake.git","ssh_url":"git@github.com:RonnChyran/snowflake.git","clone_url":"https://github.com/RonnChyran/snowflake.git","svn_url":"https://github.com/RonnChyran/snowflake","homepage":"http://blog.ronnchyran.com/tagged/snowflake","size":164723,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"SnowflakePowered:master","ref":"master","sha":"0ea6fff2021b3ac1b7553a3be3139acfa3ab386e","user":{"login":"SnowflakePowered","id":8306662,"avatar_url":"https://avatars.githubusercontent.com/u/8306662?v=3","gravatar_id":"","url":"https://api.github.com/users/SnowflakePowered","html_url":"https://github.com/SnowflakePowered","followers_url":"https://api.github.com/users/SnowflakePowered/followers","following_url":"https://api.github.com/users/SnowflakePowered/following{/other_user}","gists_url":"https://api.github.com/users/SnowflakePowered/gists{/gist_id}","starred_url":"https://api.github.com/users/SnowflakePowered/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SnowflakePowered/subscriptions","organizations_url":"https://api.github.com/users/SnowflakePowered/orgs","repos_url":"https://api.github.com/users/SnowflakePowered/repos","events_url":"https://api.github.com/users/SnowflakePowered/events{/privacy}","received_events_url":"https://api.github.com/users/SnowflakePowered/received_events","type":"Organization","site_admin":false},"repo":{"id":21444864,"name":"snowflake","full_name":"SnowflakePowered/snowflake","owner":{"login":"SnowflakePowered","id":8306662,"avatar_url":"https://avatars.githubusercontent.com/u/8306662?v=3","gravatar_id":"","url":"https://api.github.com/users/SnowflakePowered","html_url":"https://github.com/SnowflakePowered","followers_url":"https://api.github.com/users/SnowflakePowered/followers","following_url":"https://api.github.com/users/SnowflakePowered/following{/other_user}","gists_url":"https://api.github.com/users/SnowflakePowered/gists{/gist_id}","starred_url":"https://api.github.com/users/SnowflakePowered/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/SnowflakePowered/subscriptions","organizations_url":"https://api.github.com/users/SnowflakePowered/orgs","repos_url":"https://api.github.com/users/SnowflakePowered/repos","events_url":"https://api.github.com/users/SnowflakePowered/events{/privacy}","received_events_url":"https://api.github.com/users/SnowflakePowered/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/SnowflakePowered/snowflake","description":" :snowflake: :video_game: Extensible Emulator Frontend written in C# and Javascript","fork":false,"url":"https://api.github.com/repos/SnowflakePowered/snowflake","forks_url":"https://api.github.com/repos/SnowflakePowered/snowflake/forks","keys_url":"https://api.github.com/repos/SnowflakePowered/snowflake/keys{/key_id}","collaborators_url":"https://api.github.com/repos/SnowflakePowered/snowflake/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/SnowflakePowered/snowflake/teams","hooks_url":"https://api.github.com/repos/SnowflakePowered/snowflake/hooks","issue_events_url":"https://api.github.com/repos/SnowflakePowered/snowflake/issues/events{/number}","events_url":"https://api.github.com/repos/SnowflakePowered/snowflake/events","assignees_url":"https://api.github.com/repos/SnowflakePowered/snowflake/assignees{/user}","branches_url":"https://api.github.com/repos/SnowflakePowered/snowflake/branches{/branch}","tags_url":"https://api.github.com/repos/SnowflakePowered/snowflake/tags","blobs_url":"https://api.github.com/repos/SnowflakePowered/snowflake/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/SnowflakePowered/snowflake/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/SnowflakePowered/snowflake/git/refs{/sha}","trees_url":"https://api.github.com/repos/SnowflakePowered/snowflake/git/trees{/sha}","statuses_url":"https://api.github.com/repos/SnowflakePowered/snowflake/statuses/{sha}","languages_url":"https://api.github.com/repos/SnowflakePowered/snowflake/languages","stargazers_url":"https://api.github.com/repos/SnowflakePowered/snowflake/stargazers","contributors_url":"https://api.github.com/repos/SnowflakePowered/snowflake/contributors","subscribers_url":"https://api.github.com/repos/SnowflakePowered/snowflake/subscribers","subscription_url":"https://api.github.com/repos/SnowflakePowered/snowflake/subscription","commits_url":"https://api.github.com/repos/SnowflakePowered/snowflake/commits{/sha}","git_commits_url":"https://api.github.com/repos/SnowflakePowered/snowflake/git/commits{/sha}","comments_url":"https://api.github.com/repos/SnowflakePowered/snowflake/comments{/number}","issue_comment_url":"https://api.github.com/repos/SnowflakePowered/snowflake/issues/comments{/number}","contents_url":"https://api.github.com/repos/SnowflakePowered/snowflake/contents/{+path}","compare_url":"https://api.github.com/repos/SnowflakePowered/snowflake/compare/{base}...{head}","merges_url":"https://api.github.com/repos/SnowflakePowered/snowflake/merges","archive_url":"https://api.github.com/repos/SnowflakePowered/snowflake/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/SnowflakePowered/snowflake/downloads","issues_url":"https://api.github.com/repos/SnowflakePowered/snowflake/issues{/number}","pulls_url":"https://api.github.com/repos/SnowflakePowered/snowflake/pulls{/number}","milestones_url":"https://api.github.com/repos/SnowflakePowered/snowflake/milestones{/number}","notifications_url":"https://api.github.com/repos/SnowflakePowered/snowflake/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/SnowflakePowered/snowflake/labels{/name}","releases_url":"https://api.github.com/repos/SnowflakePowered/snowflake/releases{/id}","deployments_url":"https://api.github.com/repos/SnowflakePowered/snowflake/deployments","created_at":"2014-07-03T00:34:28Z","updated_at":"2016-03-08T03:33:38Z","pushed_at":"2016-03-11T00:01:29Z","git_url":"git://github.com/SnowflakePowered/snowflake.git","ssh_url":"git@github.com:SnowflakePowered/snowflake.git","clone_url":"https://github.com/SnowflakePowered/snowflake.git","svn_url":"https://github.com/SnowflakePowered/snowflake","homepage":"http://snowflakepowe.red","size":164797,"stargazers_count":48,"watchers_count":48,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":22,"forks":3,"open_issues":22,"watchers":48,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/SnowflakePowered/snowflake/pulls/211"},"html":{"href":"https://github.com/SnowflakePowered/snowflake/pull/211"},"issue":{"href":"https://api.github.com/repos/SnowflakePowered/snowflake/issues/211"},"comments":{"href":"https://api.github.com/repos/SnowflakePowered/snowflake/issues/211/comments"},"review_comments":{"href":"https://api.github.com/repos/SnowflakePowered/snowflake/pulls/211/comments"},"review_comment":{"href":"https://api.github.com/repos/SnowflakePowered/snowflake/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/SnowflakePowered/snowflake/pulls/211/commits"},"statuses":{"href":"https://api.github.com/repos/SnowflakePowered/snowflake/statuses/810ef687e6dff1767659de0d30a533b9a6544c20"}},"merged":true,"mergeable":null,"mergeable_state":"unknown","merged_by":{"login":"RonnChyran","id":1000503,"avatar_url":"https://avatars.githubusercontent.com/u/1000503?v=3","gravatar_id":"","url":"https://api.github.com/users/RonnChyran","html_url":"https://github.com/RonnChyran","followers_url":"https://api.github.com/users/RonnChyran/followers","following_url":"https://api.github.com/users/RonnChyran/following{/other_user}","gists_url":"https://api.github.com/users/RonnChyran/gists{/gist_id}","starred_url":"https://api.github.com/users/RonnChyran/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RonnChyran/subscriptions","organizations_url":"https://api.github.com/users/RonnChyran/orgs","repos_url":"https://api.github.com/users/RonnChyran/repos","events_url":"https://api.github.com/users/RonnChyran/events{/privacy}","received_events_url":"https://api.github.com/users/RonnChyran/received_events","type":"User","site_admin":false},"comments":2,"review_comments":0,"commits":31,"additions":1862,"deletions":1642,"changed_files":119}}