|
1 |
| -# Familia - 1.0.0-rc2 (August 2024) |
| 1 | +# Familia - 1.0.0-rc4 (August 2024) |
2 | 2 |
|
3 |
| -**Organize and store ruby objects in Redis. A Ruby ORM for Redis.** |
| 3 | +**Organize and store Ruby objects in Redis. A powerful Ruby ORM (of sorts) for Redis.** |
4 | 4 |
|
5 |
| -Familia provides a powerful and flexible way to interact with Redis using Ruby objects. It's designed to make working with Redis as natural as working with Ruby classes. |
| 5 | +Familia provides a flexible and feature-rich way to interact with Redis using Ruby objects. It's designed to make working with Redis as natural as working with Ruby classes, while offering advanced features for complex data management. |
6 | 6 |
|
7 | 7 | ## Installation
|
8 | 8 |
|
| 9 | + |
9 | 10 | Get it in one of the following ways:
|
10 | 11 |
|
11 |
| -* In your Gemfile: `gem 'familia', '>= 1.0.0-rc2'` |
12 |
| -* Install it by hand: `gem install familia` |
| 12 | +* In your Gemfile: `gem 'familia', '>= 1.0.0-rc4'` |
| 13 | +* Install it by hand: `gem install familia --pre` |
13 | 14 | * Or for development: `git clone [email protected]:delano/familia.git`
|
14 | 15 |
|
15 |
| -## Basic Example |
| 16 | + |
| 17 | +## Core Concepts and Features |
| 18 | + |
| 19 | +### 1. Defining Horreum Classes |
| 20 | + |
| 21 | +Familia uses the concept of "Horreum" classes to represent Redis-backed objects: |
16 | 22 |
|
17 | 23 | ```ruby
|
18 | 24 | class Flower < Familia::Horreum
|
19 |
| - identifier :generate_id |
20 |
| - field :token |
21 |
| - field :name |
22 |
| - list :owners |
23 |
| - set :tags |
24 |
| - zset :metrics |
| 25 | + identifier :token |
| 26 | + field :name |
| 27 | + list :owners |
| 28 | + set :tags |
| 29 | + zset :metrics |
25 | 30 | hashkey :props
|
26 |
| - string :counter |
| 31 | + string :counter |
| 32 | +end |
| 33 | +``` |
| 34 | + |
| 35 | +### 2. Flexible Identifiers |
| 36 | + |
| 37 | +You can define identifiers in various ways: |
| 38 | + |
| 39 | +```ruby |
| 40 | +class User < Familia::Horreum |
| 41 | + identifier :email |
| 42 | + # or |
| 43 | + identifier -> (user) { "user:#{user.email}" } |
| 44 | + # or |
| 45 | + identifier [:type, :email] |
| 46 | + |
| 47 | + field :email |
| 48 | + field :type |
| 49 | +end |
| 50 | +``` |
| 51 | + |
| 52 | +### 3. Redis Data Types |
| 53 | + |
| 54 | +Familia supports various Redis data types: |
| 55 | + |
| 56 | +```ruby |
| 57 | +class Product < Familia::Horreum |
| 58 | + string :name |
| 59 | + list :categories |
| 60 | + set :tags |
| 61 | + zset :ratings |
| 62 | + hashkey :attributes |
| 63 | +end |
| 64 | +``` |
| 65 | + |
| 66 | +### 4. Class-level Redis Types |
| 67 | + |
| 68 | +You can also define Redis types at the class level: |
| 69 | + |
| 70 | +```ruby |
| 71 | +class Customer < Familia::Horreum |
| 72 | + class_sorted_set :values, key: 'project:customers' |
| 73 | + class_hashkey :projects |
| 74 | + class_list :customers, suffix: [] |
| 75 | + class_string :message |
| 76 | +end |
| 77 | +``` |
| 78 | + |
| 79 | +### 5. Automatic Expiration |
| 80 | + |
| 81 | +Use the expiration feature to set TTL for objects: |
| 82 | + |
| 83 | +```ruby |
| 84 | +class Session < Familia::Horreum |
| 85 | + feature :expiration |
| 86 | + ttl 180.minutes |
| 87 | +end |
| 88 | +``` |
| 89 | + |
| 90 | +### 6. Safe Dumping for APIs |
| 91 | + |
| 92 | +Control which fields are exposed when serializing objects: |
| 93 | + |
| 94 | +```ruby |
| 95 | +class User < Familia::Horreum |
| 96 | + feature :safe_dump |
| 97 | + |
| 98 | + @safe_dump_fields = [ |
| 99 | + :id, |
| 100 | + :username, |
| 101 | + {full_name: ->(user) { "#{user.first_name} #{user.last_name}" }} |
| 102 | + ] |
| 103 | +end |
| 104 | +``` |
| 105 | + |
| 106 | +### 7. Quantization for Time-based Data |
| 107 | + |
| 108 | +Use quantization for time-based metrics: |
| 109 | + |
| 110 | +```ruby |
| 111 | +class DailyMetric < Familia::Horreum |
| 112 | + feature :quantization |
| 113 | + string :counter, ttl: 1.day, quantize: [10.minutes, '%H:%M'] |
27 | 114 | end
|
28 | 115 | ```
|
29 | 116 |
|
30 |
| -## What Familia::Horreum Can Do |
| 117 | +### 8. Custom Methods and Logic |
31 | 118 |
|
32 |
| -Familia::Horreum provides a powerful abstraction layer over Redis, allowing you to: |
| 119 | +Add custom methods to your Horreum classes: |
33 | 120 |
|
34 |
| -1. **Define Redis-backed Ruby Classes**: As shown in the example, you can easily define classes that map to Redis structures. |
| 121 | +```ruby |
| 122 | +class User < Familia::Horreum |
| 123 | + def full_name |
| 124 | + "#{first_name} #{last_name}" |
| 125 | + end |
| 126 | + |
| 127 | + def active? |
| 128 | + status == 'active' |
| 129 | + end |
| 130 | +end |
| 131 | +``` |
35 | 132 |
|
36 |
| -2. **Use Various Redis Data Types**: Familia supports multiple Redis data types: |
37 |
| - - `field`: For simple key-value pairs |
38 |
| - - `list`: For Redis lists |
39 |
| - - `set`: For Redis sets |
40 |
| - - `zset`: For Redis sorted sets |
41 |
| - - `hashkey`: For Redis hashes |
42 |
| - - `string`: For Redis strings |
| 133 | +### 9. Custom Methods and Logic |
43 | 134 |
|
44 |
| -3. **Custom Identifiers**: Use the `identifier` method to specify how objects are uniquely identified in Redis. |
| 135 | +You can add custom methods to your Horreum classes: |
45 | 136 |
|
46 |
| -4. **Automatic Serialization**: Familia handles the serialization and deserialization of your objects to and from Redis. |
| 137 | +```ruby |
| 138 | +class Customer < Familia::Horreum |
| 139 | + def active? |
| 140 | + verified && !reset_requested |
| 141 | + end |
| 142 | +end |
47 | 143 |
|
48 |
| -5. **Redis Commands as Ruby Methods**: Interact with Redis using familiar Ruby syntax instead of raw Redis commands. |
| 144 | +class Session < Familia::Horreum |
| 145 | + def external_identifier |
| 146 | + elements = [ipaddress || 'UNKNOWNIP', custid || 'anon'] |
| 147 | + @external_identifier ||= Familia.generate_sha_hash(elements) |
| 148 | + end |
| 149 | +end |
| 150 | +``` |
| 151 | +### 10. Open-ended Serialization |
49 | 152 |
|
50 |
| -6. **TTL Support**: Set expiration times for your objects in Redis. |
| 153 | +```ruby |
| 154 | +class ComplexObject < Familia::Horreum |
| 155 | + def to_redis |
| 156 | + custom_serialization_method |
| 157 | + end |
| 158 | + |
| 159 | + def self.from_redis(data) |
| 160 | + custom_deserialization_method(data) |
| 161 | + end |
| 162 | +end |
| 163 | +``` |
51 | 164 |
|
52 |
| -7. **Flexible Configuration**: Configure Redis connection details, serialization methods, and more. |
| 165 | +### 11. Transactional Operations |
| 166 | + |
| 167 | +```ruby |
| 168 | +user.transaction do |conn| |
| 169 | + conn.set("user:#{user.id}:status", "active") |
| 170 | + conn.zadd("active_users", Time.now.to_i, user.id) |
| 171 | +end |
| 172 | +``` |
53 | 173 |
|
54 |
| -## Advanced Features |
55 | 174 |
|
56 |
| -- **API Versioning**: Familia supports API versioning to help manage changes in your data model over time. |
57 |
| -- **Custom Serialization**: You can specify custom serialization methods for your objects. |
58 |
| -- **Redis URI Support**: Easily connect to Redis using URI strings. |
59 |
| -- **Debugging Tools**: Built-in debugging capabilities to help troubleshoot Redis interactions. |
| 175 | +## Usage Examples |
60 | 176 |
|
61 |
| -## Usage Example |
| 177 | +### Creating and Saving Objects |
62 | 178 |
|
63 | 179 | ```ruby
|
64 |
| -# Create a new Flower |
65 |
| -rose = Flower.new |
66 |
| -rose.name = "Red Rose" |
67 |
| -rose.tags << "romantic" << "red" |
68 |
| -rose.owners.push("Alice", "Bob") |
| 180 | +flower = Flower.create(name: "Red Rose", token: "rrose") |
| 181 | +flower.owners.push("Alice", "Bob") |
| 182 | +flower.tags.add("romantic") |
| 183 | +flower.metrics.increment("views", 1) |
| 184 | +flower.props[:color] = "red" |
| 185 | +flower.save |
| 186 | +``` |
| 187 | + |
| 188 | +### Retrieving and Updating Objects |
| 189 | + |
| 190 | +```ruby |
| 191 | +rose = Flower.from_identifier("rrose") |
| 192 | +rose.name = "Pink Rose" |
69 | 193 | rose.save
|
| 194 | +``` |
| 195 | + |
| 196 | +### Using Safe Dump |
| 197 | + |
| 198 | +```ruby |
| 199 | +user = User.create(username: "rosedog", first_name: "Rose", last_name: "Dog") |
| 200 | +user.safe_dump |
| 201 | +# => {id: "user:rosedog", username: "rosedog", full_name: "Rose Dog"} |
| 202 | +``` |
| 203 | + |
| 204 | +### Working with Time-based Data |
| 205 | + |
| 206 | +```ruby |
| 207 | +metric = DailyMetric.new |
| 208 | +metric.counter.increment # Increments the counter for the current hour |
| 209 | +``` |
| 210 | + |
| 211 | +### Bulk Operations |
70 | 212 |
|
71 |
| -# Retrieve a Flower |
72 |
| -retrieved_rose = Flower.get(rose.identifier) |
73 |
| -puts retrieved_rose.name # => "Red Rose" |
74 |
| -puts retrieved_rose.tags.members # => ["romantic", "red"] |
| 213 | +```ruby |
| 214 | +Flower.multiget("rrose", "tulip", "daisy") |
| 215 | +``` |
| 216 | + |
| 217 | +### Transactional Operations |
| 218 | + |
| 219 | +```ruby |
| 220 | +user.transaction do |conn| |
| 221 | + conn.set("user:#{user.id}:status", "active") |
| 222 | + conn.zadd("active_users", Time.now.to_i, user.id) |
| 223 | +end |
75 | 224 | ```
|
76 | 225 |
|
77 |
| -## More Information |
| 226 | +## Conclusion |
78 | 227 |
|
79 |
| -* [Github](https://github.com/delano/familia) |
80 |
| -* [Rubygems](https://rubygems.org/gems/familia) |
| 228 | +Familia provides a powerful and flexible way to work with Redis in Ruby applications. Its features like automatic expiration, safe dumping, and quantization make it suitable for a wide range of use cases, from simple key-value storage to complex time-series data management. |
81 | 229 |
|
82 |
| -## Contributing |
| 230 | +For more information, visit: |
| 231 | +- [Github Repository](https://github.com/delano/familia) |
| 232 | +- [RubyGems Page](https://rubygems.org/gems/familia) |
83 | 233 |
|
84 |
| -Contributions are welcome! Please feel free to submit a Pull Request. |
| 234 | +Contributions are welcome! Feel free to submit a Pull Request. |
0 commit comments