class ApkProvider extends FDroidProvider {

    @Override
    public Cursor query(@NonNull Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {

        QuerySelection query = new QuerySelection(selection, selectionArgs);

        switch (MATCHER.match(uri)) {
            case CODE_REPO_APP:
                List<String> uriSegments = uri.getPathSegments();
                Long repoId = Long.parseLong(uriSegments.get(1));
                String packageName = uriSegments.get(2);
                query = query.add(queryRepo(repoId)).add(queryPackage(packageName));
                break;

            case CODE_LIST:
                break;

            case CODE_APK_FROM_ANY_REPO:
                query = query.add(querySingleFromAnyRepo(uri));
                break;

            case CODE_APK_ROW_ID:
                query = query.add(querySingle(Long.parseLong(uri.getLastPathSegment())));
                break;

            case CODE_PACKAGE:
                query = query.add(queryPackage(uri.getLastPathSegment()));
                break;

            case CODE_APKS:
                query = query.add(queryApks(uri.getLastPathSegment()));
                break;

            case CODE_REPO:
                query = query.add(queryRepo(Long.parseLong(uri.getLastPathSegment())));
                break;

            default:
                Log.e(TAG, "Invalid URI for apk content provider: " + uri);
                throw new UnsupportedOperationException("Invalid URI for apk content provider: " + uri);
        }

        Query queryBuilder = new Query();
        for (final String field : projection) {
            queryBuilder.addField(field);
        }
        queryBuilder.addSelection(query);
        queryBuilder.addOrderBy(sortOrder);

        Cursor cursor = LoggingQuery.rawQuery(db(), queryBuilder.toString(), queryBuilder.getArgs());
        cursor.setNotificationUri(getContext().getContentResolver(), uri);
        return cursor;
    }

}

class ApkProviderTest extends FDroidProvider {

    private static final String[] PROJ;
    private static final long REPO_KEEP;
    private static final long REPO_DELETE;

    @Test
    public void testInsertWithValidExtraFields() {


        assertResultCount(0, queryAllApks());

        ContentValues values = new ContentValues();
        values.put(Cols.REPO_ID, 10);
        values.put(Cols.Repo.ADDRESS, "http://example.com");
        values.put(Cols.Repo.VERSION, 3);
        values.put(Cols.FEATURES, "Some features");
        Uri uri = Assert.insertApk(context, "com.example.com", 1, values);

        assertResultCount(1, queryAllApks());

        String[] projections = Cols.ALL;
        Cursor cursor = contentResolver.query(uri, projections, null, null, null);
        cursor.moveToFirst();
        Apk apk = new Apk(cursor);
        cursor.close();

        // These should have quietly been dropped when we tried to save them,
        // because the provider only knows how to query them (not update them).
        assertEquals(null, apk.repoAddress);
        assertEquals(0, apk.repoVersion);

        // But this should have saved correctly...
        assertEquals(1, apk.features.length);
        assertEquals("Some features", apk.features[0]);
        assertEquals("com.example.com", apk.packageName);
        assertEquals(1, apk.versionCode);
        assertEquals(10, apk.repoId);
    }

}