/** * * TURTLE PLAYER * * Licensed under MIT & GPL * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE * OR OTHER DEALINGS IN THE SOFTWARE. * * More Information @ www.turtle-player.co.uk * * @author Simon Honegger (Hoene84) */ package com.turtleplayer.persistance.turtle.db; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; import com.turtleplayer.model.*; import com.turtleplayer.persistance.framework.creator.ResultCreator; import com.turtleplayer.persistance.framework.db.Database; import com.turtleplayer.persistance.framework.db.ObservableDatabase; import com.turtleplayer.persistance.framework.executor.OperationExecutor; import com.turtleplayer.persistance.framework.filter.Filter; import com.turtleplayer.persistance.framework.sort.FieldOrder; import com.turtleplayer.persistance.framework.sort.SortOrder; import com.turtleplayer.persistance.source.relational.FieldPersistable; import com.turtleplayer.persistance.source.relational.View; import com.turtleplayer.persistance.source.sql.MappingDistinct; import com.turtleplayer.persistance.source.sql.MappingTable; import com.turtleplayer.persistance.source.sql.query.Select; import com.turtleplayer.persistance.source.sqlite.*; import com.turtleplayer.persistance.turtle.FileBase; import com.turtleplayer.persistance.turtle.db.structure.Tables; import com.turtleplayer.persistance.turtle.db.structure.Views; import com.turtleplayer.persistance.turtle.mapping.*; import java.util.Arrays; import java.util.List; // Import - Android Content // Import - Android Database public class TurtleDatabase extends ObservableDatabase<Select, Cursor, SQLiteDatabase> implements FileBase { final SQLiteDatabase db; public TurtleDatabase(Context context) { SQLiteOpenHelper turtleDatabaseImpl = new TurtleDatabaseImpl(context) { @Override public void dbResetted() { notifyCleared(); } }; db = turtleDatabaseImpl.getWritableDatabase(); } //Write------------------------------------ /** * @return true when successful inserted */ public boolean push(final Track track) { int insertedCount = OperationExecutor.execute(this, new InsertOperationSqlLite<Track>(new TrackToDbMapper()), track); if(insertedCount > 0) { notifyUpdate(track); return true; } return false; } public void push(final AlbumArtLocation albumArtLocation) { OperationExecutor.execute(this, new InsertOperationSqlLite<AlbumArtLocation>(new AlbumArtLoactionToDbMapper()), albumArtLocation); } public void push(final FSobject dir) { OperationExecutor.execute(this, new InsertOperationSqlLite<FSobject>(new FsObjectToDbMapper()), dir); } public void clear() { OperationExecutor.execute(this, new DeleteTableContentSqlLite(), Tables.TRACKS); OperationExecutor.execute(this, new DeleteTableContentSqlLite(), Tables.DIRS); notifyCleared(); } //Read------------------------------------ public boolean isEmpty(Filter<Tables.Tracks> filter) { return OperationExecutor.execute( this, new QuerySqlite<Tables.Tracks, Tables.Tracks, Integer>(filter, new CounterSqlite(Tables.TRACKS))).equals(0); } public int countAvailableTracks(Filter<Tables.Tracks> filter) { return OperationExecutor.execute( this, new QuerySqlite<Tables.Tracks, Tables.Tracks, Integer>(filter, new CounterSqlite(Tables.TRACKS))); } public List<? extends Track> getTracks(Filter<? super Tables.Tracks> filter) { return getList(filter, new TrackCreator(), Tables.TRACKS, Tables.TRACKS ,Tables.Tracks.TITLE); } public List<? extends Song> getSongs(Filter<? super Tables.Tracks> filter) { return getList(filter, new SongCreator(), Tables.TRACKS, Views.SONGS ,Tables.SongsReadable.TITLE); } public List<? extends Artist> getArtists(Filter<? super Tables.Tracks> filter) { return getList(filter, new ArtistCreator(), Tables.TRACKS, Views.ARTISTS, Tables.ArtistsReadable.ARTIST); } public List<? extends Genre> getGenres(Filter<? super Tables.Tracks> filter) { return getList(filter, new GenreCreator(), Tables.TRACKS, Views.GENRES, Tables.GenresReadable.GENRE); } public List<? extends Album> getAlbums(Filter<? super Tables.Tracks> filter) { return getList(filter, new AlbumCreator(), Tables.TRACKS, Views.ALBUMS, Tables.AlbumsReadable.ALBUM); } public List<? extends FSobject> getDirList(Filter<? super Tables.Dirs> filter) { return getList(filter, new DirCreator(), Tables.DIRS, Tables.DIRS, Tables.Dirs.NAME); } private <RESULT, TARGET extends View, PROJECTION extends View, Z> List<RESULT> getList( Filter<? super PROJECTION> filter, ResultCreator<TARGET, RESULT, Cursor> creator, PROJECTION view, TARGET target, FieldPersistable<? super RESULT, Z>... sortFields) { return OperationExecutor.execute( this, new QuerySqlite<PROJECTION, TARGET, List<RESULT>>( filter, FieldOrder.<PROJECTION, RESULT, Z>getMultiFieldOrder(SortOrder.ASC, sortFields), new MappingDistinct<TARGET, PROJECTION, RESULT>(view, new CreatorForListSqlite<TARGET, RESULT>(creator), target) ) ); } public <I> I read(Select query, Database.DbReadOp<I, Cursor> readOp) { Cursor cursor = null; try { String[] params = new String[query.getParams().size()]; int i = 0; for (Object param : query.getParams()) { params[i++] = param.toString(); } Log.v(TurtleDatabase.class.getName(), "Running Query: " + query.toSql() + " with params " + Arrays.deepToString(params)); cursor = db.rawQuery(query.toSql(), params); Log.v(TurtleDatabase.class.getName(), "Resulting in " + cursor.getCount() + " Resulting Rows"); return readOp.read(cursor); } finally { if (cursor != null) { cursor.close(); } } } public <I> int write(DbWriteOp<SQLiteDatabase, I> writeOp, I instance) { return writeOp.write(db, instance); } }