代码之家  ›  专栏  ›  技术社区  ›  Leff

正在从auth0获取用户名的最新值

  •  0
  • Leff  · 技术社区  · 4 年前

    我以前从未和科特林合作过,所以我有一个新手问题。我正在使用现有的代码库,所以我想知道一些事情。我看到有一个函数 看起来是这样的:

    fun getDepartmentById(ctx: Ctx, params: JsonObject): Either<Failure, FlatResp> =
        getOneByIdFlattened(ctx, params.right(), getDepartmentByIdSql(ctx), flattenOne = flattenerToType(MainAccessType.DEPARTMENT))
    
    fun getDepartmentById(ctx: Ctx, id: Long): Either<Failure, FlatResp> =
        getDepartmentById(ctx, jsonObject("id" to id))
    

    调用该函数将返回Failure或FlatResp。从代码中我可以看到 平坦响应 typealias是 Map<MainAccessType, Entities>

    功能 GetOneByIdFlatten 看起来像这样:

    fun getOneByIdFlattened(ctx: Ctx,
                            params: Either<Long, JsonObject>,
                            statement: String,
                            rowConverter: (Row) -> Map<String, Any?> = ::mapFromDbNames,
                            grouper: (List<Map<String, Any?>>) -> List<Map<String, Any?>> = ::identity,
                            flattenOne: (List<Map<String, Any?>>) -> FlatResp
    ): Either<Failure, FlatResp> =
        either.eager {
          val id = when (params) {
            is Either.Left -> Either.Right(params.value)
            is Either.Right -> params.value.idL?.right()
                ?: Failure.JsonError(SErr(GlowErrs.MISSING_ID, "You must provide id")).left()
          }.bind()
    
          val dbDataList: List<Map<String, Any?>> = doQuery(ctx, statement, mapOf(
              "courierIds" to ctx.user.courierIds,
              "id" to id,
              "count" to 1,
              "offset" to 0,
              "departmentIds" to ctx.userDepartments,
              "customerIds" to ctx.user.customerIds
          ),
              rowConverter, false
          ).bind()
          val result = flattenOne(grouper(dbDataList))
          addUpdatedAtEpoch(result)
        }
    

    enter image description here

    举个例子,如果我想 name 另外,我想知道为什么这个函数返回一个集合,而不仅仅是一个对象,而它应该从DB中按id获取一行?

    private fun getDepartmentByIdSql(ctx: Ctx) =
        """select ${createSelectFields(departmentKeys)}
            from department dept
            where dept.id = :id
      ${
          when (ctx.user.role) {
            UserRoles.ADMIN -> ""
            else -> "and dept.id = any (:departmentIds) "
          }
        }"""
    
    0 回复  |  直到 3 年前
        1
  •  1
  •   ansh sachdeva    3 年前

    因此,在提供的代码片段中有很多错误。给定的代码片段:

    • 1.
    fun getDepartmentById(ctx: Ctx, params: JsonObject): Either<Failure, FlatResp> =
        getOneByIdFlattened(ctx, params.right(), getDepartmentByIdSql(ctx), flattenOne = flattenerToType(MainAccessType.DEPARTMENT))
    
    • 2.
    fun getDepartmentById(ctx: Ctx, id: Long): Either<Failure, FlatResp> =
        getDepartmentById(ctx, jsonObject("id" to id))
    
    private fun getDepartmentByIdSql(ctx: Ctx) =
        """select ${createSelectFields(departmentKeys)}
            from department dept
            where dept.id = :id
      ${
          when (ctx.user.role) {
            UserRoles.ADMIN -> ""
            else -> "and dept.id = any (:departmentIds) "
          }
        }"""
    
    • 4.
    fun getOneByIdFlattened(ctx: Ctx,
                            params: Either<Long, JsonObject>,
                            statement: String,
                            rowConverter: (Row) -> Map<String, Any?> = ::mapFromDbNames,
                            grouper: (List<Map<String, Any?>>) -> List<Map<String, Any?>> = ::identity,
                            flattenOne: (List<Map<String, Any?>>) -> FlatResp
    ): Either<Failure, FlatResp> =
        either.eager {
          val id = when (params) {
            is Either.Left -> Either.Right(params.value)
            is Either.Right -> params.value.idL?.right()
                ?: Failure.JsonError(SErr(GlowErrs.MISSING_ID, "You must provide id")).left()
          }.bind()
    
          val dbDataList: List<Map<String, Any?>> = doQuery(ctx, statement, mapOf(
              "courierIds" to ctx.user.courierIds,
              "id" to id,
              "count" to 1,
              "offset" to 0,
              "departmentIds" to ctx.userDepartments,
              "customerIds" to ctx.user.customerIds
          ),
              rowConverter, false
          ).bind()
          val result = flattenOne(grouper(dbDataList))
          addUpdatedAtEpoch(result)
        }
    
    

    问题:

    1. 在片段2中, jsonObject 应该是 JsonObject(..)
    2. 我不知道下面几行是怎么做的:
    //snippet1:  
    flattenOne = flattenerToType(MainAccessType.DEPARTMENT)) 
    
    
    //snipper 4
    either.eager {...block...}
    addUpdatedAtEpoch(result)
    doQuery(ctx, statement, mapOf(..)
    
    //snippet3
    UserRoles.ADMIN -> ""
    """select ${createSelectFields(departmentKeys)}
    
    

    anko splitties . 另外,这些是与您自己的类的函数调用的混合,如 createSelectFields ctx.user.courierIds . 另外,如果我不得不猜测的话,那么这似乎是在sql dB上执行某些操作的一种不寻常的方式

    
    
    class  Entities
    typealias  FlatResp = Map<MainAccessType, Entities>
    
    class Ctx
    sealed class Either<A,B>(val a:A?, val b:B?){
        val value:A? = null
    
        class Left<A>(val aa:A):Either<A,A>(aa,aa)
        class Right<B>(val bv:B):Either<B,B>(bb,bb)
    }
    class Failure
    class Row
    class JsonObject(val pair:Pair<String,Long>):JSONObject(){
        fun right():Either<Long,JsonObject>{
        }
    }
    class jsonObject()
    enum class MainAccessType{DEPARTMENT}
    
    fun getDepartmentById(ctx: Ctx, params: JsonObject): Either<Failure, FlatResp> {
        return getOneByIdFlattened(
            ctx,
            params.right(),
            getDepartmentByIdSql(ctx),
            flattenOne = flattenerToType(MainAccessType.DEPARTMENT))
    }
    
    fun getDepartmentById(ctx: Ctx, id: Long): Either<Failure, FlatResp> {
        return getDepartmentById(ctx, JsonObject("id" to id))
    }
    
    fun getOneByIdFlattened(ctx: Ctx,
                            params: Either<Long, JsonObject>,
                            statement: String,
                            rowConverter: (Row) -> Map<String, Any?> = ::mapFromDbNames,
                            grouper: (List<Map<String, Any?>>) -> List<Map<String, Any?>> = ::identity,
                            flattenOne: (List<Map<String, Any?>>) -> FlatResp
    ): Either<Failure, FlatResp> {
        return either.eager {
            val id = when (params) {
                is Either.Left -> Either.Right(params.value)
                is Either.Right -> params.value.idL?.right()
                    ?: Failure.JsonError(SErr(GlowErrs.MISSING_ID, "You must provide id")).left()
            }.bind()
    
            val dbDataList: List<Map<String, Any?>> = doQuery(ctx, statement, mapOf(
                "courierIds" to ctx.user.courierIds,
                "id" to id,
                "count" to 1,
                "offset" to 0,
                "departmentIds" to ctx.userDepartments,
                "customerIds" to ctx.user.customerIds
            ),
                rowConverter, false
            ).bind()
            val result = flattenOne(grouper(dbDataList))
            addUpdatedAtEpoch(result)
        }
    }
    
    private fun getDepartmentByIdSql(ctx: Ctx) =
        """select ${createSelectFields(departmentKeys)}
            from department dept
            where dept.id = :id
      ${
            when (ctx.user.role) {
                UserRoles.ADMIN -> ""
                else -> "and dept.id = any (:departmentIds) "
            }
        }"""
    
    fun mapFromDbNames(row:Row): Map<String,Any?>{
    
    }
    
    fun identity(param : List<Map<String, Any?>>): List<Map<String, Any?>>{
    
    }
    
    

    这仍然是不正确的,并且有很多红线。但您可以做的是将其作为启动程序保存在一个单独的文件中,相应地比较和修复代码,然后也许我们可以告诉您更好的方法:

    1. 替换内联函数( fun xyz(...) = someValue
    2. 直接使用map而不是typeAlias
    3. ::something 表示函数作为参数传递。它类似于我们在Java8中传递Runnable的方式,但更为简捷。您可以在该函数上执行ctrl+click(对于mac及其cmd+click),然后转到该函数以检查其参数和返回类型。对不同的类/扩展函数和变量也执行相同的操作。 这将最有帮助
    4. 而不是将某个东西传递给另一个东西(比如 val bot = Robot(Petrol("5Litres") ) val amount = "5litres"; val equipment = Petrol(amount) ; val bot = Robot(equipment) )
    5. 尽量不要使用第三方库/替换为您自己可以理解的代码。
    6. 重复步骤1-5

    希望这能给我们一个开始。kotlin是一种美丽的语言,但也很容易让人看不懂。

        2
  •  0
  •   aSemy    3 年前

    映射 Map 价值观

    我想知道如何从平面图中获得对象的属性,如下所示:

    enter image description here

    例如,如果我只想从这个对象中获取名称,那么最好的方法是什么?

    TL;博士

    在没有数据的情况下,我想:

    val extractedNames: Map<Long, String?> = destinationDepartment
      .mapValues { (_, userData: Map<String, Any?>) ->
        when (val name = userData["name"]) {
          is String -> name
          else      -> null
        }
      }
    println(extractedNames)
    // {1=Bergen, 2=Cindy, 3=Dave}
    

    简介

    Kotlin非常适合处理集合。对于如何在Kotlin中使用集合的更一般的了解,我认为文档非常清楚 Collection transformation operations#Map .

    让我们看看这个例子是如何工作的。您想要提取一个特定的元素,因此我们可以使用 map() .

    Map<Long, Map> ,其中值为 Map<String, Any?> . 我想你是想换个房间 地图<长,地图> Map<Long, String> ,其中键是数据库ID,值是用户名。

    测试数据

    所以我有一些东西要测试,我做了一个新的 地图 :

    val destinationDepartment: Map<Long, Map<String, Any?>> =
      mapOf(
        1L to mapOf(
          "id" to 1,
          "name" to "Bergen",
          "createdAt" to LocalDateTime.now(),
          "updatedAt" to LocalDateTime.now(),
        ),
        2L to mapOf(
          "id" to 2,
          "name" to "Cindy",
          "createdAt" to LocalDateTime.now(),
          "updatedAt" to LocalDateTime.now(),
        ),
        3L to mapOf(
          "id" to 3,
          "name" to "Dave",
          "createdAt" to LocalDateTime.now(),
          "updatedAt" to LocalDateTime.now(),
        ),
      )
    

    基本节点

    Map 可以转换为 Entries 地图() ,它将在每个 Entry 地图 必须 返回一个新值。

    map.entrySet().stream().map(...)...

    在这里,lambda只返回一对(使用 to ).

    val extractedNames = destinationDepartment
      .map { (id: Long, userData: Map<String, Any?>) ->
        id to userData
      }
    println(extractedNames)
    // Output: [(1, {id=1, name=Bergen, createdAt=2021-08-19T11:00:07.447660, updatedAt=2021-08-19T11:00:07.449969}), 
    // (2, {id=2, name=Cindy, createdAt=2021-08-19T11:00:07.463813, updatedAt=2021-08-19T11:00:07.463845}), 
    // (3, {id=3, name=Dave, createdAt=2021-08-19T11:00:07.463875, updatedAt=2021-08-19T11:00:07.463890})]
    

    userData: Map<String, Any?> .

    
    val extractedNames = destinationDepartment
      .map { (id: Long, userData: Map<String, Any?>) ->
        val name = userData["name"]
        id to name
      }
    println(extractedNames)
    // Output: [(1, Bergen), (2, Cindy), (3, Dave)]
    

    现在有很多方法可以改进这一点。确保 name 是字符串,不是 Any? ,过滤掉空白或空名称,映射到DTO,排序。同样,Kotlin文档将是一个良好的开端。我将首先列出一个非常好的改进。

    转换 List<Pair<>> Map<>

    如果你看一下 val extractedNames ,您将看到它是一个列表,而不是一张地图。

    val extractedNames: List<Pair<Long, Any?>> = ...
    

    地图() 函数正在返回一个 Pair<Long, String> . 科特林不知道这仍然被认为是一个错误 地图 . 我们可以转换任何 列表<配对<&燃气轮机&燃气轮机; toMap()

    toMap()

    val extractedNames: Map<Long, Any?> = destinationDepartment
      .map { (id: Long, userData: Map<String, Any?>) ->
        val name = userData["name"]
        id to name
      }
      .toMap() // convert List<Pair<>> to a Map<>
    println(extractedNames)
    // Output: {1=Bergen, 2=Cindy, 3=Dave}
    

    但这也不是很好。为什么 id: Long 在lambda中,如果我们不使用它?因为我们只提取 名称 userData ,我们只是在映射 价值观 地图 . 我们不需要 id:长 完全幸运的是,Kotlin还有另一个有用的方法: mapValues() -它返回一个 ,这样我们就可以放下 toMap() . 让我们使用它。

    mapValues()

    val extractedNames: Map<Long, Any?> = destinationDepartment
      .mapValues { (id: Long, userData: Map<String, Any?>) ->
        val name = userData["name"]
        id to name
      }
    println(extractedNames)
    // {1=(1, Bergen), 2=(2, Cindy), 3=(3, Dave)}
    

    嗯,奇怪。为什么会这样 id 什么是价值观?那是因为 mapValues() 身份证件 名称 -哎呀!让我们只返回名称。

    固定

    val extractedNames: Map<Long, Any?> = destinationDepartment
      .mapValues { (_, userData: Map<String, Any?>) ->
        userData["name"]
      }
    println(extractedNames)
    // {1=(1, Bergen), 2=(2, Cindy), 3=(3, Dave)}
    

    较好的因为 没有使用, an underscore can be used instead

    return . 阅读 Returning a value from a lambda expression