0

UPDATE: The error regarding Projection vs ColumnBase has been resolved however I'm still running into issues the overloaded insert method. The code has been updated to reflect this.


I'm trying to write my first moderately complicated Scala program. I'd like it to read values from my Twitter timeline and write them into a postgres table.

I'm using twitter4j for the Twitter connection and Slick to write the data into postgres, however I'm getting two compile errors:

Error:

[error] /Users/trenthauck/Dropbox/Code/twitter-api/src/main/scala/org/trenthauck/TwitterApi.scala:45: overloaded method value insert with alternatives:
[error]   [TT](query: scala.slick.lifted.Query[TT,org.trenthauck.Timeline])(implicit session: scala.slick.session.Session)Int <and>
[error]   (value: org.trenthauck.Timeline)(implicit session: scala.slick.session.Session)Int
[error]  cannot be applied to (java.util.Date, Int, String)
[error]       Timeline.insert(date, id, text)
[error]                ^
[error] one error found
[error] (compile:compile) Compilation failed

My Slick Definition in file DatabaseApi.scala:

package org.trenthauck

import slick._
import scala.slick.driver.PostgresDriver.simple._
import Database.threadLocalSession

import java.sql.Date

case class Timeline (date: Date, id: Long, text: String)

object Timeline extends Table[Timeline]("timeline") {
  def date = column[Date]("date")
  def id = column[Long]("id")
  def text = column[String]("text")
  def * = date ~ id ~ text <> (Timeline.apply _, Timeline.unapply _)
}

My Twitter Definition in file TwitterApi.scala:

package org.trenthauck

import twitter4j._

import slick._
import scala.slick.driver.PostgresDriver.simple._
import Database.threadLocalSession

trait TwitterInstance {
  val consumerKey = ""
  val consumerSecret = ""
  val accessToken = ""
  val accessSecret = ""

  val cb = new conf.ConfigurationBuilder()

  cb.setOAuthConsumerKey(consumerKey)
    .setOAuthConsumerSecret(consumerSecret)
    .setOAuthAccessToken(accessToken)
    .setOAuthAccessTokenSecret(accessSecret)

  val twitter = new TwitterFactory(cb.build()).getInstance

}

class Twitter extends TwitterInstance {
  //get timeline
  def getUserTimeline() = twitter.getUserTimeline()

  //insert tweets
  def insertTweets() = {
    val tweets = this.getUserTimeline.iterator
    implicit val session = Database.forURL("jdbc:postgres//localhost/twitter",
                                            driver="org.postgresql.Driver",
                                            user="trenthauck")
    session withTransaction {

      Timeline.ddl.create

      while(tweets.hasNext) {
        var tweet = tweets.next
        Timeline.insert(tweet.getCreatedAt, tweet.getId, tweet.getText)
      }
    }
  }
}

The connection to twitter seems to work just fine, it's inserting the data into the timeline table that's causing issues.

Thanks

0

3 Answers 3

1

You need to define the mapping for Timeline class. Try this..

def * = date ~ id ~ text <> (Timeline.apply _, Timeline.unapply _)
Sign up to request clarification or add additional context in comments.

1 Comment

thanks (+1), that resolved the issue concerning the projection vs column base however the overloading issue still exists.
0

What vidit posted means that you're mapping the default projection to the Timeline case class, so your insert should be using the case class instead of a raw tuple.

However, since your code sample defines the case class and the table to have the same name, it will probably still error out. I recommend you at least rename your table, and then your insert would look something like TimelineTable.insert(Timeline(tweet.getCreatedAt, tweet.getId, tweet.getText))

Comments

0

Change mapper object from: object Timeline

to: object Timelines

and then do Timelines.insert(...)

The built-in companion object of case class Timeline interferes with Slick functionality.

Look at all the example code in Slick docs, the companion object is always pluralized, or removed entirely, using plain class/instantiation instead.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.