<commit_before>/*
 *     Food Inspector - Choose well to eat better
 *     Copyright (C) 2016  <NAME>
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Affero General Public License as published
 *     by the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Affero General Public License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.fredericletellier.foodinspector.data.source.local;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.support.annotation.Nullable;

import com.fredericletellier.foodinspector.data.source.local.db.CategoriesInProductPersistenceContract;
import com.fredericletellier.foodinspector.data.source.local.db.CategoryPersistenceContract;
import com.fredericletellier.foodinspector.data.source.local.db.EventPersistenceContract;
import com.fredericletellier.foodinspector.data.source.local.db.LocalDbHelper;
import com.fredericletellier.foodinspector.data.source.local.db.ProductPersistenceContract;
import com.fredericletellier.foodinspector.data.source.local.db.ProductsInCategoryPersistenceContract;

public class FoodInspectorContentProvider extends ContentProvider {

    private static final int PRODUCT = 100;
    private static final int PRODUCT_ITEM = 101;
    private static final int PRODUCTSINCATEGORY_JOIN_PRODUCT = 102;
    private static final int CATEGORY = 200;
    private static final int CATEGORY_ITEM = 201;
    private static final int EVENT = 300;
    private static final int EVENT_ITEM = 301;
    private static final int PRODUCTSINCATEGORY = 400;
    private static final int PRODUCTSINCATEGORY_ITEM = 401;
    private static final int CATEGORIESINPRODUCT = 500;
    private static final int CATEGORIESINPRODUCT_ITEM = 501;
    private static final UriMatcher sUriMatcher = buildUriMatcher();
    private LocalDbHelper mLocalDbHelper;

    private static UriMatcher buildUriMatcher() {
        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        final String authority = ProductPersistenceContract.CONTENT_AUTHORITY;

        matcher.addURI(authority, ProductPersistenceContract.ProductEntry.TABLE_NAME, PRODUCT);
        matcher.addURI(authority, ProductPersistenceContract.ProductEntry.TABLE_NAME + "/*", PRODUCT_ITEM);
        matcher.addURI(authority, ProductPersistenceContract.ProductEntry.PRODUCTSINCATEGORY_JOIN_PRODUCT, PRODUCTSINCATEGORY_JOIN_PRODUCT);
        matcher.addURI(authority, CategoryPersistenceContract.CategoryEntry.TABLE_NAME, CATEGORY);
        matcher.addURI(authority, CategoryPersistenceContract.CategoryEntry.TABLE_NAME + "/*", CATEGORY_ITEM);
        matcher.addURI(authority, EventPersistenceContract.EventEntry.TABLE_NAME, EVENT);
        matcher.addURI(authority, EventPersistenceContract.EventEntry.TABLE_NAME + "/*", EVENT_ITEM);
        matcher.addURI(authority, ProductsInCategoryPersistenceContract.ProductsInCategoryEntry.TABLE_NAME, PRODUCTSINCATEGORY);
        matcher.addURI(authority, ProductsInCategoryPersistenceContract.ProductsInCategoryEntry.TABLE_NAME + "/*", PRODUCTSINCATEGORY_ITEM);
        matcher.addURI(authority, CategoriesInProductPersistenceContract.CategoriesInProductEntry.TABLE_NAME, CATEGORIESINPRODUCT);
        matcher.addURI(authority, CategoriesInProductPersistenceContract.CategoriesInProductEntry.TABLE_NAME + "/*", CATEGORIESINPRODUCT_ITEM);

        return matcher;
    }

    @Override
    public boolean onCreate() {
        mLocalDbHelper = new LocalDbHelper(getContext());
        return true;
    }

    @Nullable
    @Override
    public String getType(Uri uri) {
        final int match = sUriMatcher.match(uri);
        switch (match) {
            case PRODUCT:
                return ProductPersistenceContract.CONTENT_PRODUCT_TYPE;
            case PRODUCT_ITEM:
                return ProductPersistenceContract.CONTENT_PRODUCT_ITEM_TYPE;
            case CATEGORY:
                return CategoryPersistenceContract.CONTENT_CATEGORY_TYPE;
            case CATEGORY_ITEM:
                return CategoryPersistenceContract.CONTENT_CATEGORY_ITEM_TYPE;
            case EVENT:
                return EventPersistenceContract.CONTENT_EVENT_TYPE;
            case EVENT_ITEM:
                return EventPersistenceContract.CONTENT_EVENT_ITEM_TYPE;
            case PRODUCTSINCATEGORY:
                return ProductsInCategoryPersistenceContract.CONTENT_PRODUCTSINCATEGORY_TYPE;
            case PRODUCTSINCATEGORY_ITEM:
                return ProductsInCategoryPersistenceContract.CONTENT_PRODUCTSINCATEGORY_ITEM_TYPE;
            case CATEGORIESINPRODUCT:
                return CategoriesInProductPersistenceContract.CONTENT_CATEGORIESINPRODUCT_TYPE;
            case CATEGORIESINPRODUCT_ITEM:
                return CategoriesInProductPersistenceContract.CONTENT_CATEGORIESINPRODUCT_ITEM_TYPE;
            default:
                throw new UnsupportedOperationException("Unknown uri: " + uri);
        }
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        Cursor retCursor;
        switch (sUriMatcher.match(uri)) {
            case PRODUCT:
                retCursor = mLocalDbHelper.getReadableDatabase().query(
                        ProductPersistenceContract.ProductEntry.TABLE_NAME,
                        projection,
                        selection,
                        selectionArgs,
                        null,
                        null,
                        sortOrder
                );
                break;
            case PRODUCT_ITEM:
                String[] where_product = {uri.getLastPathSegment()};
                retCursor = mLocalDbHelper.getReadableDatabase().query(
                        ProductPersistenceContract.ProductEntry.TABLE_NAME,
                        projection,
                        ProductPersistenceContract.ProductEntry._ID + " = ?",
                        where_product,
                        null,
                        null,
                        sortOrder
                );
                break;
            case PRODUCTSINCATEGORY_JOIN_PRODUCT:
                //TODO JOIN two tables ProductsInCategories and Product
                retCursor = null;
                break;
            case CATEGORY:
                retCursor = mLocalDbHelper.getReadableDatabase().query(
                        CategoryPersistenceContract.CategoryEntry.TABLE_NAME,
                        projection,<commit_msg>feat: Join Product and ProductsInCategory in a query of content provider<commit_after>/*
 *     Food Inspector - Choose well to eat better
 *     Copyright (C) 2016  <NAME>
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Affero General Public License as published
 *     by the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Affero General Public License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.fredericletellier.foodinspector.data.source.local;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.support.annotation.Nullable;

import com.fredericletellier.foodinspector.data.source.local.db.CategoriesInProductPersistenceContract;
import com.fredericletellier.foodinspector.data.source.local.db.CategoryPersistenceContract;
import com.fredericletellier.foodinspector.data.source.local.db.EventPersistenceContract;
import com.fredericletellier.foodinspector.data.source.local.db.LocalDbHelper;
import com.fredericletellier.foodinspector.data.source.local.db.ProductPersistenceContract;
import com.fredericletellier.foodinspector.data.source.local.db.ProductsInCategoryPersistenceContract;

public class FoodInspectorContentProvider extends ContentProvider {

    private static final int PRODUCT = 100;
    private static final int PRODUCT_ITEM = 101;
    private static final int PRODUCTSINCATEGORY_JOIN_PRODUCT = 102;
    private static final int CATEGORY = 200;
    private static final int CATEGORY_ITEM = 201;
    private static final int EVENT = 300;
    private static final int EVENT_ITEM = 301;
    private static final int PRODUCTSINCATEGORY = 400;
    private static final int PRODUCTSINCATEGORY_ITEM = 401;
    private static final int CATEGORIESINPRODUCT = 500;
    private static final int CATEGORIESINPRODUCT_ITEM = 501;
    private static final UriMatcher sUriMatcher = buildUriMatcher();
    private LocalDbHelper mLocalDbHelper;

    private static final SQLiteQueryBuilder sProductsInCategoryQueryBuilder;

    static{
        sProductsInCategoryQueryBuilder = new SQLiteQueryBuilder();

        sProductsInCategoryQueryBuilder.setTables(
                ProductsInCategoryPersistenceContract.ProductsInCategoryEntry.TABLE_NAME + " INNER JOIN " +
                        ProductPersistenceContract.ProductEntry.TABLE_NAME +
                        " ON " + ProductsInCategoryPersistenceContract.ProductsInCategoryEntry.TABLE_NAME +
                        "." + ProductsInCategoryPersistenceContract.ProductsInCategoryEntry.COLUMN_NAME_PRODUCT_ID +
                        " = " + ProductPersistenceContract.ProductEntry.TABLE_NAME +
                        "." + ProductPersistenceContract.ProductEntry._ID);
    }


    private static UriMatcher buildUriMatcher() {
        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        final String authority = ProductPersistenceContract.CONTENT_AUTHORITY;

        matcher.addURI(authority, ProductPersistenceContract.ProductEntry.TABLE_NAME, PRODUCT);
        matcher.addURI(authority, ProductPersistenceContract.ProductEntry.TABLE_NAME + "/*", PRODUCT_ITEM);
        matcher.addURI(authority, ProductPersistenceContract.ProductEntry.PRODUCTSINCATEGORY_JOIN_PRODUCT, PRODUCTSINCATEGORY_JOIN_PRODUCT);
        matcher.addURI(authority, CategoryPersistenceContract.CategoryEntry.TABLE_NAME, CATEGORY);
        matcher.addURI(authority, CategoryPersistenceContract.CategoryEntry.TABLE_NAME + "/*", CATEGORY_ITEM);
        matcher.addURI(authority, EventPersistenceContract.EventEntry.TABLE_NAME, EVENT);
        matcher.addURI(authority, EventPersistenceContract.EventEntry.TABLE_NAME + "/*", EVENT_ITEM);
        matcher.addURI(authority, ProductsInCategoryPersistenceContract.ProductsInCategoryEntry.TABLE_NAME, PRODUCTSINCATEGORY);
        matcher.addURI(authority, ProductsInCategoryPersistenceContract.ProductsInCategoryEntry.TABLE_NAME + "/*", PRODUCTSINCATEGORY_ITEM);
        matcher.addURI(authority, CategoriesInProductPersistenceContract.CategoriesInProductEntry.TABLE_NAME, CATEGORIESINPRODUCT);
        matcher.addURI(authority, CategoriesInProductPersistenceContract.CategoriesInProductEntry.TABLE_NAME + "/*", CATEGORIESINPRODUCT_ITEM);

        return matcher;
    }

    @Override
    public boolean onCreate() {
        mLocalDbHelper = new LocalDbHelper(getContext());
        return true;
    }

    @Nullable
    @Override
    public String getType(Uri uri) {
        final int match = sUriMatcher.match(uri);
        switch (match) {
            case PRODUCT:
                return ProductPersistenceContract.CONTENT_PRODUCT_TYPE;
            case PRODUCT_ITEM:
                return ProductPersistenceContract.CONTENT_PRODUCT_ITEM_TYPE;
            case CATEGORY:
                return CategoryPersistenceContract.CONTENT_CATEGORY_TYPE;
            case CATEGORY_ITEM:
                return CategoryPersistenceContract.CONTENT_CATEGORY_ITEM_TYPE;
            case EVENT:
                return EventPersistenceContract.CONTENT_EVENT_TYPE;
            case EVENT_ITEM:
                return EventPersistenceContract.CONTENT_EVENT_ITEM_TYPE;
            case PRODUCTSINCATEGORY:
                return ProductsInCategoryPersistenceContract.CONTENT_PRODUCTSINCATEGORY_TYPE;
            case PRODUCTSINCATEGORY_ITEM:
                return ProductsInCategoryPersistenceContract.CONTENT_PRODUCTSINCATEGORY_ITEM_TYPE;
            case CATEGORIESINPRODUCT:
                return CategoriesInProductPersistenceContract.CONTENT_CATEGORIESINPRODUCT_TYPE;
            case CATEGORIESINPRODUCT_ITEM:
                return CategoriesInProductPersistenceContract.CONTENT_CATEGORIESINPRODUCT_ITEM_TYPE;
            default:
                throw new UnsupportedOperationException("Unknown uri: " + uri);
        }
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        Cursor retCursor;
        switch (sUriMatcher.match(uri)) {
            case PRODUCT:
                retCursor = mLocalDbHelper.getReadableDatabase().query(
                        ProductPersistenceContract.ProductEntry.TABLE_NAME,
                        projection,
                        selection,
                        selectionArgs,
                        null,
                        null,
                        sortOrder
                );
                break;
            case PRODUCT_ITEM:
                String[] where_product = {uri.getLastPathSegment()};
                retCursor = mLocalDbHelper.getReadableDatabase().query(
                        ProductPersistenceContract.ProductEntry.TABLE_NAME,
                        projection,
                        ProductPersistenceContract.ProductEntry._ID + " = ?",
                        where_product,
                        null,
                        null,
                        sortOrder
                );
                break;
            case PRODUCTSINCATEGORY_JOIN_PRODUCT:
                retCursor = sProductsInCategoryQueryBuilder.query(mLocalDbHelper.getReadableDatabase(),
                        projection,
                        selection,
                        selectionArgs,
                        null,
                        null,
                        sortOrder
                );
                break;
            case CATEGORY:
                retCursor = mLocalDbHelper.getReadableDatabase().query(
                        CategoryPersistenceContract.CategoryEntry.TABLE_NAME,
                        projection,
{'fraction_non_alphanumeric': 0.06066727485989835, 'fraction_numerical': 0.004952430600808028, 'mean_word_length': 2.71328332930075, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7255551', 'n_tokens_mistral': 4096, 'n_tokens_neox': 3831, 'n_words': 829}