/src/libtomahawk/database/Schema.sql

http://github.com/tomahawk-player/tomahawk · SQL · 303 lines · 195 code · 59 blank · 49 comment · 0 complexity · ccdb470f9aa9ee0ffb1a3c8ff539508e MD5 · raw file

  1. -- Mutates to the database are entered into the transaction log
  2. -- so they can be sent to peers to replay against a cache of your DB.
  3. -- This allows peers to get diffs/sync your collection easily.
  4. CREATE TABLE IF NOT EXISTS oplog (
  5. id INTEGER PRIMARY KEY AUTOINCREMENT,
  6. source INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE, -- DEFERRABLE INITIALLY DEFERRED,
  7. guid TEXT NOT NULL,
  8. command TEXT NOT NULL,
  9. singleton BOOLEAN NOT NULL,
  10. compressed BOOLEAN NOT NULL,
  11. json TEXT NOT NULL
  12. );
  13. CREATE UNIQUE INDEX oplog_guid ON oplog(guid);
  14. CREATE INDEX oplog_source ON oplog(source);
  15. -- the basic 3 catalogue tables:
  16. CREATE TABLE IF NOT EXISTS artist (
  17. id INTEGER PRIMARY KEY AUTOINCREMENT,
  18. name TEXT NOT NULL,
  19. sortname TEXT NOT NULL
  20. );
  21. CREATE UNIQUE INDEX artist_sortname ON artist(sortname);
  22. CREATE INDEX artist_name ON artist(name);
  23. CREATE TABLE IF NOT EXISTS track (
  24. id INTEGER PRIMARY KEY AUTOINCREMENT,
  25. artist INTEGER NOT NULL REFERENCES artist(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  26. name TEXT NOT NULL,
  27. sortname TEXT NOT NULL
  28. );
  29. CREATE UNIQUE INDEX track_artist_sortname ON track(artist,sortname);
  30. CREATE INDEX track_name ON track(name);
  31. CREATE TABLE IF NOT EXISTS album (
  32. id INTEGER PRIMARY KEY AUTOINCREMENT,
  33. artist INTEGER NOT NULL REFERENCES artist(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  34. name TEXT NOT NULL,
  35. sortname TEXT NOT NULL
  36. );
  37. CREATE UNIQUE INDEX album_artist_sortname ON album(artist,sortname);
  38. -- Source, typically a remote peer.
  39. CREATE TABLE IF NOT EXISTS source (
  40. id INTEGER PRIMARY KEY AUTOINCREMENT,
  41. name TEXT NOT NULL,
  42. friendlyname TEXT,
  43. lastop TEXT NOT NULL DEFAULT "", -- guid of last op we've successfully applied
  44. isonline BOOLEAN NOT NULL DEFAULT false
  45. );
  46. CREATE UNIQUE INDEX source_name ON source(name);
  47. -- playlists
  48. CREATE TABLE IF NOT EXISTS playlist (
  49. guid TEXT PRIMARY KEY,
  50. source INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, -- owner
  51. shared BOOLEAN DEFAULT false,
  52. title TEXT,
  53. info TEXT,
  54. creator TEXT,
  55. lastmodified INTEGER NOT NULL DEFAULT 0,
  56. currentrevision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED,
  57. dynplaylist BOOLEAN DEFAULT false,
  58. createdOn INTEGER NOT NULL DEFAULT 0
  59. );
  60. --INSERT INTO playlist(guid, title, info, currentrevision, dynplaylist)
  61. --VALUES('dynamic_playlist-guid-1','Test Dynamic Playlist Dynamic','this playlist automatically created and used for testing','revisionguid-1', 1);
  62. --INSERT INTO playlist(guid, title, info, currentrevision, dynplaylist)
  63. --VALUES('dynamic_playlist-guid-2','Test Dynamic Playlist Static','this playlist automatically created and used for testing','revisionguid-11', 1);
  64. CREATE TABLE IF NOT EXISTS playlist_item (
  65. guid TEXT PRIMARY KEY,
  66. playlist TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  67. trackname TEXT NOT NULL,
  68. artistname TEXT NOT NULL,
  69. albumname TEXT,
  70. annotation TEXT,
  71. duration INTEGER, -- in seconds, even tho xspf uses milliseconds
  72. addedon INTEGER NOT NULL DEFAULT 0, -- date added to playlist
  73. addedby INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, -- who added this to the playlist
  74. result_hint TEXT -- hint as to a result, to avoid using the resolver
  75. );
  76. CREATE INDEX playlist_item_playlist ON playlist_item(playlist);
  77. CREATE INDEX playlist_item_trackname ON playlist_item(trackname);
  78. CREATE INDEX playlist_item_artistname ON playlist_item(artistname);
  79. CREATE TABLE IF NOT EXISTS playlist_revision (
  80. guid TEXT PRIMARY KEY,
  81. playlist TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  82. entries TEXT, -- qlist( guid, guid... )
  83. author INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  84. timestamp INTEGER NOT NULL DEFAULT 0,
  85. previous_revision TEXT REFERENCES playlist_revision(guid) DEFERRABLE INITIALLY DEFERRED
  86. );
  87. --INSERT INTO playlist_revision(guid, playlist, entries)
  88. -- VALUES('revisionguid-1', 'dynamic_playlist-guid-1', '[]');
  89. --INSERT INTO playlist_revision(guid, playlist, entries)
  90. -- VALUES('revisionguid-11', 'dynamic_playlist-guid-2', '[]');
  91. CREATE TABLE IF NOT EXISTS dynamic_playlist (
  92. guid TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  93. pltype TEXT, -- the generator type
  94. plmode INTEGER, -- the mode of this playlist
  95. autoload BOOLEAN DEFAULT true -- if this playlist should be autoloaded or not. true except for the case of special playlists we want to display elsewhere
  96. );
  97. --INSERT INTO dynamic_playlist(guid, pltype, plmode)
  98. -- VALUES('dynamic_playlist-guid-1', 'echonest', 0);
  99. --INSERT INTO dynamic_playlist(guid, pltype, plmode)
  100. -- VALUES('dynamic_playlist-guid-2', 'echonest', 1);
  101. -- list of controls in each playlist. each control saves a selectedType, a match, and an input
  102. CREATE TABLE IF NOT EXISTS dynamic_playlist_controls (
  103. id TEXT PRIMARY KEY,
  104. playlist TEXT NOT NULL REFERENCES playlist(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  105. selectedType TEXT,
  106. match TEXT,
  107. input TEXT
  108. );
  109. --INSERT INTO dynamic_playlist_controls(id, playlist, selectedType, match, input)
  110. -- VALUES('controlid-1', 'dynamic_playlist-guid-1', "artist", 0, "FooArtist" );
  111. --INSERT INTO dynamic_playlist_controls(id, playlist, selectedType, match, input)
  112. -- VALUES('controlid-2', 'dynamic_playlist-guid-11', "artist", 0, "FooArtist" );
  113. CREATE TABLE IF NOT EXISTS dynamic_playlist_revision (
  114. guid TEXT PRIMARY KEY NOT NULL REFERENCES playlist_revision(guid) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  115. controls TEXT, -- qlist( id, id, id )
  116. plmode INTEGER,
  117. pltype TEXT
  118. );
  119. --INSERT INTO dynamic_playlist_revision(guid, controls, plmode, pltype)
  120. -- VALUES('revisionguid-1', '["controlid-1"]', 0, "echonest");
  121. --INSERT INTO dynamic_playlist_revision(guid, controls, plmode, pltype)
  122. -- VALUES('revisionguid-11', '["controlid-2"]', 1, "echonest");
  123. -- files on disk and joinage with catalogue. physical properties of files only:
  124. -- if source=null, file is local to this machine
  125. CREATE TABLE IF NOT EXISTS file (
  126. id INTEGER PRIMARY KEY AUTOINCREMENT,
  127. source INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  128. url TEXT NOT NULL, -- file:///music/foo/bar.mp3, <guid or hash?>
  129. size INTEGER NOT NULL, -- in bytes
  130. mtime INTEGER NOT NULL, -- file mtime, so we know to rescan
  131. md5 TEXT, -- useful when comparing stuff p2p
  132. mimetype TEXT, -- "audio/mpeg"
  133. duration INTEGER NOT NULL DEFAULT 0, -- seconds
  134. bitrate INTEGER NOT NULL DEFAULT 0 -- kbps (or equiv)
  135. );
  136. CREATE UNIQUE INDEX file_url_src_uniq ON file(source, url);
  137. CREATE INDEX file_source ON file(source);
  138. CREATE INDEX file_mtime ON file(mtime);
  139. -- mtime of dir when last scanned.
  140. -- load into memory when rescanning, skip stuff that's unchanged
  141. CREATE TABLE IF NOT EXISTS dirs_scanned (
  142. name TEXT PRIMARY KEY,
  143. mtime INTEGER NOT NULL
  144. );
  145. CREATE TABLE IF NOT EXISTS file_join (
  146. file INTEGER PRIMARY KEY REFERENCES file(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  147. artist INTEGER NOT NULL REFERENCES artist(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  148. track INTEGER NOT NULL REFERENCES track(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  149. album INTEGER REFERENCES album(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  150. albumpos INTEGER,
  151. composer INTEGER REFERENCES artist(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  152. discnumber INTEGER
  153. );
  154. CREATE INDEX file_join_track ON file_join(track);
  155. CREATE INDEX file_join_artist ON file_join(artist);
  156. CREATE INDEX file_join_album ON file_join(album);
  157. -- tags, weighted and by source (rock, jazz etc)
  158. -- weight is always 1.0 if tag provided by our user.
  159. -- may be less from aggregate sources like lastfm global tags
  160. CREATE TABLE IF NOT EXISTS track_tags (
  161. id INTEGER PRIMARY KEY, -- track id
  162. source INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  163. tag TEXT NOT NULL, -- always store as lowercase
  164. ns TEXT, -- ie 'last.fm', 'echonest'
  165. weight float DEFAULT 1.0 -- range 0-1
  166. );
  167. CREATE INDEX track_tags_tag ON track_tags(tag);
  168. CREATE TABLE IF NOT EXISTS album_tags (
  169. id INTEGER PRIMARY KEY, -- album id
  170. source INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  171. tag TEXT NOT NULL, -- always store as lowercase
  172. ns TEXT, -- ie 'last.fm', 'echonest'
  173. weight float DEFAULT 1.0 -- range 0-1
  174. );
  175. CREATE INDEX album_tags_tag ON album_tags(tag);
  176. CREATE TABLE IF NOT EXISTS artist_tags (
  177. id INTEGER PRIMARY KEY, -- artist id
  178. source INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  179. tag TEXT NOT NULL, -- always store as lowercase
  180. ns TEXT, -- ie 'last.fm', 'echonest'
  181. weight float DEFAULT 1.0 -- range 0-1
  182. );
  183. CREATE INDEX artist_tags_tag ON artist_tags(tag);
  184. -- all other attributes.
  185. -- like tags that have a value, eg:
  186. -- BPM=120, releaseyear=1980, key=Dminor, composer=Someone
  187. -- NB: since all values are text, numeric values should be zero-padded to a set amount
  188. -- so that we can always do range queries.
  189. CREATE TABLE IF NOT EXISTS track_attributes (
  190. id INTEGER REFERENCES track(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, -- track id
  191. k TEXT NOT NULL,
  192. v TEXT NOT NULL
  193. );
  194. CREATE INDEX track_attrib_id ON track_attributes(id);
  195. CREATE INDEX track_attrib_k ON track_attributes(k);
  196. -- Collection attributes, tied to a source. An example might be an echonest song catalog
  197. CREATE TABLE IF NOT EXISTS collection_attributes (
  198. id INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, -- source id, null for local source
  199. k TEXT NOT NULL,
  200. v TEXT NOT NULL
  201. );
  202. -- social attributes connected to the track.
  203. -- like love, hate, comments, recommendations
  204. -- love=[comment], hate=[comment], comment=Some text
  205. -- NB: since all values are text, numeric values should be zero-padded to a set amount
  206. -- so that we can always do range queries.
  207. CREATE TABLE IF NOT EXISTS social_attributes (
  208. id INTEGER REFERENCES track(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED, -- track id
  209. source INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE, -- DEFERRABLE INITIALLY DEFERRED,
  210. k TEXT NOT NULL,
  211. v TEXT NOT NULL,
  212. timestamp INTEGER NOT NULL DEFAULT 0
  213. );
  214. CREATE INDEX social_attrib_id ON social_attributes(id);
  215. CREATE INDEX social_attrib_source ON social_attributes(source);
  216. CREATE INDEX social_attrib_k ON social_attributes(k);
  217. CREATE INDEX social_attrib_timestamp ON social_attributes(timestamp);
  218. -- playback history
  219. -- if source=null, file is local to this machine
  220. CREATE TABLE IF NOT EXISTS playback_log (
  221. id INTEGER PRIMARY KEY AUTOINCREMENT,
  222. source INTEGER REFERENCES source(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  223. track INTEGER REFERENCES track(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
  224. playtime INTEGER NOT NULL, -- when playback finished (timestamp)
  225. secs_played INTEGER NOT NULL
  226. );
  227. CREATE INDEX playback_log_source ON playback_log(source);
  228. CREATE INDEX playback_log_track ON playback_log(track);
  229. CREATE INDEX playback_log_playtime ON playback_log(playtime);
  230. -- auth information for http clients
  231. CREATE TABLE IF NOT EXISTS http_client_auth (
  232. token TEXT NOT NULL PRIMARY KEY,
  233. website TEXT NOT NULL,
  234. name TEXT NOT NULL,
  235. ua TEXT,
  236. mtime INTEGER,
  237. permissions TEXT NOT NULL
  238. );
  239. -- Schema version, and misc tomahawk settings relating to the collection db
  240. CREATE TABLE IF NOT EXISTS settings (
  241. k TEXT NOT NULL PRIMARY KEY,
  242. v TEXT NOT NULL DEFAULT ''
  243. );
  244. INSERT INTO settings(k,v) VALUES('schema_version', '31');