me.everything.providers.stetho.Database.java Source code

Java tutorial

Introduction

Here is the source code for me.everything.providers.stetho.Database.java

Source

/*
 * Copyright (c) 2014-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 */

package me.everything.providers.stetho;

import android.annotation.TargetApi;
import android.content.Context;
import android.database.sqlite.SQLiteException;
import android.os.Build;

import com.facebook.stetho.inspector.jsonrpc.JsonRpcException;
import com.facebook.stetho.inspector.jsonrpc.JsonRpcPeer;
import com.facebook.stetho.inspector.jsonrpc.JsonRpcResult;
import com.facebook.stetho.inspector.jsonrpc.protocol.JsonRpcError;
import com.facebook.stetho.inspector.protocol.ChromeDevtoolsDomain;
import com.facebook.stetho.inspector.protocol.ChromeDevtoolsMethod;
import com.facebook.stetho.json.ObjectMapper;
import com.facebook.stetho.json.annotation.JsonProperty;

import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import me.everything.providers.core.Entity;

@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class Database implements ChromeDevtoolsDomain {

    private Context mContext;
    private final ProvidersPeerManager mProvidersPeerManager;
    private final ObjectMapper mObjectMapper;
    private final ModuleDatabaseDelegator mModuleDatabaseDelegator;

    public Database(Context context, ProvidersStetho providersStetho) {
        mContext = context;
        mModuleDatabaseDelegator = new ModuleDatabaseDelegator(mContext);
        mObjectMapper = new ObjectMapper();
        mProvidersPeerManager = new ProvidersPeerManager(mContext, providersStetho);
    }

    @ChromeDevtoolsMethod
    public void enable(JsonRpcPeer peer, JSONObject params) {
        mModuleDatabaseDelegator.enable(peer, params);
        mProvidersPeerManager.addPeer(peer);
    }

    @ChromeDevtoolsMethod
    public void disable(JsonRpcPeer peer, JSONObject params) {
        mModuleDatabaseDelegator.disable(peer, params);
        mProvidersPeerManager.removePeer(peer);
    }

    @ChromeDevtoolsMethod
    public JsonRpcResult getDatabaseTableNames(JsonRpcPeer peer, JSONObject params) throws JsonRpcException {

        // fetch database id
        GetDatabaseTableNamesRequest request = mObjectMapper.convertValue(params,
                GetDatabaseTableNamesRequest.class);
        String databaseId = request.databaseId;

        if (mProvidersPeerManager.contains(databaseId)) {
            return getDatabaseTableNames(databaseId);
        }

        return mModuleDatabaseDelegator.getDatabaseTableNames(peer, params);

    }

    private JsonRpcResult getDatabaseTableNames(String databaseId) throws JsonRpcException {

        try {
            GetDatabaseTableNamesResponse response = new GetDatabaseTableNamesResponse();
            response.tableNames = mProvidersPeerManager.getDatabaseTableNames(databaseId);
            return response;
        } catch (SQLiteException e) {
            throw new JsonRpcException(
                    new JsonRpcError(JsonRpcError.ErrorCode.INVALID_REQUEST, e.toString(), null /* data */));
        }

    }

    @ChromeDevtoolsMethod
    public JsonRpcResult executeSQL(JsonRpcPeer peer, JSONObject params) {

        ExecuteSQLRequest request = mObjectMapper.convertValue(params, ExecuteSQLRequest.class);

        String databaseId = request.databaseId;

        if (mProvidersPeerManager.contains(databaseId)) {
            return executeSQL(databaseId, request.query);
        }

        return mModuleDatabaseDelegator.executeSQL(peer, params);
    }

    private JsonRpcResult executeSQL(String databaseId, String query) {

        ExecuteSQLResponse response = new ExecuteSQLResponse();

        try {

            QueryResolver queryResolver = new QueryResolver(query);
            String tableName = queryResolver.tableName;

            String[] columns = mProvidersPeerManager.getColumns(databaseId, tableName);
            List<? extends Entity> entities = mProvidersPeerManager.getEntites(databaseId, tableName, query);

            response.columnNames = Arrays.asList(columns);
            response.values = flattenRows(columns, entities);

        } catch (Exception e) {
            Error error = new Error();
            error.message = e.getMessage();
            error.code = 8000;
            response.sqlError = error;
        }

        return response;
    }

    private List<Object> flattenRows(String[] columns, List<? extends Entity> entities) {
        List<Object> rows = new ArrayList<Object>();
        for (Entity entity : entities) {
            rows.addAll(Entity.getFlattenedValues(columns, entity));
        }
        return rows;
    }

    static class QueryResolver {

        // #events:schema
        // #events:col=aas,add:id=100:orderby=aas:limit=100

        String tableName;
        String whereId;

        public QueryResolver(String query) {
            query = query.toLowerCase();
            if (query.startsWith("#")) {
                // example: #events:id=100
                tableName = query.substring(1, query.indexOf(":"));
                whereId = query.substring(query.indexOf("=") + 1);
            } else {
                tableName = query.split("\"")[1];
            }
        }
    }

    private static class GetDatabaseTableNamesRequest {
        @JsonProperty(required = true)
        public String databaseId;
    }

    private static class GetDatabaseTableNamesResponse implements JsonRpcResult {
        @JsonProperty(required = true)
        public List<String> tableNames;
    }

    private static class ExecuteSQLRequest {
        @JsonProperty(required = true)
        public String databaseId;

        @JsonProperty(required = true)
        public String query;
    }

    private static class ExecuteSQLResponse implements JsonRpcResult {
        @JsonProperty
        public List<String> columnNames;

        @JsonProperty
        public List<Object> values;

        @JsonProperty
        public Error sqlError;
    }

    private static class AddDatabaseEvent {
        @JsonProperty(required = true)
        public DatabaseObject database;
    }

    private static class DatabaseObject {
        @JsonProperty(required = true)
        public String id;

        @JsonProperty(required = true)
        public String domain;

        @JsonProperty(required = true)
        public String name;

        @JsonProperty(required = true)
        public String version;
    }

    private static class Error {
        @JsonProperty(required = true)
        public String message;

        @JsonProperty(required = true)
        public int code;
    }

}