SlideShare a Scribd company logo
* #sor09
Ruby sittin’ on the Couch
About me


• Alexander Lang
• Upstream Agile GmbH, Berlin
  programmer, owner
• http://upstream-berlin.com
11/52
Web development w/
      Ruby
BDD
Buzzword Driven
 Development
TDD
  BDD
                                   “agile”
Pair Programming


          * all the f****** time
About me

• playing with CouchDB since 09/2008
• helped hack the CouchDB statistics module
  (with @janl)
• wrote Couch Potato
• working on smaller production apps
Who are you?
Who is in this room?
• Chris Anderson
• George Palmer
• Paul Carey
• Johan Sørensen
• Cheah Chu Yeow/Carlos Villela
Who is in this room?
• Chris Anderson (couchrest + couchapp)
• George Palmer (couch_foo)
• Paul Carey (relaxdb)
• Johan Sørensen (couchbject)
• Cheah Chu Yeow/Carlos Villela (activecouch)
Forget it!
Agenda

• CouchDB introduction
• The CouchDB example wiki
• The frameworks
• Conclusion: where to go from here?
• Q &A
CouchDB introduction
What is CouchDB?
Apache Project
   so it has to be good
Document oriented
    Database
Store/read any JSON
     document
Powerful map/reduce
 views for querying*
     * we’ll see what that is
Why CouchDB?
Buzzword
compliant
JavaScript
REST
HTTP interface
JSON
Map/Reduce
the thing that made Google rich
Fun !
No more SQL/Schema/
    Migrations
JavaScript views instead
Simple!
HTTP interface
can use existing
clients, libraries
It scales
just like Ruby :)
No locks,
instead MVCC
integrated replication
      (yes, multi master)
use existing load
balancer, proxies etc.
        HTTP ftw
and so on...
So how does Couch work?
JSON
{
    _id: “some UUID”,
    _rev: “MVCC key”,
    title: “page one”
    body: “this is page one.”,
    tags: [“ruby”, “couchdb”, “sor09”]
    metadata: {created_at: “2009/03/28 06:34:00”,
      author: “alex”}
}
HTTP API

• POST ‘/my_db’, {my_json}
• GET ‘/my_db/my_document_id’
• PUT ‘/my_db/my_document_id’,
  {new_json}
• DELETE ‘/my_db/my_document_id’
Map/Reduce views

• views are documens
• provide a map (and optional reduce
  function) written in JavaScript
• this creates an index over all documents
• query that index via GET
Map/Reduce views
{
    title: “page one”,
    tags: [“first”, important”]
}

{
    title: “page 2”,
    tags: [“funny”]
}
Map/Reduce views
{                                function(doc) {
    title: “page one”,
                                   emit(doc.title, doc.tags.length)
    tags: [“first”, important”]
                                 }
}

{
    title: “page 2”,
    tags: [“funny”]
}
Map/Reduce views
{                                function(doc) {
    title: “page one”,
                                   emit(doc.title, doc.tags.length)
    tags: [“first”, important”]
                                 }
}
                                              key        value
{
                                           “page one”      2
    title: “page 2”,
    tags: [“funny”]                         “page 2”       1
}
Map/Reduce views
{                                function(doc) {
    title: “page one”,
                                   emit(doc.title, doc.tags.length)
    tags: [“first”, important”]
                                 }
}
                                              key        value
{
                                           “page one”      2
    title: “page 2”,
    tags: [“funny”]                         “page 2”       1
}

               function(keys, values) {
                 return sum(values);
               }
Map/Reduce views
{                                function(doc) {
    title: “page one”,
                                   emit(doc.title, doc.tags.length)
    tags: [“first”, important”]
                                 }
}
                                              key        value
{
                                           “page one”      2
    title: “page 2”,
    tags: [“funny”]                         “page 2”       1
}

               function(keys, values) {
                 return sum(values);
                                                    3
               }
Query a View
Query a View

/my_db/_design/wiki/_view/tags_count
Query a View

/my_db/_design/wiki/_view/tags_count
/my_db/_design/wiki/_view/tags_count?reduce=false
Query a View

/my_db/_design/wiki/_view/tags_count
/my_db/_design/wiki/_view/tags_count?reduce=false
/my_db/_design/wiki/_view/tags_count?limit=1
Query a View

/my_db/_design/wiki/_view/tags_count
/my_db/_design/wiki/_view/tags_count?reduce=false
/my_db/_design/wiki/_view/tags_count?limit=1
/my_db/_design/wiki/_view/tags_count?key=page one
Query a View

/my_db/_design/wiki/_view/tags_count
/my_db/_design/wiki/_view/tags_count?reduce=false
/my_db/_design/wiki/_view/tags_count?limit=1
/my_db/_design/wiki/_view/tags_count?key=page one
Query a View
Query a View
  ?key=‘page one’
Query a View
          ?key=‘page one’
?startkey=‘page 1’&endkey=’page 999’
Query a View
          ?key=‘page one’
?startkey=‘page 1’&endkey=’page 999’
      ?key=[‘composite’, ‘key’]
Query a View
           ?key=‘page one’
?startkey=‘page 1’&endkey=’page 999’
      ?key=[‘composite’, ‘key’]
       ?keys=[‘set’, ‘of’, ‘keys’]
Query a View
           ?key=‘page one’
?startkey=‘page 1’&endkey=’page 999’
      ?key=[‘composite’, ‘key’]
       ?keys=[‘set’, ‘of’, ‘keys’]
That is CouchDB
                 (the basics)


• upload documents via POST/PUT
• read documents via GET
• create indexes by providing map/reduce
  functions
• query views via GET, pass keys + other
  options
The CouchDB example wiki
Example Wiki
• ActiveRecord   • RelaxDB
• CouchRest      • Couch Potato
• ActiveCouch    • CouchOject
• CouchFoo       • CouchApp
• a wiki example app implemented in all
      frameworks I could find
   • + in ActiveRecord for comparison

DISCLAIMER: implementations are insecure, have
bugs and aren’t meant for production at all
http://github.com/langalex/couchdb_example_wiki
Example Wiki

• a few simple features
 • create a page
 • add new pages by clicking on a
    CamelCase link
 • list of pages
Example Wiki

• and a few special cases
 • keep history of each page, browse old
    versions
 • statistics: count occurrences of all words
    in all pages
Example Wiki

• creating pages is easy
• versioning, statistics harder
• views are the source of CouchDB’s power
let me show you how it works
          Example Wiki
ActiveRecord Wiki
routes.rb
map.resources :pages do |pages|
  pages.resources :versions
end

map.resources :statistics
map.root :controller => quot;pagesquot;, :action => 'show'
page.rb
class Page < ActiveRecord::Base
  acts_as_versioned

  def to_param
    title
  end
end
pages/show.html.erb
<%= <%= simple_format linkify(@page.body) %>
    simple_format linkify(@page.body) %>



  def linkify(text)
    text.gsub(/([A-Z][a-z]+([A-Z][a-z]+)+)/) do
      link_to($1, page_path($1))
    end
  end



replace CamelCase words with links to #show
pages_controller.rb

def show
  @page = Page.first unless params[:id]
  @page ||= Page.find_by_title params[:id]
  redirect_to new_page_path(:title => params[:id]) unless @page
end




           redirect to #new if no page found
statistics
  def self.word_counts
    Page.all.map(&:body).join(quot; quot;).split(/s
+/).grep(/w+/i).inject(Hash.new(0)) do |res,
word|
      res[word] += 1
      res
    end
  end
schema.rb
create_table   quot;page_versionsquot;, :force => true do |t|
  t.integer    quot;page_idquot;
  t.integer    quot;versionquot;
  t.text       quot;bodyquot;
  t.datetime   quot;created_atquot;
  t.datetime   quot;updated_atquot;
end

create_table   quot;pagesquot;, :force => true do |t|
  t.string     quot;titlequot;
  t.text       quot;bodyquot;
  t.datetime   quot;created_atquot;
  t.datetime   quot;updated_atquot;
  t.integer    quot;versionquot;,    :default => 1
end
AR Summary

• Page has_many PageVersions
• ugly schema with duplicated table
• acts_as_versioned does the magic for us
• statistics - ?!?
CouchDB Wiki
  How does it work?
The Page
{
    _id: “89765”,
    _rev: “lb7tlb”,
    type: “Page”,
    title: “page one”,
    body: “this is page one”
}
Page Versions
{
    _id: “765”,
    _rev: “lhjb97”
    type: “PageVersion”,
    title: “page one”,
    body: “this is page one”,
    version: 23,
    page_id: “89765”
}
All in one namespace
    {                                                                            {
        _id: “ 89765”,                           {
                                                                                     _id: “ 9753”,
                                                     _id: “97865”,
        _rev: “lb7tlb”,                                                              _rev: “lb7tlb”,
                                                     _rev: “lhjb97”
        type: “Page”,                                type: “PageVersion”,
                                                                                     type: “Page”,
                                                     title: “page one”,
        title: “page one”,                                                           title: “page one”,
                                                     body: “this is page one”,
        body: “this is page one”                     version: 23,
                                                                                     body: “this is page one”
                                                     page_id: “89765”
    }                  {
                                                                                 }
                                                  }
                           _id: “6437”,
                           _rev: “lhjb97”                                                     {
                           type: “PageVersion”,                                                   _id: “6367”,
                           title: “page one”,
{                                                           {                                     _rev: “lhjb97”
                           body: “this is page one”,                                              type: “PageVersion”,
    _id: “ 76538”,                                              _id: “ 8975763”,
                           version: 23,                                                           title: “page one”,
                           page_id: “89765”
    _rev: “lb7tlb”, }                                           _rev: “lb7tlb”,                   body: “this is page one”,
                                                                                                  version: 23,
    type: “Page”,                                               type: “Page”,                     page_id: “89765”
    title: “page one”,                                          title: “page one”,            }
    body: “this is page one”                                    body: “this is page one”
}                                                           }
Finding pages
function(doc) {                 key       value
  if(doc.type == “Page”) {
    emit(doc.title, doc);
                              “page 2”    {...}
  }
}
                             “page one”   {...}
Finding Page Versions
function(doc) {
  if(doc.type == “PageVersion”) {
    emit([doc.page_id, doc.version], doc);
  }
}                                key          value
                            [“ladsb7gi”, 1]   {...}
                            [“ladsb7gi”, 2]   {...}
                            [“nloh79d”, 1]    {...}
Finding Page Versions
                               key          value
                          [“ladsb7gi”, 1]   {...}
                          [“ladsb7gi”, 2]   {...}
                          [“nloh79d”, 1]    {...}


GET /mydb/_design/page_versions/_view/by_page? 
  startkey=[“ladsb7gi”, 1]&endkey=[“ ladsb7gi”,{}]
Counting Words - Map
Counting Words - Map



{body: “page one”}
 {body: “page 2”}
Counting Words - Map
function(doc) {
  if(doc.type == 'Page') {
    var words = doc.body.split(/W/);
    words.forEach(function(word) {
      if (word.length > 0) emit(word, 1);
});}}




{body: “page one”}
 {body: “page 2”}
Counting Words - Map
function(doc) {
  if(doc.type == 'Page') {
    var words = doc.body.split(/W/);
    words.forEach(function(word) {
      if (word.length > 0) emit(word, 1);
});}}

                                   key      value
                                  “page”      1
{body: “page one”}
                                  “page”      1
 {body: “page 2”}
                                  “one”       1
                                   “2”        1
Counting Words - reduce
Counting Words - reduce
 key     value
“page”     1
“page”     1
“one”      1
 “2”       1
Counting Words - reduce
  key          value
 “page”          1
 “page”          1
 “one”           1
  “2”            1


function(keys, values) {
  return sum(values);
}
Counting Words - reduce
  key          value
 “page”          1
 “page”          1
 “one”           1
  “2”            1
                            key     value
                           “page”    2
function(keys, values) {
  return sum(values);
                           “one”     1
}

                            “2”      1
CouchDB summary

• no schema, arbitrary documents in one
  namespace
• still use foreign keys to implement
  associations
• create views instead of join tables
• views! views! views!
Show us the
frameworks already
What’s the framework’s job?
What’s the framework’s job?
      ActiveRecord
What’s the framework’s job?
         ActiveRecord

• map objects to relations and back
• do the whole SQL thing
What’s the framework’s job?
              ActiveRecord
schema                                   attribute auto
tracking                                   detection
          serialized attributes   pagination
  groups
                       JOINS unique    lazy loading
         caching
     • map objects to relations and back count
     • do the whole SQL thing           HABTM
                        create or update?
  has_many :through                   conditions
       eager association loading
connection DDL              :dependent => :destroy
What’s the framework’s job?
          ActiveRecord
           Page.all :include => :tags



SELECT pages.id ... JOIN tags ON ... WHERE ...
           ... [10 more lines] ...
What’s the framework’s job?
      ActiveRecord

      big fat abstraction


            SQL
What’s the framework’s job?
 ActiveCouchRelaxFooDBObject
What’s the framework’s job?
 ActiveCouchRelaxFooDBObject

      <#134 Page title=”page one”>




{type: “Page”, title: “page one”}
What’s the framework’s job?
 ActiveCouchRelaxFooDBObject


POST /mydb/, {title: “page one”, type: “Page”}

            GET /mydb/page-one
What’s the framework’s job?
 ActiveCouchRelaxFooDBObject


                          skinny
         CouchDB        abstraction
ActiveCouchRelaxFooDBObject


          ... are not *that* important
The frameworks

       CouchPoato        RelaxDB
                    CouchObject
ActiveCouch
                        CouchRest
    CouchFoo
CouchRest


• 2 in 1
• foundation for most
  other frameworks
Low level part

• relatively thin layer on top of RestClient
• store and retrieve JSON structures
• query views the Couch way
Class mapping part


• map Ruby classes to JSON documents
• CRUD
• declarative views with CouchDB
  semantics
RelaxDB

• CRUD + very basic associations
• automatic view generation via view_by
• a bit of support for custom views via
  RelaxDB::View
• CouchDB like view API
Couch Object

• last updated in 2007
• pretty low level - okay for learning
  the details of Couch the DIY way
• no update, no properties, no
  automatic view creation
Couch Potato
• CRUD, associations + JSON mapping
• built-in acts_as_versioned - 60 LOC but
  doing it by hand only requires 7
• ViewQuery class for creating/querying
  custom views
• AR like finders
CouchFoo

• takes ActiveRecord and makes it
  work with CouchDB
• if you (have) to migrate an AR
  app...
• doesn’t give you the power of
  CouchDB
ActiveCouch
• “Object Relational Mapper for [..]
  CouchDB”
• “Since, the Rubyists here at Wego are
  already very familiar with ActiveRecord
  semantics, care has been taken to ensure
  that ActiveCouch resembled it in many
  ways.”
ActiveCouch

• one database per model
• View class to upload #@!? views via Rake
  task
• no support for custom views
Use the source
CouchRest Wiki
Page CRUD
class Page < CouchRest::ExtendedDocument
  update_callback :after, :create_version

  property :title          can’t infer attributes from table
  property :body

  view_by :title
                         auto-generate simple views
  def create_version
    PageVersion.new(:page_id => id,
      :body => @body_was, :version => versions_count + 1).save!
  end
                                  create version on update
end
PageVersion

class PageVersion < CouchRest::ExtendedDocument
  property :body
  property :version
  property :page_id

  view_by [:page_id, :version]
end
Word Count
class WordCount < CouchRest::ExtendedDocument
  view_by :all, :map => quot;function(doc) {
     if(doc['couchrest-type'] == 'Page') {
       var words = doc.body.split(/W/);
       words.forEach(function(word) {
         if (word.length > 0) emit(word, 1);
       });
     }
  }quot;,
  :reduce => quot;function(keys, values) {
     return sum(values);
  }quot;
end
Querying Views
Page.by_title

Page.by_created_at(:limit => 1)

PageVersion.get params[:id]

Page.by_title(:key => title, :limit => 1).first

WordCount.all
One more thing
CouchApp


• serve entire apps directly from CouchDB
• just JSON, HTML & JavaScript
What is CouchApp

• bunch of Ruby Python scripts to help with
  development/deployment
• data, CouchDB views, validations, shows,
  lists and assets in one database
AJAX apps
•   serve HTML, CSS as assets

•   do all the work in JavaScript

•   in the browser: GET from couch and append
    HTML, POST form data to CouchDB to
    update documents

•   in CouchDB: views to retrieve, compute data,
    validations
“real” apps

• lists
• shows
• server HTML, XML etc. from CouchDB
Conclusion
DON’T

use ActiveCouch
unless you understand why it is
the way it is

or Couch Potato
I’ll break all of its bones and APIS
DON’T


or CouchFoo
unless you want more power
than AR can give you
Conclusion


forgetting about the ActiveRecord way
is more important than what framework
Conclusion


think in documents & views,
not in records and associations
Conclusion


CouchDB is not about finding your
records, it’s about clever map/reduce
to get exactly what you want
What you want is


a thin abstraction
CouchDB semantics, not ActiveRecord
start simple with CouchREST or RelaxDB
and relax...




       time to relax
Resources
•   The CouchDB book
    http://books.couchdb.org/relax/

•   jchris CouchApp talk
    http://jchrisa.net/drl/CouchDB%20Talk%20at%20Vidoop/
    VidoopCouchTalk.pdf

•   janl CouchDB talk
    http://www.slideshare.net/bbcwebdev/introduction-into-couchdb-
    jan-lehnardt-presentation

•   The example wiki
    http://github.com/langalex/couchdb_example_wiki/

•   http://couch.io
    support, training, hosting, development
Questions?
• Email: alex@upstream-berlin.com
• Twitter: @langalex




                   time to relax

More Related Content

What's hot

JQuery In Rails
JQuery In RailsJQuery In Rails
JQuery In Rails
Louie Zhao
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODM
Jonathan Wage
 
H T M L Help Sheet
H T M L  Help  SheetH T M L  Help  Sheet
H T M L Help Sheet
51 lecture
 
Aggregation in MongoDB
Aggregation in MongoDBAggregation in MongoDB
Aggregation in MongoDB
Kishor Parkhe
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODM
Jonathan Wage
 

What's hot (18)

HTML5 - Pedro Rosa
HTML5 - Pedro RosaHTML5 - Pedro Rosa
HTML5 - Pedro Rosa
 
DrupalCon Chicago Practical MongoDB and Drupal
DrupalCon Chicago Practical MongoDB and DrupalDrupalCon Chicago Practical MongoDB and Drupal
DrupalCon Chicago Practical MongoDB and Drupal
 
Doctrine for NoSQL
Doctrine for NoSQLDoctrine for NoSQL
Doctrine for NoSQL
 
Doctrine and NoSQL
Doctrine and NoSQLDoctrine and NoSQL
Doctrine and NoSQL
 
IN4308 Lecture 3
IN4308 Lecture 3IN4308 Lecture 3
IN4308 Lecture 3
 
Jquery
JqueryJquery
Jquery
 
XML Binding Language 2.0
XML Binding Language 2.0XML Binding Language 2.0
XML Binding Language 2.0
 
JQuery In Rails
JQuery In RailsJQuery In Rails
JQuery In Rails
 
Intoduction to php restful web service
Intoduction to php  restful web serviceIntoduction to php  restful web service
Intoduction to php restful web service
 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
 
Learning the basics of the Drupal API
Learning the basics of the Drupal APILearning the basics of the Drupal API
Learning the basics of the Drupal API
 
ZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODMZendCon2010 Doctrine MongoDB ODM
ZendCon2010 Doctrine MongoDB ODM
 
H T M L Help Sheet
H T M L  Help  SheetH T M L  Help  Sheet
H T M L Help Sheet
 
What's new in the Drupal 7 API?
What's new in the Drupal 7 API?What's new in the Drupal 7 API?
What's new in the Drupal 7 API?
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Aggregation in MongoDB
Aggregation in MongoDBAggregation in MongoDB
Aggregation in MongoDB
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODM
 

Similar to Ruby sittin' on the Couch

development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...
development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...
development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...
ActsAsCon
 
Migrating To Ruby1.9
Migrating To Ruby1.9Migrating To Ruby1.9
Migrating To Ruby1.9
tomaspavelka
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
偉格 高
 
Merb Pluming - The Router
Merb Pluming - The RouterMerb Pluming - The Router
Merb Pluming - The Router
carllerche
 
The Dom Scripting Toolkit J Query
The Dom Scripting Toolkit J QueryThe Dom Scripting Toolkit J Query
The Dom Scripting Toolkit J Query
QConLondon2008
 

Similar to Ruby sittin' on the Couch (20)

CouchDB
CouchDBCouchDB
CouchDB
 
Umleitung: a tiny mochiweb/CouchDB app
Umleitung: a tiny mochiweb/CouchDB appUmleitung: a tiny mochiweb/CouchDB app
Umleitung: a tiny mochiweb/CouchDB app
 
Rails GUI Development with Ext JS
Rails GUI Development with Ext JSRails GUI Development with Ext JS
Rails GUI Development with Ext JS
 
Hacking with ruby2ruby
Hacking with ruby2rubyHacking with ruby2ruby
Hacking with ruby2ruby
 
Rails <form> Chronicle
Rails <form> ChronicleRails <form> Chronicle
Rails <form> Chronicle
 
Relaxing With CouchDB
Relaxing With CouchDBRelaxing With CouchDB
Relaxing With CouchDB
 
development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...
development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...
development, ruby, conferences, frameworks, ruby on rails, confreaks, actsasc...
 
Migrating To Ruby1.9
Migrating To Ruby1.9Migrating To Ruby1.9
Migrating To Ruby1.9
 
Couchdb
CouchdbCouchdb
Couchdb
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
 
jQuery Internals + Cool Stuff
jQuery Internals + Cool StuffjQuery Internals + Cool Stuff
jQuery Internals + Cool Stuff
 
Rack Middleware
Rack MiddlewareRack Middleware
Rack Middleware
 
Couchdb
CouchdbCouchdb
Couchdb
 
Capistrano2
Capistrano2Capistrano2
Capistrano2
 
jQuery Presentation to Rails Developers
jQuery Presentation to Rails DevelopersjQuery Presentation to Rails Developers
jQuery Presentation to Rails Developers
 
MongoDB Aggregation Framework
MongoDB Aggregation FrameworkMongoDB Aggregation Framework
MongoDB Aggregation Framework
 
Merb Pluming - The Router
Merb Pluming - The RouterMerb Pluming - The Router
Merb Pluming - The Router
 
The Dom Scripting Toolkit J Query
The Dom Scripting Toolkit J QueryThe Dom Scripting Toolkit J Query
The Dom Scripting Toolkit J Query
 
What's up with Prototype and script.aculo.us?
What's up with Prototype and script.aculo.us?What's up with Prototype and script.aculo.us?
What's up with Prototype and script.aculo.us?
 
Network Automation: Ansible 102
Network Automation: Ansible 102Network Automation: Ansible 102
Network Automation: Ansible 102
 

Recently uploaded

Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 

Recently uploaded (20)

Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 

Ruby sittin' on the Couch