couchbase-orm 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/deploy.yml +45 -0
  3. data/.github/workflows/test.yml +18 -13
  4. data/README.md +12 -0
  5. data/couchbase-orm.gemspec +2 -2
  6. data/docusaurus/.gitignore +20 -0
  7. data/docusaurus/README.md +41 -0
  8. data/docusaurus/babel.config.js +3 -0
  9. data/docusaurus/docs/tutorial-ruby-couchbase-orm/01-introduction.md +49 -0
  10. data/docusaurus/docs/tutorial-ruby-couchbase-orm/02-installation.md +108 -0
  11. data/docusaurus/docs/tutorial-ruby-couchbase-orm/03-defining-models.md +239 -0
  12. data/docusaurus/docs/tutorial-ruby-couchbase-orm/04-querying.md +154 -0
  13. data/docusaurus/docs/tutorial-ruby-couchbase-orm/05-persistence.md +93 -0
  14. data/docusaurus/docs/tutorial-ruby-couchbase-orm/06-associations-and-validations.md +236 -0
  15. data/docusaurus/docs/tutorial-ruby-couchbase-orm/07-sqlpp-queries.md +180 -0
  16. data/docusaurus/docs/tutorial-ruby-couchbase-orm/08-views.md +158 -0
  17. data/docusaurus/docs/tutorial-ruby-couchbase-orm/09-nested-documents.md +138 -0
  18. data/docusaurus/docs/tutorial-ruby-couchbase-orm/10-enums.md +91 -0
  19. data/docusaurus/docs/tutorial-ruby-couchbase-orm/11-encryption.md +114 -0
  20. data/docusaurus/docs/tutorial-ruby-couchbase-orm/12-logging.md +48 -0
  21. data/docusaurus/docs/tutorial-ruby-couchbase-orm/13-troubleshooting.md +41 -0
  22. data/docusaurus/docs/tutorial-ruby-couchbase-orm/_category_.json +8 -0
  23. data/docusaurus/docusaurus.config.ts +122 -0
  24. data/docusaurus/package-lock.json +14540 -0
  25. data/docusaurus/package.json +47 -0
  26. data/docusaurus/sidebars.ts +31 -0
  27. data/docusaurus/src/components/HomepageFeatures/index.tsx +69 -0
  28. data/docusaurus/src/components/HomepageFeatures/styles.module.css +11 -0
  29. data/docusaurus/src/css/custom.css +30 -0
  30. data/docusaurus/src/pages/index.module.css +23 -0
  31. data/docusaurus/src/pages/index.tsx +43 -0
  32. data/docusaurus/src/pages/markdown-page.md +7 -0
  33. data/docusaurus/static/.nojekyll +0 -0
  34. data/docusaurus/static/CNAME +1 -0
  35. data/docusaurus/static/img/familiar.svg +1 -0
  36. data/docusaurus/static/img/fast.svg +1 -0
  37. data/docusaurus/static/img/logo.svg +1 -0
  38. data/docusaurus/static/img/undraw_docusaurus_mountain.svg +171 -0
  39. data/docusaurus/static/img/undraw_docusaurus_react.svg +170 -0
  40. data/docusaurus/static/img/undraw_docusaurus_tree.svg +40 -0
  41. data/docusaurus/tsconfig.json +7 -0
  42. data/lib/couchbase-orm/types/date_time.rb +2 -1
  43. data/lib/couchbase-orm/utilities/query_helper.rb +1 -1
  44. data/lib/couchbase-orm/version.rb +1 -1
  45. metadata +43 -10
@@ -0,0 +1,158 @@
1
+ # Views (aka Map/Reduce indexes)
2
+
3
+ Views are a powerful feature in Couchbase that allow you to define map functions to extract and emit specific data from your documents. The Ruby Couchbase ORM provides a convenient way to define and query views within your Ruby application.
4
+
5
+ ## 8.1 Defining Views
6
+
7
+ To define a view in your Ruby Couchbase ORM model, you can use the `view` method followed by the view name and options. Here's an example:
8
+
9
+ ```ruby
10
+ class Factory < CouchbaseOrm::Base
11
+ attribute :name, type: String
12
+ attribute :location, type: String
13
+ attribute :established_year, type: Integer
14
+ attribute :active, type: Boolean
15
+
16
+ view :by_name, emit_key: :name
17
+ view :by_location, emit_key: :location
18
+ view :by_established_year, emit_key: :established_year
19
+ view :by_active, emit_key: :active
20
+ end
21
+ ```
22
+
23
+ In this example, we define four views for the `Factory` model:
24
+ - `by_name`: Emits the `name` attribute as the key.
25
+ - `by_location`: Emits the `location` attribute as the key.
26
+ - `by_established_year`: Emits the `established_year` attribute as the key.
27
+ - `by_active`: Emits the `active` attribute as the key.
28
+
29
+ The `emit_key` option specifies the attribute to use as the key for the view.
30
+
31
+ ## 8.2 Custom Map Functions
32
+
33
+ You can also define custom map functions for your views using the `map` option. This allows you to emit custom keys and values based on your specific requirements. Here's an example:
34
+
35
+ ```ruby
36
+ view :by_name_and_location,
37
+ map: %{
38
+ function(doc) {
39
+ if (doc.type === "factory") {
40
+ emit([doc.name, doc.location], null);
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ In this example, we define a view named `by_name_and_location` that emits a composite key consisting of the `name` and `location` attributes.
47
+
48
+ ## 8.3 Querying Views
49
+
50
+ Once you have defined your views, you can query them using the corresponding view methods. The view methods are automatically generated based on the view names. Here are some examples:
51
+
52
+ ```ruby
53
+ # Query factories by name
54
+ Factory.by_name(key: 'Factory A').each do |factory|
55
+ puts "- #{factory.name}"
56
+ end
57
+
58
+ # Query factories by location
59
+ Factory.by_location(key: 'City X').each do |factory|
60
+ puts "- #{factory.name}"
61
+ end
62
+
63
+ # Query factories by established year
64
+ Factory.by_established_year(key: 2010).each do |factory|
65
+ puts "- #{factory.name}"
66
+ end
67
+
68
+ # Query active factories
69
+ Factory.by_active(key: true).each do |factory|
70
+ puts "- #{factory.name}"
71
+ end
72
+ ```
73
+
74
+ These examples demonstrate how to query views based on specific keys using the generated view methods.
75
+
76
+ ## 8.4 Indexing Views
77
+
78
+ In this section, let's explore the `index_view` function and the methods it generates for the `location` attribute.
79
+
80
+ Here's an updated version of the `Factory` model using `index_view` for the `location` attribute:
81
+
82
+ ```ruby
83
+ class Factory < CouchbaseOrm::Base
84
+ attribute :name, type: String
85
+ attribute :location, type: String
86
+ attribute :established_year, type: Integer
87
+ attribute :active, type: Boolean
88
+
89
+ view :by_name, emit_key: :name
90
+ index_view :location
91
+ view :by_established_year, emit_key: :established_year
92
+ view :by_active, emit_key: :active
93
+
94
+ view :by_name_and_location,
95
+ map: %{
96
+ function(doc) {
97
+ if (doc.type === "factory") {
98
+ emit([doc.name, doc.location], null);
99
+ }
100
+ }
101
+ }
102
+
103
+ view :by_established_year_range,
104
+ map: %{
105
+ function(doc) {
106
+ if (doc.type === "factory" && doc.established_year) {
107
+ emit(doc.established_year, null);
108
+ }
109
+ }
110
+ }
111
+ end
112
+ ```
113
+
114
+ In this updated code, we replaced `view :by_location, emit_key: :location` with `index_view :location`. The `index_view` function generates two methods for querying based on the `location` attribute:
115
+
116
+ 1. `find_by_location(location)`: This method allows you to find factories by a specific location. It returns an array of factories that match the given location.
117
+
118
+ 2. `by_location(key: location)`: This method is similar to `find_by_location` but returns a `CouchbaseOrm::ResultsProxy` object, which provides an enumerable interface to access the view results.
119
+
120
+ Now, let's see how we can use these generated methods to query factories by location:
121
+
122
+ ```ruby
123
+ # Find factories by location using find_by_location
124
+ factories = Factory.find_by_location('City X')
125
+ factories.each do |factory|
126
+ puts "- #{factory.name} (#{factory.location})"
127
+ end
128
+
129
+ # Find factories by location using by_location
130
+ Factory.by_location(key: 'City X').each do |factory|
131
+ puts "- #{factory.name} (#{factory.location})"
132
+ end
133
+ ```
134
+
135
+ Both `find_by_location` and `by_location` achieve the same result of finding factories by a specific location. The difference is that `find_by_location` returns an array of factories directly, while `by_location` returns a `CouchbaseOrm::ResultsProxy` object that you can further chain or iterate over.
136
+
137
+ Using `index_view` provides a convenient way to generate commonly used query methods for a specific attribute. It simplifies the process of querying based on that attribute and enhances the readability of your code.
138
+
139
+ <!-- ## 8.5 Range Queries (Experimental)
140
+
141
+ You can perform range queries on views by specifying the `startkey` and `endkey` options. Here's an example:
142
+
143
+ ```ruby
144
+ # Query factories established between 2005 and 2015
145
+ Factory.by_established_year_range(startkey: 2005, endkey: 2015).each do |factory|
146
+ puts "- #{factory.name} (#{factory.established_year})"
147
+ end
148
+ ```
149
+
150
+ In this example, we query the `by_established_year_range` view to retrieve factories established between 2005 and 2015. -->
151
+
152
+ ## 8.5 Conclusion
153
+
154
+ Views in the Ruby Couchbase ORM provide a powerful way to define and query data based on specific attributes and custom map functions. By defining views, you can easily retrieve subsets of your data and perform efficient queries based on your application's requirements.
155
+
156
+ Remember to ensure that your design documents are up to date by calling `ensure_design_document!` on your models before running queries.
157
+
158
+ With the flexibility and ease of use provided by the Ruby Couchbase ORM's view functionality, you can efficiently query and retrieve data from your Couchbase database.
@@ -0,0 +1,138 @@
1
+ # Nested Documents
2
+
3
+ CouchbaseOrm supports nested documents, which allow you to store complex, hierarchical data structures within a single Couchbase document. Nested documents are useful when you have related data that you want to store together with the parent document for performance or consistency reasons.
4
+
5
+ ## 9.1. Defining Nested Documents
6
+
7
+ To define an nested document, you create a new class that inherits from `CouchbaseOrm::NestedDocument`.
8
+
9
+ ```ruby
10
+ class Part < CouchbaseOrm::NestedDocument
11
+ attribute :name, :string
12
+ attribute :manufacturer, :string
13
+ end
14
+
15
+ # Define the Car model with a nested Part document
16
+ class Car < CouchbaseOrm::Base
17
+ attribute :make, :string
18
+ attribute :model, :string
19
+ attribute :year, :integer
20
+ attribute :parts, :array, type: Part
21
+
22
+ validates :make, presence: true
23
+ validates :model, presence: true
24
+ validates :year, presence: true
25
+ end
26
+
27
+ ```
28
+
29
+ In this example, we define a `Car` model with a nested `Part` document. The `Part` class inherits from `CouchbaseOrm::NestedDocument` and defines attributes for `name` and `manufacturer`. The `Car` model has an `parts` attribute that is an array of `Part` nested documents.
30
+
31
+ ## 9.2. Embedding Documents
32
+
33
+ To embed a document within a parent document, you can assign an instance of the nested document class to the corresponding attribute.
34
+
35
+ ```ruby
36
+ # Create a new car with nested parts
37
+ car = Car.new(
38
+ make: 'Toyota',
39
+ model: 'Corolla',
40
+ year: 2022,
41
+ parts: [
42
+ Part.new(name: 'Engine', manufacturer: 'Toyota Motors'),
43
+ Part.new(name: 'Transmission', manufacturer: 'Toyota Motors')
44
+ ]
45
+ )
46
+ car.save
47
+ ```
48
+
49
+ When saving the parent document (`Car`), CouchbaseOrm serializes the nested `Part` documents and stores them within the parent document. This allows you to retrieve the entire data structure with a single query.
50
+
51
+ ## 9.3. Accessing Nested Documents
52
+
53
+ To access an nested document, you can simply call the corresponding attribute on the parent document.
54
+
55
+ ```ruby
56
+ toyota_cars = Car.where(make: 'Toyota')
57
+ ```
58
+
59
+ CouchbaseOrm automatically deserializes the nested document and returns an instance of the nested document class.
60
+
61
+ ## 9.4. Updating Nested Documents
62
+
63
+ To update an nested document, you can modify the attributes of the nested document instance and save the parent document.
64
+
65
+ ```ruby
66
+ engine_part = car.parts.find { |part| part.name == 'Engine' }
67
+ engine_part.manufacturer = 'Toyota Industries'
68
+ car.save
69
+ ```
70
+
71
+ CouchbaseOrm will serialize the updated nested document and save it along with the parent document.
72
+
73
+ ## 9.5. Embedding Multiple Documents
74
+
75
+ You can also embed multiple documents within a parent document using an array attribute.
76
+
77
+ ```ruby
78
+ car = Car.new(
79
+ make: 'Toyota',
80
+ model: 'Corolla',
81
+ year: 2022,
82
+ parts: [
83
+ Part.new(name: 'Engine', manufacturer: 'Toyota Motors'),
84
+ Part.new(name: 'Transmission', manufacturer: 'Toyota Motors')
85
+ ]
86
+ )
87
+ car.save
88
+ ```
89
+
90
+ In this example, the `Car` model has an `parts` attribute that is an array of `Part` nested documents. You can embed multiple `Part` documents within a single `Car` document, allowing you to store related data together.
91
+
92
+ ## 9.6. Querying Nested Documents
93
+
94
+ CouchbaseOrm allows you to query nested documents using dot notation and attribute conditions.
95
+
96
+ ```ruby
97
+ cars_by_part_manufacturer = Car.where("ANY part IN parts SATISFIES part.manufacturer = 'Toyota Industries' END")
98
+ ```
99
+
100
+ This query retrieves all the `Car` documents where at least one `Part` document has a `manufacturer` attribute equal to `'Toyota Industries'`. You can use dot notation to access nested document attributes within the query condition.
101
+
102
+ ## 9.7. Validating Nested Documents
103
+
104
+ CouchbaseOrm allows you to validate nested documents along with the parent document.
105
+
106
+ ```ruby
107
+ class Part < CouchbaseOrm::NestedDocument
108
+ attribute :name, :string
109
+ attribute :manufacturer, :string
110
+
111
+ validates :name, presence: true
112
+ validates :manufacturer, presence: true
113
+ end
114
+
115
+ class Car < CouchbaseOrm::Base
116
+ attribute :make, :string
117
+ attribute :model, :string
118
+ attribute :year, :integer
119
+ attribute :parts, :array, type: Part
120
+
121
+ validates :make, presence: true
122
+ validates :model, presence: true
123
+ validates :year, presence: true
124
+ validates :parts, presence: true
125
+ end
126
+
127
+
128
+ ```
129
+
130
+ In this example, we define validations for the `Part` nested document, ensuring that the `name` and `manufacturer` attributes are present. We also add validations to the `Car` model to ensure that the `make`, `model`, `year`, and `parts` attributes are present.
131
+
132
+ When saving a `Car` document, CouchbaseOrm will validate both the parent document and the nested `Part` documents. If any validation fails, the parent document will not be saved, and validation errors will be added to the parent document.
133
+
134
+ Nested documents provide a powerful way to model complex data structures and relationships within a single Couchbase document. They allow you to store related data together, improving performance and reducing the need for separate queries to retrieve associated data.
135
+
136
+ However, it's important to consider the trade-offs when using nested documents. Embedding too much data within a single document can lead to large document sizes and potential performance issues. It's recommended to use nested documents judiciously and to consider the access patterns and data relationships of your application.
137
+
138
+ In the next section, we'll explore enums in CouchbaseOrm and how they can be used to define a fixed set of values for an attribute.
@@ -0,0 +1,91 @@
1
+ # Enums
2
+
3
+ CouchbaseOrm provides support for enums, which allow you to define a fixed set of values for an attribute. Enums are useful when you have a limited number of possible values for a particular attribute and want to ensure data consistency and validity.
4
+
5
+ ## 10.1. Defining Enums
6
+
7
+ To define an enum in your model, you can use the `enum` class method provided by CouchbaseOrm.
8
+
9
+ ```ruby
10
+ class User < CouchbaseOrm::Base
11
+ enum status: [:active, :inactive, :suspended]
12
+ end
13
+ ```
14
+
15
+ In this example, we define an enum named `status` for the `User` model. The enum has three possible values: `:active`, `:inactive`, and `:suspended`.
16
+
17
+ ## 10.2. Using Enums
18
+
19
+ You can assign enum values to an attribute using the generated methods or by directly assigning the value.
20
+
21
+ ```ruby
22
+ user = User.new
23
+ user.status = :active
24
+ user.save
25
+
26
+ user.suspended!
27
+ user.save
28
+
29
+ puts user.status # Output: "suspended"
30
+ ```
31
+
32
+ In this example, we create a new `User` instance and set the `status` to `:active` using the direct assignment. We then change the `status` to `:suspended` using the generated `suspended!` method.
33
+
34
+ ## 10.3. Querying by Enums
35
+
36
+ CouchbaseOrm allows you to query records based on their enum values.
37
+
38
+ ```ruby
39
+ active_users = User.where(status: 1)
40
+ suspended_users = User.where(status: 3)
41
+ ```
42
+
43
+ These queries retrieve users with the `status` enum set to `:active` and `:suspended`, respectively.
44
+
45
+ ## 10.4. Enum Mapping
46
+
47
+ Behind the scenes, CouchbaseOrm maps the enum values to integers for storage in the database. By default, the mapping starts from 0 and increments by 1 for each enum value in the order they are defined.
48
+
49
+ However, you can customize the mapping by providing a hash of enum values and their corresponding integer values.
50
+
51
+ ```ruby
52
+ class User < CouchbaseOrm::Base
53
+ enum status: { active: 1, inactive: 2, suspended: 3 }
54
+ end
55
+ ```
56
+
57
+ In this example, we explicitly define the mapping of enum values to integers. The `:active` value is mapped to 1, `:inactive` to 2, and `:suspended` to 3.
58
+
59
+ ## 10.5. Enum Validation
60
+
61
+ CouchbaseOrm automatically validates that the assigned enum value is one of the defined values for the enum.
62
+
63
+ ```ruby
64
+ user = User.new
65
+ user.status = :invalid
66
+ user.save # Raises an error: "Invalid enum value: :invalid"
67
+ ```
68
+
69
+ If you try to assign an invalid value to an enum attribute, CouchbaseOrm will raise an error indicating that the value is not a valid enum value.
70
+
71
+ ## 10.6. Enum Defaults
72
+
73
+ You can specify a default value for an enum attribute using the `default` option.
74
+
75
+ ```ruby
76
+ class User < CouchbaseOrm::Base
77
+ enum status: [:active, :inactive, :suspended], default: :active
78
+ end
79
+ ```
80
+
81
+ In this example, if no value is assigned to the `status` attribute when creating a new `User` instance, the default value of `:active` will be used.
82
+
83
+ Enums in CouchbaseOrm provide a convenient way to define a fixed set of values for an attribute. They help ensure data consistency, improve code readability, and simplify querying and validation.
84
+
85
+ When using enums, consider the following:
86
+
87
+ - Enums are stored as integers in the database, so be cautious when changing the order or removing enum values, as it may affect existing records.
88
+ - Enums are case-sensitive, so `:active` and `:Active` are considered different values.
89
+ - Enums can be used in combination with other attribute types, such as `default` and `validates`, to further customize the behavior of the attribute.
90
+
91
+ In the next section, we'll explore how to use encryption in CouchbaseOrm to secure sensitive data stored in your Couchbase documents.
@@ -0,0 +1,114 @@
1
+ # Encryption
2
+
3
+ CouchbaseOrm provides built-in support for encrypting sensitive data stored in your Couchbase documents. Encryption allows you to protect confidential information, such as personal data or financial details, by encrypting the values before storing them in the database and decrypting them when retrieving the data.
4
+
5
+ ## 11.1. Encrypted Attributes
6
+
7
+ To mark an attribute as encrypted, you can use the `:encrypted` type when defining the attribute in your model.
8
+
9
+ ```ruby
10
+ # Define the Bank model with an encrypted attribute
11
+ class Bank < CouchbaseOrm::Base
12
+ attribute :name, :string
13
+ attribute :account_number, :encrypted
14
+ attribute :routing_number, :encrypted, alg: "3DES"
15
+ end
16
+ ```
17
+
18
+ In this example, the `account_number` and `routing_number` attributes are marked as encrypted. By default, CouchbaseOrm uses the default `CB_MOBILE_CUSTOM` encryption algorithm for encrypting the values. You can specify a different encryption algorithm by providing the `alg` option.
19
+
20
+ ```plaintext
21
+ {
22
+ "name": "Test Bank",
23
+ "encrypted$account_number": {
24
+ "alg": "CB_MOBILE_CUSTOM",
25
+ "ciphertext": "MTIzNDU2Nzg5"
26
+ },
27
+ "encrypted$routing_number": {
28
+ "alg": "3DES",
29
+ "ciphertext": "OTg3NjU0MzIx"
30
+ },
31
+ "type": "bank"
32
+ }
33
+ ```
34
+
35
+ When a document is saved, CouchbaseOrm stores the encrypted values in the document with a prefix of `encrypted$`. The encrypted values are stored as JSON objects containing the encryption algorithm (`alg`) and the ciphertext (`ciphertext`) of the encrypted value.
36
+
37
+ You can assign values to encrypted attributes just like any other attribute.
38
+
39
+ ```ruby
40
+ bank = Bank.new(name: 'My Bank', account_number: '123456789', routing_number: '987654321')
41
+ ```
42
+
43
+ When the document is saved, CouchbaseOrm encrypts the value of `ssn` using the configured encryption key.
44
+
45
+ ## 11.2. Encryption Process
46
+
47
+ ```ruby
48
+ require 'base64'
49
+ require 'logger'
50
+
51
+ Bank.all.each(&:destroy)
52
+
53
+ # Method to print serialized attributes
54
+ def expect_serialized_attributes(bank)
55
+ serialized_attrs = bank.send(:serialized_attributes)
56
+ serialized_attrs.each do |key, value|
57
+ puts "#{key}: #{value}"
58
+ end
59
+ json_attrs = JSON.parse(bank.to_json)
60
+ json_attrs.each do |key, value|
61
+ puts "#{key}: #{value}"
62
+ end
63
+ bank.as_json.each do |key, value|
64
+ puts "#{key}: #{value}"
65
+ end
66
+ end
67
+
68
+ # Create a new bank record with encrypted attributes
69
+ bank = Bank.new(
70
+ name: "Test Bank",
71
+ account_number: Base64.strict_encode64("123456789"),
72
+ routing_number: Base64.strict_encode64("987654321")
73
+ )
74
+
75
+ # Print serialized attributes before saving
76
+ expect_serialized_attributes(bank)
77
+
78
+ # Save the bank record to Couchbase
79
+ bank.save!
80
+
81
+ # Reload the bank record from Couchbase
82
+ bank.reload
83
+
84
+ # Print serialized attributes after reloading
85
+ expect_serialized_attributes(bank)
86
+
87
+ # Find the bank record by ID
88
+ found_bank = Bank.find(bank.id)
89
+
90
+ # Print serialized attributes after finding
91
+ expect_serialized_attributes(found_bank)
92
+ ```
93
+
94
+ ## 11.3. Encryption and Decryption Process
95
+
96
+ When an encrypted attribute is assigned a value, CouchbaseOrm encrypts the value using the configured encryption key and algorithm. The encrypted value is then stored in the Couchbase document.
97
+
98
+ When retrieving a document with encrypted attributes, CouchbaseOrm automatically decrypts the encrypted values using the same encryption key and algorithm. The decrypted values are then accessible through the model's attributes.
99
+
100
+ It's important to keep the encryption key secure and protect it from unauthorized access. If the encryption key is compromised, the encrypted data can be decrypted by anyone who obtains the key.
101
+
102
+ ## 11.4. Considerations and Best Practices
103
+
104
+ When using encryption in CouchbaseOrm, consider the following best practices:
105
+
106
+ - Keep the encryption key secure and protect it from unauthorized access. Store the key securely and avoid committing it to version control systems.
107
+ - Use strong and unique encryption keys for each environment (development, staging, production) to prevent cross-environment access to encrypted data.
108
+ - Be cautious when querying encrypted attributes as it may impact performance. Consider indexing encrypted attributes separately if frequent querying is required.
109
+ - If you need to search or query encrypted data frequently, consider using a separate encrypted search index or a dedicated encryption service.
110
+ - Ensure that the encryption key is properly rotated and managed. If the encryption key is compromised, you should generate a new key and re-encrypt the affected data.
111
+
112
+ Encryption is a powerful tool for protecting sensitive data, but it should be used judiciously. Encrypting every attribute in your model may not be necessary or practical. Focus on encrypting the most sensitive and confidential data while balancing the trade-offs between security and performance.
113
+
114
+ In the next section, we'll explore logging in CouchbaseOrm and how you can configure and customize logging to monitor and debug your application.
@@ -0,0 +1,48 @@
1
+ # Logging
2
+
3
+ CouchbaseOrm provides a logging mechanism to help you monitor and debug your application. Logging allows you to capture important events, errors, and information during the execution of your application. CouchbaseOrm integrates with the logging framework used in your Ruby application, such as the built-in `Logger` class or third-party logging libraries.
4
+
5
+
6
+ ## 12.1. Log Levels
7
+
8
+ CouchbaseOrm supports different log levels to control the verbosity of the logged messages. The available log levels, in increasing order of severity, are:
9
+
10
+ - `DEBUG`: Detailed information, typically of interest only when diagnosing problems.
11
+ - `INFO`: Confirmation that things are working as expected.
12
+ - `WARN`: An indication that something unexpected happened or indicative of some problem in the near future.
13
+ - `ERROR`: Due to a more serious problem, the software has not been able to perform some function.
14
+ - `FATAL`: A serious error, indicating that the program itself may be unable to continue running.
15
+
16
+ By default, CouchbaseOrm logs messages at the `INFO` level and above. You can change the log level by exporting the `COUCHBASE_ORM_DEBUG` environment variable with the desired log level. For example, to set the log level to `DEBUG`, you can run:
17
+
18
+ ```bash
19
+ export COUCHBASE_ORM_DEBUG=Logger::DEBUG
20
+ ```
21
+
22
+ This command sets the log level to `DEBUG`, which will log detailed information for debugging purposes.
23
+
24
+ ```ruby
25
+ require_relative "app"
26
+
27
+ # Create a new user
28
+ user = User.new(name: 'John Doe', email: 'john@example.com')
29
+ user.save
30
+
31
+ # Update the user's email
32
+ user.email = 'john.doe@example.com'
33
+ user.save
34
+
35
+ # Log a custom message
36
+ CouchbaseOrm.logger.info "User #{user.id} updated email to #{user.email}"
37
+ ```
38
+
39
+ In this example, we create a new `User` instance, save it to the database, update the user's email, and log a custom message using the `CouchbaseOrm.logger` object. The log message includes the user's ID and the updated email address.
40
+
41
+ Output:
42
+ ```
43
+ D, [2024-05-24T11:48:00.071104 #234447] DEBUG -- : Initialize model with {:name=>"John Doe", :email=>"john@example.com"}
44
+ D, [2024-05-24T11:48:00.086972 #234447] DEBUG -- : _create_record - Upsert user-1-vncZNSYZj {"id"=>"user-1-vncZNSYZj", "email"=>"john@example.com", "name"=>"John Doe", "age"=>nil, "height"=>nil, "is_active"=>nil, "birth_date"=>nil, "created_at"=>"2024-05-24T06:18:00Z", "updated_at"=>"2024...
45
+ D, [2024-05-24T11:48:00.113166 #234447] DEBUG -- : _update_record - replace user-1-vncZNSYZj {"id"=>"user-1-vncZNSYZj", "email"=>"john.doe@example.com", "name"=>"John Doe", "age"=>nil, "height"=>nil, "is_active"=>nil, "birth_date"=>nil, "created_at"=>"2024-05-24T06:18:00Z", "updated_at"=>"...
46
+ I, [2024-05-24T11:48:00.115239 #234447] INFO -- : User user-1-vncZNSYZj updated email to john.doe@example.com
47
+ ```
48
+
@@ -0,0 +1,41 @@
1
+ # Troubleshooting
2
+
3
+ When working with CouchbaseOrm, you may encounter various issues or errors. In this section, we'll discuss common problems and provide troubleshooting tips to help you identify and resolve these issues effectively.
4
+
5
+ ## 15.1. Common Issues
6
+
7
+ Here are some common issues you may encounter while using CouchbaseOrm:
8
+
9
+ 1. **Connection Errors**: If you experience connection errors, such as "Failed to connect to Couchbase server," ensure that your Couchbase Server is running and accessible. Verify that the connection details in your configuration file are correct, including the hostname, port, bucket name, username, and password.
10
+
11
+ 2. **Document Not Found**: If you receive a "Document not found" error when retrieving a document, double-check that the document ID is correct and exists in the Couchbase bucket. Make sure you haven't accidentally deleted or modified the document.
12
+
13
+ 3. **N1QL Query Errors**: If your N1QL queries are not returning the expected results or throwing errors, check the syntax of your queries. Ensure that you are using the correct bucket name, index names, and attribute names. Verify that the appropriate indexes are created and available for the queried attributes.
14
+
15
+ 4. **Validation Errors**: If you encounter validation errors when saving a document, review your model's validation rules and make sure the document attributes satisfy those rules. Check for presence, uniqueness, format, and other validation constraints.
16
+
17
+ 5. **Unexpected Behavior**: If you experience unexpected behavior or results, double-check your code logic, query conditions, and attribute assignments. Ensure that you are using the correct methods, parameters, and data types.
18
+
19
+ ## 15.2. Debugging Tips
20
+
21
+ When troubleshooting issues with CouchbaseOrm, consider the following debugging tips:
22
+
23
+ 1. **Enable Logging**: CouchbaseOrm provides logging functionality to help you track the execution flow and identify issues. Enable logging in your application and set the log level to an appropriate verbosity. Review the log output for any error messages, stacktraces, or unexpected behavior.
24
+
25
+ 2. **Inspect Couchbase Server**: Use the Couchbase Web Console or command-line tools to inspect your Couchbase Server instance. Check the bucket details, document contents, and index definitions to ensure they align with your application's expectations.
26
+
27
+ 3. **Use Debugging Tools**: Utilize debugging tools like `byebug` or `pry` to pause the execution of your code at specific points and inspect variable values, object states, and method invocations. Set breakpoints in your code to step through the execution flow and identify the source of the issue.
28
+
29
+ 4. **Test in Isolation**: Isolate the problematic code or query and test it in a separate environment or script. This allows you to focus on the specific issue without the complexity of the entire application. Create a minimal reproducible example that demonstrates the problem.
30
+
31
+ 5. **Verify Couchbase Server Version**: Ensure that you are using a compatible version of Couchbase Server with CouchbaseOrm. Check the CouchbaseOrm documentation for version compatibility and make sure your server version meets the requirements.
32
+
33
+ 6. **Consult Documentation and Community**: Refer to the CouchbaseOrm documentation, API reference, and guides for detailed information on how to use specific features and resolve common issues. Engage with the CouchbaseOrm community through forums, chat channels, or mailing lists to seek assistance from experienced users and developers.
34
+
35
+ 7. **Reproduce and Report**: If you encounter a bug or an issue that seems to be related to CouchbaseOrm itself, try to reproduce the problem in a isolated environment. If the issue persists, consider reporting it to the CouchbaseOrm maintainers or filing an issue on the project's issue tracker, providing detailed information about the problem, steps to reproduce it, and any relevant code snippets or error messages.
36
+
37
+ Remember, troubleshooting is an iterative process. Start by isolating the problem, gathering relevant information, and systematically eliminating possible causes. Break down the issue into smaller components and test each component independently to narrow down the root cause.
38
+
39
+ If you are unable to resolve the issue on your own, don't hesitate to seek help from the CouchbaseOrm community or reach out to the project maintainers for assistance. Providing clear and detailed information about the problem, along with any relevant code snippets and error messages, will help others understand and provide more accurate guidance.
40
+
41
+ By following these troubleshooting tips and leveraging the available resources, you can effectively diagnose and resolve issues encountered while working with CouchbaseOrm.
@@ -0,0 +1,8 @@
1
+ {
2
+ "label": "Tutorial - Ruby Couchbase ORM",
3
+ "position": 4,
4
+ "link": {
5
+ "type": "generated-index",
6
+ "description": "Here's a suggested table of contents for the Couchbase ORM documentation using Docusaurus:"
7
+ }
8
+ }