{"action":"opened","issue":{"url":"https://api.github.com/repos/joeyates/cpp-active-record/issues/8","labels_url":"https://api.github.com/repos/joeyates/cpp-active-record/issues/8/labels{/name}","comments_url":"https://api.github.com/repos/joeyates/cpp-active-record/issues/8/comments","events_url":"https://api.github.com/repos/joeyates/cpp-active-record/issues/8/events","html_url":"https://github.com/joeyates/cpp-active-record/issues/8","id":110265542,"number":8,"title":"SQLite - TableSet::update_table(...) always throwing (tries to drop primary key)","user":{"login":"rkubik","id":927179,"avatar_url":"https://avatars.githubusercontent.com/u/927179?v=3","gravatar_id":"","url":"https://api.github.com/users/rkubik","html_url":"https://github.com/rkubik","followers_url":"https://api.github.com/users/rkubik/followers","following_url":"https://api.github.com/users/rkubik/following{/other_user}","gists_url":"https://api.github.com/users/rkubik/gists{/gist_id}","starred_url":"https://api.github.com/users/rkubik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rkubik/subscriptions","organizations_url":"https://api.github.com/users/rkubik/orgs","repos_url":"https://api.github.com/users/rkubik/repos","events_url":"https://api.github.com/users/rkubik/events{/privacy}","received_events_url":"https://api.github.com/users/rkubik/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-10-07T16:31:15Z","updated_at":"2015-10-07T16:31:15Z","closed_at":null,"body":"**Reference:**\r\n\r\n    table_set.cpp:68 \r\n    void TableSet::update_table( Table &required ) \r\n\r\n`required.fields()` and `existing.fields()` will always be different because of the automatic primary key assignment. Using the example table below:\r\n\r\n    td.fields() = fields\r\n            (\"code\",        ActiveRecord::text)\r\n            (\"title\",       ActiveRecord::text);\r\n\r\n`required.fields()` will contain: [code, title]\r\n`existing.fields()` will contain: [id, code, title]\r\n\r\nThus, the set difference `required.fields() - existing.fields()` will always return the primary key `id` and try to drop it.\r\n\r\n**Proposed solution:**\r\n\r\n    void TableSet::update_table( Table &required ) {\r\n      log( \"TableSet::update_table\" );\r\n      log( required.table_name() );\r\n      Table existing = table_data( required.connection(), required.table_name() );\r\n      Fields missing = required.fields() - existing.fields();\r\n      Fields remove  = existing.fields() - required.fields();\r\n      for( Fields::iterator it = missing.begin(); it != missing.end(); ++it )\r\n        existing.add_field( *it );\r\n      for( Fields::iterator it = remove.begin(); it != remove.end(); ++it ) {\r\n        if ((*it).name() == existing.primary_key()) /* fix */\r\n          continue;\r\n        throw ActiveRecordException( \"Table::remove_field not yet implemented\", __FILE__, __LINE__ );\r\n        //existing.remove_field( *it );\r\n      }\r\n    }\r\n\r\n**Better solution:**\r\n\r\nThe `fields()` method should **always** return the same `Fields` no matter the context (ie. database fetch or class). The `TableSet::table_data` function should not load the primary key as a `Field` but instead only set the `id_` variable of the `Table`. Of course I say this without fully understanding the impact, but hopefully you agree with keeping everything deterministic."}}