All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gabrielittner.github.diff.DatastoreStorage.kt Maven / Gradle / Ivy

There is a newer version: 0.8.0
Show newest version
package com.gabrielittner.github.diff

import com.google.auth.oauth2.GoogleCredentials
import com.google.cloud.Timestamp
import com.google.cloud.datastore.DatastoreOptions
import com.google.cloud.datastore.Entity
import com.google.cloud.datastore.EntityValue
import com.google.cloud.datastore.NullValue
import com.google.cloud.datastore.StringValue
import com.google.cloud.datastore.Value
import com.google.common.collect.ImmutableSortedMap
import com.google.common.collect.ImmutableSortedSet
import com.google.gson.JsonParser
import java.util.AbstractMap

class DatastoreStorage(credentials: String) : Storage {

    private val projectId = JsonParser().parse(credentials).asJsonObject.get("project_id").asString
    private val googleCredentials = GoogleCredentials.fromStream(credentials.byteInputStream())
    private val datastore = DatastoreOptions.newBuilder()
            .setProjectId(projectId)
            .setCredentials(googleCredentials)
            .build()
            .service
//    private val storage = StorageOptions.newBuilder()
//            .setProjectId(projectId)
//            .setCredentials(googleCredentials)
//            .build()
//            .service

    override fun loadApk(name: String, commit: String?): Apk? {
        if (commit != null) {
            val commitKey = datastore.newKeyFactory().setKind(KIND).newKey("$commit-$name")
            val entity = datastore.get(commitKey)
            if (entity != null) {
                check(commit == entity.getString(COMMIT))
                check(name == entity.getString(NAME))
                val fileSize = entity.getLong(FILE_SIZE).toInt()
                val methodCount = entity.getLong(METHOD_COUNT).toInt()
                val fieldCount = entity.getLong(FIELD_COUNT).toInt()
                val permissions = entity.getList(PERMISSIONS).map { it.get() }
                val features = entity.getList(FEATURES).map { it.getEntry() }
                val featuresNR = entity.getList(FEATURES_NOT_REQUIRED).map { it.get() }
//                val bucket = storage.get("$KIND-$projectId")!!
//                val methods = bucket.load(commit, name, METHODS)?.split("\n") ?: emptyList()
//                val fields = bucket.load(commit, name, FIELDS)?.split("\n") ?: emptyList()
//                val manifest = bucket.load(commit, name, MANIFEST)!!
                return Apk(
                        commit,
                        name,
                        fileSize,
                        methodCount,
                        fieldCount,
                        ImmutableSortedSet.copyOf(permissions),
                        ImmutableSortedMap.copyOf(features),
                        ImmutableSortedSet.copyOf(featuresNR),
                        ImmutableSortedSet.of(), // ImmutableSortedSet.copyOf(methods),
                        ImmutableSortedSet.of(), // ImmutableSortedSet.copyOf(fields),
                        "" // manifest
                )
            }
        }
        return null
    }

    override fun save(commit: String, apk: Apk) {
        val key = datastore.newKeyFactory().setKind(KIND).newKey("$commit-${apk.name}")
        val task = Entity.newBuilder(key)
                .set(COMMIT, commit)
                .set(NAME, apk.name)
                .set(FILE_SIZE, apk.fileSize.toLong())
                .set(METHOD_COUNT, apk.fieldCountInt.toLong())
                .set(FIELD_COUNT, apk.fieldCountInt.toLong())
                .set(PERMISSIONS, apk.permissions.map { it.toValue() })
                .set(FEATURES, apk.features.map { it.toValue() })
                .set(FEATURES_NOT_REQUIRED, apk.featuresNot.map { it.toValue() })
                .set(TIME, Timestamp.now())
                .build()
        datastore.put(task)

//        val bucket = storage.get("$KIND-$projectId")!!
//        bucket.save(commit, apk.name, METHODS, apk.methods.joinToString("\n"))
//        bucket.save(commit, apk.name, FIELDS, apk.fields.joinToString("\n"))
//        bucket.save(commit, apk.name, MANIFEST, apk.manifest)
    }

    private fun String?.toValue(): Value<*> {
        if (this == null) {
            return NullValue.newBuilder().setExcludeFromIndexes(true).build()
        }
        return StringValue.newBuilder(this).setExcludeFromIndexes(true).build()
    }

    private fun Map.Entry.toValue(): Value<*> {
        val entity = Entity.newBuilder().set("1", key.toValue()).set("2", value.toValue()).build()
        return EntityValue.newBuilder(entity).setExcludeFromIndexes(true).build()
    }

    private fun EntityValue.getEntry(): Map.Entry {
        val entity = get()
        return AbstractMap.SimpleEntry(entity.getString("1"), entity.getString("2"))
    }

//    private fun Bucket.save(commit: String, name: String, property:String, value: String) {
//        val content = value.compress().inputStream()
//        create("$commit-$name-$property", content, "text/plain")
//    }
//
//    private fun Bucket.load(commit: String, name: String, property:String): String? {
//        return get("$commit-$name-$property")?.getContent()?.decompress()
//    }
//
//    private fun String.compress(): ByteArray {
//        ByteArrayOutputStream().let {
//            GZIPOutputStream(it).use { it.write(this.toByteArray()) }
//            return it.toByteArray()
//        }
//    }
//
//    private fun ByteArray.decompress(): String {
//        inputStream().let { GZIPInputStream(it) }.bufferedReader().use {
//            return it.readText()
//        }
//    }

    companion object {
        const val KIND = "apk"
        const val COMMIT = "commit"
        const val NAME = "name"
        const val FILE_SIZE = "file-size"
        const val PERMISSIONS = "permissions"
        const val FEATURES = "uses-feature"
        const val FEATURES_NOT_REQUIRED = "uses-feature-not-required"
        const val METHODS = "methods"
        const val METHOD_COUNT = "method-count"
        const val FIELDS = "fields"
        const val FIELD_COUNT = "field-count"
        const val MANIFEST = "manifest"
        const val TIME = "timestamp"
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy