Circumflex Blog

web framework, object-relational mapper and other cool things for Scala

1 note &

Circumflex & Milton

Hi guys!

It’s been a while since the last post. We are working hard. Today I want to announce our helper project, circumflex-milton. It allows easy integration with Milton WebDAV Server Library for Java. It aims to be the most lightweight Scala solution for accessing your structural data using WebDAV protocol. The most awesome fact about circumflex-milton is that it actually makes resource resolution process as much fun as writing routers for Circumflex Web Framework application. Just look at the code from our README:

package com.myapp
import ru.circumflex.milton._

class MiltonRouter extends WebDAVRouter {
  uri("/") = RootResource
  uri("/orders/?") = new OrdersRootResource()
  uri("/orders/:orderId") = new OrderResource(param("orderId"))
}

See? The same routing stuff! Though, due to complexity of WebDAV spec, you’ll probably have some time implementing FileResource and FolderResource for the needs of your domain model, and probably stuck inside providing Digest Authentication for the most annoying WebDAV clients who can’t talk to HTTPS servers with Basic Authentication. Still, you’ll be able to get your WebDAV server up and running in a couple of hours (well, maybe days if stuff won’t go that smoothly).

I hope you’ll get even more fun developing with Circumflex!

DISCLAIMER: Circumflex Milton is a very young project. For now we have some problems with sending non-standard status codes as well as more WebDAV-specific stuff. I’m sure we’ll get on that very soon, but you must be warned. Have fun!

0 notes &

Boolean matching in routes

Frankly, me and my fellow team members were sure that this stuff is useless. But latest comparison shows that we are actually loosing some points in this “find-the-difference-game”, so we finally decided to… emm… borrow the idea of arbitrary boolean matching into Circumflex. Here’s how it looks like:

get("/namecode/:name")
    .and(param("name").startsWith("Ch")) = "You passed our namecode."

get("/namecode/:name") = "Never heard of '" + param("name") + "' before. Get lost!"

You can chain as many .and(...) as you want, using either regular matchers or boolean expressions. Each one will be evaluated only if all previous matches succeed. And moreover, each .and(...) section can reference match results from previous ones (our example shows how).

Cheers!

0 notes &

Circumflex 2.0.RC3 Release

Hi guys! We are happy to announce that Circumflex 2.0.RC3 has just been released. Two more modules found their home among Circumflex projects: circumflex-markeven and circumflex-scalate.

Circumflex Markeven

For a long time we have enjoyed Markdown, an infamous text-to-html tool for writers. We even made our own port for Scala, formerly known as circumflex-md. As 2011 approaches and we are sitting in front of our Macs scratching our heads in desperate search for new ways to get some development fun, we realize that Markdown implementation is cool, but apparently not cool enough. No, really, walking thousand times with huge regexes over big articles is really an overkill. And some environments can’t rely on caching, making the whole beauty of Markdown ideas fade.

So, we brought you an Xmas present: Circumflex Markeven. Here’s a brief list of its features.

  • It is at least 6 times faster than our circumflex-md.
  • It is more structured (indents are now more important in lists).
  • It has more strict syntax (whenever Markdown allows you several alternatives to write stuff, we leave only one).
  • It supports tables and divs.
  • It has a neat syntax to assign HTML id and class attributes to any block-level element.
  • It has basic typographic enhancements and we plan to add more.
  • It offers easy way to extend its capabilities with macros.

Circumflex Scalate Integration

Circumflex Web Applications can now take advantage of Scalate Template Engine. Since Scalate is fairly easy to embed into any environment, the solution is quick-and-dirty. You are welcome to contribute if you find out something missing.

0 notes &

Markdown Tables

We are happy to announce that our bleeding edge Circumflex 2.0 Markdown implementation now supports tables. The syntax, however, differs from the one defined in PHP Markdown Extra: the table must start and end with at lest two minus signs (--). Of course, as with other block-level elements, it must be separated from other content with at least two line breaks.

Some brief examples:

-------------------------
|  Product   |  Price   |
|------------|----------|
|  Banana    |  $2      |
|  Apple     |  $1.5    |
|  Peach     |  $2.5    |
-------------------------

---------------
Product | Price
---------------
Banana  | $2
Apple   | $1.5
Peach   | $2.5
---------------

You can specify column alignment using colons (:) in the separator line (at left side for left alignment, at the right side for right alignment, at both sides for center alignment):

-------------------------
|  Product   |  Price   |
|:----------:|---------:|
|   Banana   |       $2 |
|    Apple   |     $1.5 |
|    Peach   |     $2.5 |
-------------------------

You can also give id attribute to your table:

---------------   {#mytable}
Product | Price
---------------
Banana  | $2
Apple   | $1.5
Peach   | $2.5
---------------

If you like your table being sized to whole page (width: 100%), but too lazy to apply css, just add a greater-than sign to the end of the first line of your table (but before id specificator, if any):

-------------->   {#mytable}
Product | Price
---------------
Banana  | $2
Apple   | $1.5
Peach   | $2.5
---------------

You are welcome to play with our Markdown implementation online.

0 notes &

2.0 is coming

My dear friends, I am happy to announce the first successful build of an entire Circumflex 2.0 suite! There are a lot of changes in 2.0, some of which will require you to revisit your code. We thank you for your patience and we are sorry for all inconveniences: it is probably the cost of innovation and establishing maturity. I’m sure you won’t run into problems with these changes, though, I want to assure you that the API became stable enough and that no more big reorganizations surprises await your application code in the near future.

You can start using Circumflex 2.0 right now, it’s in a separate branch at GitHub. The release, however, will be made only when the proper source documentation level is achieved, as well as when all subtle issues are resolved. Until then you are free to share your ideas and opinions with us!

0 notes &

Circumflex ORM 2.0 Reorganization

Well, it’s been quite an effort to develop an SQL-like DSL for data access for Scala. The model we’ve came up to is already good and beautiful, but I’ve summarized all the issues (custom PK types, cyclic dependency problems between Record and Relation, evaluation of uuids on each record instantiation, etc.) and I think we cannot maintain this model as it is anymore.

The main issue is of course the Record-Relation cyclic dependency (the so-called chicken-or-the-egg issue of Circumflex ORM 1.1). I don’t think it’s been raised by the community, so I’ll explain a bit. In short, we have two abstractions, Relation and Record. Relations are meant to be singletons, which produce record instances. In turn, records need to be aware of their relation. That’s fine. Now in order to build predicates in a DSL fashion, we need to reference fields declared in records from relation-level scope:

val co = Country as "co"   // give our table an SQL alias
co.name EQ "United Kingdom"  // construct a predicate

In the example above name field is declared inside record, not inside relation. So how does this compile and work? It’s because we use some magic here. Internally, every relation instantiates a sample record inside during it’s initialization. Relation then can be implicitly converted into Record to point to it’s fields (there are actually lots of things we do about this recordSample, but they do not matter for now). Now the issue. Because initialization code of relation instantiates a record, you cannot reference this relation inside record’s initialization block. Try it:

class Country extends Record[Country] {
  println(Country.toString)
}

object Country extends Table[Country]

You’ll get NullPointerException as soon as you attempt to access either the Country singleton or instantiate the Country record.

Why would you use the relation object inside record? This question is out of my scope. The only thing that matters is the fact that you can’t do that. It’s a limitation. And we should get rid of it at any cost.

Fortunately, I’ve came up with a solution, but the cost is significant. It will require not only complete library rewriting, but will also eliminate all backward compatibility of users code. The data definition code will look like that:

class Country extends Record[Country](Country) { ... }

object Country extends Country with Table[Long, Country]

You see, the Country singleton now extends Country itself, thus it has all it’s fields (this eliminates the need for implicit conversions when constructing predicates). This approach also eliminates that notorious cyclic dependency problem.

But apart from the hard work on complete rewriting and backward compatibility problems, there are some open questions on this solution.

  • Since relation extends record now, it will inherit ambiguous methods applicable only to record instances (such as insert, update or delete) — what should we do with them? Throw exceptions?

  • Just like with recordSample, assignment to the fields of the relation does not make any sense:

    Country.name := "New Zealand"    // wut?
    
  • It is even possible to mistakenly add a relation into the collection of records and include it into mass processing which would make absolutely no sense (and possibly introduce runtime errors):

    var countries = Country.all()
    countries ++= List(Country)
    countries.foreach { c =>
      c.code := c.code().toLowerCase    // no sense for relation
      c.update    // unacceptable for relation
    }
    

That’s kinda it, thanks for your attention. I would appreciate all your opinions and ideas.

0 notes &

Context API

Hi, friends and colleagues!

As I’ve mentioned before in Circumflex 2.0 we are planning to introduce Context API.

So, what is context? Essentially it is a ThreadLocal storage which allows you to share objects within a logical scope. Such logical scope could be anything: database transaction, HTTP request, user session within GUI form, etc.

Context is a rather common concept in programming. It lets you avoid passing too much parameters between collaborating classes (remember plain-old Servlet API where you had to pass explicitly HttpServletRequest and HttpServletResponse between controllers).

Let’s take a lot at some sample code:

class MyServlet extends HttpServlet {
  override def doGet(req: HttpServletRequest, res: HttpServletResponse) = {
    new MyController1(req, res)
    val c = new MyController2
    c.doWork(req, res)
    c.doMoreWork(req, res)
  }
}

class MyController1(req: HttpServletRequest, res: HttpServletResponse) { ... }

class MyController2 {
  def doWork(req: HttpServletRequest, res: HttpServletResponse) = { ... }
  def doMoreWork(req: HttpServletRequest, res: HttpServletResponse) = { ... }
}

This snippet shows a servlet which passes request and response objects into two controllers. You see, controllers declare that they depend on HttpServletRequest and HttpServletResponse using their constructors and method parameters. If you have thousands of controllers which are executed inside web application and must be aware of request and response, these boilerplates become really annoying. The same could be done using contexts:

class MyServlet extends HttpServlet {
  override def doGet(req: HttpServletRequest, res: HttpServletResponse) = {
    ctx("request") = req
    ctx("response") = res
    new MyController1()
    val c = new MyController2
    c.doWork()
    c.doMoreWork()
    Context.destroy
  }
}

class MyController1 { ... }

class MyController2 {
  def doWork = { ... }
  def doMoreWork = { ... }
} 

You see, the code of servlet becomes a little more complex: context initialization and context destruction are required to define a logical scope, but controllers become much simpler. Since it is clear that controllers are only executed inside context scope, they can use context variables request and response inside their code.

There is, however, one important downside of this approach: classes that rely on context (i.e. expect a context to contain necessary parameters) are harder to debug since they do not “show” their dependencies to the world via public constructors or method parameters. The documentation of such classes should always reflect their expectations about the contents of context.

Circumflex Context API is as simple as one-two-three sequence.

  1. The boundaries of context scope are set using Context.init and Context.destroy. The latter step is extremely mandatory. If threads are reused using some kind of thread pool, finalization ensures that context does not contain orphaned data from previous owners. Circumflex Web Framework, for example, performs context initialization and finalization using CircumflexFilter, it also injects HttpRequest and HttpResponse into context. You can also add listeners for context initialization and finalization events:

    Context.addInitListener(c => println("Context initialized."))
    Context.addDestroyListener(c => println("Context destroyed."))
    

    Circumflex ORM 2.0, for example, uses this approach to ensure that all data access within context scope is performed within a single database transaction without having to redefine the scope of the context.

    The last thing to know about context lifecycle is that it is initialized implicitly on first access if it hasn’t been initialized before.

  2. You can work with current context from any code that is ran inside it’s scope. You simply call Context.get (or a shortcut, the ctxmethod of package object ru.circumflex.core). Context extends mutable Scala map, so it should be already familiar to you:

    // set context variable
    ctx("key") = value
    // access context variable
    ctx.get("key") match {
      case Some(v: MyExpectedType) => ...
      case _ => ...
    }
    

    You can also rewrite the above snippet using nice and handy DSL:

    // set context variable
    'key := value
    // access context variable
    'key.get match {
      case Some(v: MyExpectedType) => ...
      case _ => ...
    }
    
  3. You can configure Circumflex to work with your own context implementation:

    package com.myapp
    
    class MyContext extends Context {
      def myUsefulContextScopedMethod = {...}
    }
    
    object MyContext {
      def get: MyContext = Context.get.asInstanceOf[MyContext]
    }
    

    Then simply override cx.context configuration parameter:

    cx.context=com.myapp.MyContext
    

    And access your own context from your code:

    MyContext.get.myUsefulContextScopedMethod
    

To summarize, there are a lot of things you can do with context. For example, we pass context object as a root data object to Freemarker templates so that you can pass your variables from request routers to views.

Now enough reading. Go and create some software masterpiece with Circumflex. Good luck :)