sqldecodefluentvaporraw

How Do I Access Data in SQLRow object in Vapor/Fluent?


I am running raw sql queries in a Vapor app in a Fluent context.

The output I am getting for the object I'm interested in looks like:

(lldb) po words
▿ _PostgresSQLRow
  ▿ randomAccessView : PostgresRandomAccessRow
    ▿ columns : 1 element
      ▿ 0 : Column
        - name : "count"
        - tableOID : 0
        - columnAttributeNumber : 0
        ▿ dataType : BIGINT
          - rawValue : 20
        - dataTypeSize : 8
        - dataTypeModifier : -1
        - format : binary
    ▿ cells : 1 element
      ▿ 0 : Optional<ByteBuffer>
        ▿ some : ByteBuffer { readerIndex: 0, writerIndex: 8, readableBytes: 8, capacity: 8, storageCapacity: 1024, slice: _ByteBufferSlice { 59..<67 }, storage: 0x000000010404bc00 (1024 bytes) }
          ▿ _storage : <_Storage: 0x600001705900>
          - _readerIndex : 0
          - _writerIndex : 8
          ▿ _slice : _ByteBufferSlice { 59..<67 }
            - upperBound : 67
            ▿ _begin : 59
              ▿ _backing : 2 elements
                - .0 : 0
                - .1 : 59
    ▿ lookupTable : 1 element
      ▿ 0 : 2 elements
        - key : "count"

Specifically, I want the "count" value in the lookupTable at the bottom.

The query is just a dummy to test with, but it looks like this:

        guard let postgres = db as? SQLDatabase else  { return nil }
        return try await postgres.raw("SELECT count(*) FROM words").first().map { row in

This will eventually be expanded to include a bunch of dynamic regex queries, but this is just to get the basic technique returning values.

So, the data is there, but how do I extract the count value from it?


Solution

  • First, you need to create a structure into which you can decode the result:

    struct CountResult: Decodable {
       let wordscount: Int
    }
    

    Then, modify your code:

    let count = try await postgres.raw("SELECT count(*) AS wordscount FROM words").first(decoding: CountResult.self)
    

    The alias of the column name makes life easier.