├── .github └── workflows │ └── RavenClient.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── abstract_document_query.go ├── abstract_index_creation_task.go ├── advanced_session_extention_base.go ├── advanced_session_operations.go ├── after_save_changes_event_args.go ├── aggregation_document_query.go ├── aggregation_query_base.go ├── aggresive_cache_options.go ├── appveyor.yml ├── atomic_integer.go ├── attachment_details.go ├── attachment_name.go ├── attachment_result.go ├── attachment_type.go ├── batch_command.go ├── batch_operation.go ├── batch_options.go ├── before_delete_event_args.go ├── before_query_event_args.go ├── before_store_event_args.go ├── bulk_insert_aborted_exception.go ├── bulk_insert_operation.go ├── character.go ├── circle_criteria.go ├── class_utils.go ├── clean_closeable.go ├── client_configuration.go ├── close_subclause_token.go ├── cluster_topology.go ├── cmd └── run_java_tests │ └── run_java_tests.go ├── cmp_x_chg.go ├── codecov.yml ├── collection_statistics.go ├── command_type.go ├── compact_database_operation.go ├── compact_settings.go ├── compare_exchange_result.go ├── compare_exchange_session_value.go ├── compare_exchange_value.go ├── compare_exchange_value_result_parser.go ├── completable_future.go ├── configure_expiration_operation.go ├── configure_revisions_operation.go ├── conflict_solver.go ├── connection_string.go ├── connection_string_type.go ├── constants.go ├── copier.go ├── create_database_operation.go ├── create_sample_data_operation.go ├── create_subscription_command.go ├── create_subscription_result.go ├── current_index_and_node.go ├── database_changes.go ├── database_promotion_status.go ├── database_put_result.go ├── database_record.go ├── database_record_with_etag.go ├── database_statistics.go ├── database_topology.go ├── declare_token.go ├── delete_attachment_command_data.go ├── delete_attachment_operation.go ├── delete_by_query_operation.go ├── delete_command_data.go ├── delete_compare_exchange_value_operation.go ├── delete_database_operation.go ├── delete_database_result.go ├── delete_document_command.go ├── delete_index_operation.go ├── delete_subscription_command.go ├── disable_index_operation.go ├── distinct_token.go ├── dive-into-raven ├── log.go ├── main.go ├── main_test.go └── pic.png ├── doc.go ├── document_change.go ├── document_change_types.go ├── document_conflict_exception.go ├── document_conventions.go ├── document_conventions_test.go ├── document_info.go ├── document_query.go ├── document_query_customization.go ├── document_query_helper.go ├── document_session.go ├── document_session_attachments.go ├── document_session_attachments_base.go ├── document_session_cluster_transaction.go ├── document_session_revisions.go ├── document_store.go ├── document_subscriptions.go ├── documents_by_id.go ├── documents_changes.go ├── drop_subscription_connection_command.go ├── duration.go ├── duration_serialization_test.go ├── dynamic_spatial_field.go ├── enable_index_operation.go ├── entity_to_json.go ├── errors.go ├── errors_test.go ├── event_handler.go ├── evict_items_from_cache_based_on_changes.go ├── examples ├── log.go ├── main.go ├── main_test.go ├── northwind │ └── definitions.go └── pic.png ├── exception_dispatcher.go ├── exceptions_utils.go ├── explain_query_command.go ├── external_replication.go ├── facet.go ├── facet_aggregation.go ├── facet_base.go ├── facet_builder.go ├── facet_options.go ├── facet_result.go ├── facet_setup.go ├── facet_term_sort_mode.go ├── facet_token.go ├── facet_value.go ├── field_indexing.go ├── field_storage.go ├── field_term_vector.go ├── fields_to_fetch_token.go ├── for_tests.go ├── from_token.go ├── generate_entity_id_on_the_client.go ├── generate_id.go ├── generate_id_test.go ├── generic_query_result.go ├── generic_range_facet.go ├── get_attachment_operation.go ├── get_client_configuration_operation.go ├── get_collection_statistics_operation.go ├── get_compare_exchange_value_operation.go ├── get_compare_exchange_values_operation.go ├── get_conflicts_command.go ├── get_conflicts_result.go ├── get_database_names_operation.go ├── get_database_record_operation.go ├── get_database_topology_command.go ├── get_documents_command.go ├── get_documents_result.go ├── get_identities_operation.go ├── get_index_errors_operation.go ├── get_index_names_operation.go ├── get_index_operation.go ├── get_index_statistics_operation.go ├── get_indexes_operation.go ├── get_indexes_statistics_operation.go ├── get_indexing_status_operation.go ├── get_next_operation_id_command.go ├── get_operation_state_operation.go ├── get_request.go ├── get_response.go ├── get_revision_operation.go ├── get_revisions_bin_entry_command.go ├── get_revisions_command.go ├── get_server_wide_operation_state_operation.go ├── get_statistics_operation.go ├── get_subscription_state_command.go ├── get_subscriptions_command.go ├── get_subscriptions_result.go ├── get_tcp_info_command.go ├── get_terms_operation.go ├── go.mod ├── go.sum ├── group_by.go ├── group_by_count_token.go ├── group_by_document_query.go ├── group_by_field.go ├── group_by_key_token.go ├── group_by_method.go ├── group_by_sum_token.go ├── group_by_token.go ├── handling_maps.md ├── hash_calculator.go ├── head_attachment_command.go ├── head_document_command.go ├── hi_lo_id_generator.go ├── hi_lo_result.go ├── hi_lo_return_command.go ├── http.go ├── http_cache.go ├── http_cache_item.go ├── http_extensions.go ├── i_command_data.go ├── i_lazy_operation.go ├── i_maintenance_operation.go ├── i_more_like_this_builder_base.go ├── i_more_like_this_builder_for_document_query.go ├── i_more_like_this_operations.go ├── i_operation.go ├── i_server_operation.go ├── id_type_and_name.go ├── in_memory_document_session_operations.go ├── includes_util.go ├── index_change.go ├── index_change_types.go ├── index_configuration.go ├── index_creation.go ├── index_definition.go ├── index_definition_builder.go ├── index_errors.go ├── index_field_options.go ├── index_has_changed_operation.go ├── index_information.go ├── index_lock_mode.go ├── index_priority.go ├── index_query.go ├── index_query_base.go ├── index_query_content.go ├── index_query_with_parameters.go ├── index_running_status.go ├── index_state.go ├── index_stats.go ├── index_type.go ├── indexing_error.go ├── indexing_status.go ├── inflect.go ├── intersect_marker_token.go ├── java_script_array.go ├── json_array_result.go ├── json_extensions.go ├── json_operation.go ├── json_util.go ├── kill_operation_command.go ├── lazy.go ├── lazy_aggregation_query_operation.go ├── lazy_load_operation.go ├── lazy_multi_loader_with_include.go ├── lazy_query_operation.go ├── lazy_session_operations.go ├── lazy_starts_with_operation.go ├── lazy_suggestion_query_operation.go ├── leader_stamp.go ├── load_operation.go ├── load_starting_with_operation.go ├── load_token.go ├── maintenance_operation_executor.go ├── map_util.go ├── metadata_as_dictionary.go ├── method_call.go ├── modify_ongoing_task_result.go ├── more_like_this_base.go ├── more_like_this_builder.go ├── more_like_this_options.go ├── more_like_this_query_result.go ├── more_like_this_scope.go ├── more_like_this_stop_words.go ├── more_like_this_token.go ├── more_like_this_using_any_document.go ├── more_like_this_using_document.go ├── more_like_this_using_document_for_document_query.go ├── multi_database_hi_lo_id_generator.go ├── multi_get_command.go ├── multi_get_operation.go ├── multi_loader_with_include.go ├── multi_type_hi_lo_id_generator.go ├── negate_token.go ├── next_hi_lo_command.go ├── next_identity_for_command.go ├── node_id.go ├── node_selector.go ├── object_set.go ├── open_subclause_token.go ├── operation.go ├── operation_exception_result.go ├── operation_executor.go ├── operation_id_result.go ├── operation_status_change.go ├── order_by_token.go ├── ordering_type.go ├── parameters.go ├── patch_by_query_operation.go ├── patch_command_data.go ├── patch_operation.go ├── patch_request.go ├── patch_result.go ├── patch_status.go ├── point_field.go ├── porting_notes.md ├── put_attachment_command_data.go ├── put_attachment_operation.go ├── put_client_configuration_operation.go ├── put_command_data_with_json.go ├── put_compare_exchange_value_operation.go ├── put_connection_string_operation.go ├── put_connection_string_result.go ├── put_document_command.go ├── put_index_result.go ├── put_indexes_operation.go ├── put_indexes_response.go ├── put_result.go ├── query_command.go ├── query_data.go ├── query_field_util.go ├── query_operation.go ├── query_operation_options.go ├── query_operator.go ├── query_operator_token.go ├── query_result.go ├── query_result_base.go ├── query_statistics.go ├── query_stream_command.go ├── query_token.go ├── raft_id_generator.go ├── range_builder.go ├── range_builder_test.go ├── range_facet.go ├── raven_command.go ├── raven_command_response_type.go ├── raven_connection_string.go ├── raw_document_query.go ├── read_balance_behavior.go ├── readme-dev.md ├── readme.md ├── reflect.go ├── reflect_test.go ├── replication_node.go ├── request_executor.go ├── requests_helpers.go ├── reset_index_operation.go ├── response_dispose_handling.go ├── response_time_information.go ├── revision.go ├── revisions_collection_configuration.go ├── revisions_configuration.go ├── script_resolver.go ├── scripts ├── appveyor_run_tests.sh ├── appveyor_run_tests_win.bat ├── compile.ps1 ├── download_mac_and_unpack_locally.sh ├── lint.go ├── loc.ps1 ├── loc.py ├── mkcert.sh ├── profile.ps1 ├── run_dive_example.ps1 ├── run_example.ps1 ├── run_java_tests.ps1 ├── run_server_locally.ps1 ├── run_server_locally.sh ├── run_single_test.ps1 ├── run_single_test_multiple.ps1 ├── run_tests.ps1 ├── test_cert.conf └── travis_run_tests.sh ├── search_operator.go ├── seed_identity_for_command.go ├── semaphore.go ├── server_node.go ├── server_operation_executor.go ├── server_wide_operation.go ├── serverwide ├── certificates │ ├── certificate_definition.go │ └── operation_put_certificate.go └── operations │ ├── operation_add_cluster_node.go │ ├── operation_add_database_to_node.go │ ├── operation_boostrap.go │ ├── operation_database_health_check.go │ ├── operation_demote_cluster_node.go │ ├── operation_get_build_number.go │ ├── operation_get_cluster_topology.go │ ├── operation_promote_cluster_node.go │ └── operation_remove_cluster_node.go ├── session_created_event_args.go ├── session_info.go ├── session_options.go ├── set_indexes_lock_operation.go ├── set_indexes_priority_operation.go ├── shape_token.go ├── size.go ├── spatial_criteria.go ├── spatial_criteria_factory.go ├── spatial_field_type.go ├── spatial_options.go ├── spatial_options_factory.go ├── spatial_relation.go ├── spatial_search_strategy.go ├── spatial_units.go ├── start_index_operation.go ├── start_indexing_operation.go ├── starts_with_args.go ├── stop_index_operation.go ├── stop_indexing_operation.go ├── stream_command.go ├── stream_operation.go ├── stream_query_statistics.go ├── stream_result.go ├── stream_result_response.go ├── string_array.go ├── string_array_test.go ├── string_distance_types.go ├── string_utils.go ├── subscription_batch.go ├── subscription_connection_client_message.go ├── subscription_connection_server_message.go ├── subscription_creation_options.go ├── subscription_opening_strategy.go ├── subscription_state.go ├── subscription_state_with_node_details.go ├── subscription_tryout.go ├── subscription_worker.go ├── subscription_worker_options.go ├── suggest_token.go ├── suggestion_base.go ├── suggestion_builder.go ├── suggestion_document_query.go ├── suggestion_options.go ├── suggestion_query_base.go ├── suggestion_result.go ├── suggestion_sort_mode.go ├── suggestion_with_term.go ├── suggestion_with_terms.go ├── tcp_connection_header_message.go ├── tcp_connection_header_response.go ├── tcp_connection_info.go ├── tcp_connection_status.go ├── tcp_negotiate_parameters.go ├── tcp_negotiation.go ├── tcp_utils.go ├── terms_query_result.go ├── tests ├── address_test.go ├── advanced_patching_test.go ├── aggregation_test.go ├── aggresive_caching_test.go ├── attachments_revisions_test.go ├── attachments_session_test.go ├── basic_documents_test.go ├── bounding_box_index_test.go ├── bulk_inserts_test.go ├── caching_of_document_include_test.go ├── capturing_cread_closer_test.go ├── cert │ └── test_cert.conf ├── changes_test.go ├── client_configuration_test.go ├── cluster_transaction_test.go ├── compact_test.go ├── company_test.go ├── company_type_test.go ├── contact_test.go ├── contains_test.go ├── crud_test.go ├── custom_serialization_test.go ├── delete_by_query_test.go ├── delete_document_command_test.go ├── delete_test.go ├── document_replication_test.go ├── document_streaming_test.go ├── documents_load_test.go ├── employee_test.go ├── exists_test.go ├── expiration_operation_test.go ├── facet_paging_test.go ├── facet_test_base_test.go ├── first_class_patch_test.go ├── geek_person_test.go ├── get_database_record_test.go ├── get_next_operation_id_command_test.go ├── get_statistics_command_test.go ├── get_tcp_info_test.go ├── get_topology_test.go ├── go1_test.go ├── go_northwind_test.go ├── hi_lo_test.go ├── https_test.go ├── index_operations_test.go ├── indexes_from_client_test.go ├── lazy_aggregation_embedded_test.go ├── lazy_test.go ├── load_all_starting_with_test.go ├── load_into_stream_test.go ├── load_test.go ├── logging_test.go ├── more_like_this_test.go ├── next_and_seed_identities_test.go ├── non_null_time.go ├── nullable_time.go ├── operation_add_database_to_node_test.go ├── operation_database_health_check_test.go ├── operation_get_cluster_topology_test.go ├── operation_put_certificate_test.go ├── operation_remove_cluster_node_test.go ├── order_line_test.go ├── order_test.go ├── patch_test.go ├── person_test.go ├── post_test.go ├── put_document_command_test.go ├── queries_with_custom_functions_test.go ├── query_streaming_test.go ├── query_test.go ├── raven_test_driver_test.go ├── ravendb_10566_test.go ├── ravendb_10641_test.go ├── ravendb_12132_test.go ├── ravendb_12790_test.go ├── ravendb_14006_test.go ├── ravendb_14989_test.go ├── ravendb_5669_test.go ├── ravendb_6292_test.go ├── ravendb_8328_test.go ├── ravendb_8761_test.go ├── ravendb_903_test.go ├── ravendb_9676_test.go ├── regex_query_test.go ├── replication_test_base_test.go ├── request_executor_test.go ├── revisions_subscriptions_test.go ├── revisions_test.go ├── secured_subscriptions_basic_test.go ├── simon_bartlett_test.go ├── simple_multi_map_test.go ├── spatial_queries_test.go ├── spatial_search_test.go ├── spatial_sorting_test.go ├── spatial_test.go ├── store_test.go ├── string_nil_save_changes_test.go ├── subscriptions_basic_test.go ├── suggestions_lazy_test.go ├── suggestions_test.go ├── track_entity_test.go ├── unique_values_test.go ├── user_test.go ├── util_test.go ├── what_changed_test.go └── zip_util_test.go ├── time.go ├── time_test.go ├── time_utils.go ├── topology.go ├── true_token.go ├── update_external_replication_operation.go ├── url_utils.go ├── util.go ├── util_test.go ├── uuid.go ├── where_operator.go ├── where_params.go ├── where_token.go ├── wkt_criteria.go └── wkt_field.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | # Test binary, build with `go test -c` 7 | *.test 8 | 9 | # Output of the go coverage tool, specifically when used with LiteIDE 10 | *.out 11 | 12 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 13 | .glide/ 14 | /.idea 15 | 16 | /certs 17 | 18 | responses.log 19 | .vscode/ 20 | main 21 | cmd/test/debug 22 | cmd/loggingproxy/db 23 | logs/ 24 | RavenDB/ 25 | coverage.txt 26 | RavenDB.tar.bz2 27 | netgraph 28 | *.zip 29 | .DS_Store 30 | cpu.prof 31 | http_requests_log.txt 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 ravendb 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /advanced_session_extention_base.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // AdvancedSessionExtensionBase implements common advanced session operations 4 | type AdvancedSessionExtensionBase struct { 5 | session *InMemoryDocumentSessionOperations 6 | documents []*documentInfo 7 | requestExecutor *RequestExecutor 8 | sessionInfo *SessionInfo 9 | documentStore *DocumentStore 10 | deferredCommandsMap map[idTypeAndName]ICommandData 11 | 12 | deletedEntities *objectSet 13 | documentsByID *documentsByID 14 | } 15 | 16 | func newAdvancedSessionExtensionBase(session *InMemoryDocumentSessionOperations) *AdvancedSessionExtensionBase { 17 | return &AdvancedSessionExtensionBase{ 18 | session: session, 19 | documents: session.documentsByEntity, 20 | requestExecutor: session.GetRequestExecutor(), 21 | sessionInfo: session.sessionInfo, 22 | documentStore: session.GetDocumentStore(), 23 | deferredCommandsMap: session.deferredCommandsMap, 24 | deletedEntities: session.deletedEntities, 25 | documentsByID: session.documentsByID, 26 | } 27 | } 28 | 29 | // Defer defers multiple commands to be executed on SaveChnages 30 | func (e *AdvancedSessionExtensionBase) Defer(commands ...ICommandData) { 31 | e.session.Defer(commands...) 32 | } 33 | -------------------------------------------------------------------------------- /after_save_changes_event_args.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // AfterSaveChangesEventArgs describes arguments for "after save changes" listener 4 | type AfterSaveChangesEventArgs struct { 5 | documentMetadata *MetadataAsDictionary 6 | 7 | Session *InMemoryDocumentSessionOperations 8 | DocumentID string 9 | Entity interface{} 10 | } 11 | 12 | func newAfterSaveChangesEventArgs(session *InMemoryDocumentSessionOperations, documentID string, entity interface{}) *AfterSaveChangesEventArgs { 13 | return &AfterSaveChangesEventArgs{ 14 | Session: session, 15 | DocumentID: documentID, 16 | Entity: entity, 17 | } 18 | } 19 | 20 | // GetDocumentMetadata returns metadata for the entity represented by this event 21 | func (a *AfterSaveChangesEventArgs) GetDocumentMetadata() *MetadataAsDictionary { 22 | if a.documentMetadata == nil { 23 | a.documentMetadata, _ = a.Session.GetMetadataFor(a.Entity) 24 | } 25 | 26 | return a.documentMetadata 27 | } 28 | -------------------------------------------------------------------------------- /aggregation_document_query.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // Note: In Java it's IAggregationDocumentQuery but in Go we use 4 | // concrete type AggregationDocumentQuery 5 | 6 | // Note: AggregationDocumentQuery is fused into AggregationQueryBase because 7 | // in Java AggregationQueryBase calls functions implemented in AggregationDocumentQuery 8 | // and that doesn't translate to Go's embedding 9 | type AggregationDocumentQuery = aggregationQueryBase 10 | -------------------------------------------------------------------------------- /aggresive_cache_options.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "time" 4 | 5 | // TODO: should this be exported? 6 | type AggressiveCacheOptions struct { 7 | Duration time.Duration 8 | } 9 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | # based on https://github.com/joefitzgerald/go-plus/blob/master/appveyor.yml 2 | version: 4.0.{build} 3 | 4 | image: 5 | - Visual Studio 2017 6 | - Ubuntu1804 7 | 8 | stack: go 1.11 9 | 10 | build: off 11 | 12 | notifications: 13 | - provider: Email 14 | to: 15 | - kkowalczyk@gmail.com 16 | 17 | environment: 18 | LOG_HTTP_REQUEST_SUMMARY: true 19 | LOG_FAILED_HTTP_REQUESTS: true 20 | LOG_FAILED_HTTP_REQUESTS_DELAYED: true 21 | LOG_ALL_REQUESTS: true 22 | VERBOSE_LOG: true 23 | RAVENDB_SERVER_VERSION: 4.1.3 24 | 25 | install: 26 | - go version 27 | - go env 28 | - cmd: echo %CD% 29 | - sh: echo `pwd` 30 | - sh: sudo apt-get -qq update 31 | - sh: sudo apt-get install -y wget tar bzip2 zip 32 | - sh: sudo cp ./certs/ca.crt /usr/local/share/ca-certificates/ca.crt 33 | - sh: sudo update-ca-certificates 34 | # note: when changing version, update RAVENDB_SERVER_VERSION in appveyor_run_tests.sh 35 | # and above in environment 36 | - sh: wget -O RavenDB.tar.bz2 https://daily-builds.s3.amazonaws.com/RavenDB-4.1.3-linux-x64.tar.bz2 37 | - sh: tar xvjf RavenDB.tar.bz2 38 | - sh: rm RavenDB.tar.bz2 39 | - sh: ls -lah RavenDB 40 | 41 | # https://www.appveyor.com/docs/windows-images-software/#golang 42 | 43 | test_script: 44 | - cmd: .\scripts\appveyor_run_tests_win.bat 45 | - sh: ./scripts/appveyor_run_tests.sh 46 | 47 | deploy: off 48 | -------------------------------------------------------------------------------- /atomic_integer.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "sync/atomic" 4 | 5 | // atomicInteger makes porting Java code easier 6 | type atomicInteger struct { 7 | N int32 8 | } 9 | 10 | func (i *atomicInteger) incrementAndGet() int { 11 | res := atomic.AddInt32(&i.N, 1) 12 | return int(res) 13 | } 14 | 15 | func (i *atomicInteger) get() int { 16 | res := atomic.LoadInt32(&i.N) 17 | return int(res) 18 | } 19 | 20 | func (i *atomicInteger) Get() int { 21 | res := atomic.LoadInt32(&i.N) 22 | return int(res) 23 | } 24 | 25 | func (i *atomicInteger) set(n int) { 26 | atomic.StoreInt32(&i.N, int32(n)) 27 | } 28 | 29 | func (i *atomicInteger) compareAndSet(old, new int) bool { 30 | return atomic.CompareAndSwapInt32(&i.N, int32(old), int32(new)) 31 | } 32 | 33 | func (i *atomicInteger) decrementAndGet() int { 34 | res := atomic.AddInt32(&i.N, -1) 35 | return int(res) 36 | } 37 | -------------------------------------------------------------------------------- /attachment_details.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // AttachmentDetails represents details of an attachment 4 | type AttachmentDetails struct { 5 | AttachmentName 6 | ChangeVector *string `json:"ChangeVector"` 7 | DocumentID string `json:"DocumentId"` 8 | } 9 | -------------------------------------------------------------------------------- /attachment_name.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // AttachmentName represents infor about an attachment 4 | type AttachmentName struct { 5 | Name string `json:"Name"` 6 | Hash string `json:"Hash"` 7 | ContentType string `json:"ContentType"` 8 | Size int64 `json:"Size"` 9 | } 10 | -------------------------------------------------------------------------------- /attachment_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | ) 7 | 8 | // Note: In Java it's CloseableAttachmentResult 9 | 10 | // AttachmentResult represents an attachment 11 | type AttachmentResult struct { 12 | Data io.Reader 13 | Details *AttachmentDetails 14 | response *http.Response 15 | } 16 | 17 | func newAttachmentResult(response *http.Response, details *AttachmentDetails) *AttachmentResult { 18 | return &AttachmentResult{ 19 | Data: response.Body, 20 | Details: details, 21 | response: response, 22 | } 23 | } 24 | 25 | // Close closes the attachment 26 | func (r *AttachmentResult) Close() error { 27 | if r.response.Body != nil { 28 | return r.response.Body.Close() 29 | } 30 | return nil 31 | } 32 | -------------------------------------------------------------------------------- /attachment_type.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type AttachmentType = string 4 | 5 | const ( 6 | AttachmentDocument = "Document" 7 | AttachmentRevision = "Revision" 8 | ) 9 | -------------------------------------------------------------------------------- /batch_options.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "time" 4 | 5 | // BatchOptions describes options for batch operations 6 | type BatchOptions struct { 7 | waitForReplicas bool 8 | numberOfReplicasToWaitFor int 9 | waitForReplicasTimeout time.Duration 10 | majority bool 11 | throwOnTimeoutInWaitForReplicas bool 12 | 13 | waitForIndexes bool 14 | waitForIndexesTimeout time.Duration 15 | throwOnTimeoutInWaitForIndexes bool 16 | waitForSpecificIndexes []string 17 | } 18 | 19 | // NewBatchOptions returns new BatchOptions 20 | func NewBatchOptions() *BatchOptions { 21 | return &BatchOptions{ 22 | throwOnTimeoutInWaitForReplicas: true, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /before_delete_event_args.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // BeforeDeleteEventArgs describes arguments for "before delete" listener 4 | type BeforeDeleteEventArgs struct { 5 | documentMetadata *MetadataAsDictionary 6 | 7 | Session *InMemoryDocumentSessionOperations 8 | DocumentID string 9 | Entity interface{} 10 | } 11 | 12 | func newBeforeDeleteEventArgs(session *InMemoryDocumentSessionOperations, documentID string, entity interface{}) *BeforeDeleteEventArgs { 13 | return &BeforeDeleteEventArgs{ 14 | Session: session, 15 | DocumentID: documentID, 16 | Entity: entity, 17 | } 18 | } 19 | 20 | // GetDocumentMetadata returns metadata for the entity being deleted 21 | func (a *BeforeDeleteEventArgs) GetDocumentMetadata() *MetadataAsDictionary { 22 | if a.documentMetadata == nil { 23 | a.documentMetadata, _ = a.Session.GetMetadataFor(a.Entity) 24 | } 25 | 26 | return a.documentMetadata 27 | } 28 | -------------------------------------------------------------------------------- /before_query_event_args.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // BeforeQueryEventArgs describes arguments for "before query" event 4 | type BeforeQueryEventArgs struct { 5 | Session *InMemoryDocumentSessionOperations 6 | QueryCustomization *DocumentQueryCustomization 7 | } 8 | -------------------------------------------------------------------------------- /before_store_event_args.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // BeforeStoreEventArgs describe arguments for "before store" listener 4 | type BeforeStoreEventArgs struct { 5 | documentMetadata *MetadataAsDictionary 6 | 7 | Session *InMemoryDocumentSessionOperations 8 | DocumentID string 9 | Entity interface{} 10 | } 11 | 12 | func newBeforeStoreEventArgs(session *InMemoryDocumentSessionOperations, documentID string, entity interface{}) *BeforeStoreEventArgs { 13 | return &BeforeStoreEventArgs{ 14 | Session: session, 15 | DocumentID: documentID, 16 | Entity: entity, 17 | } 18 | } 19 | 20 | func (a *BeforeStoreEventArgs) isMetadataAccessed() bool { 21 | return a.documentMetadata != nil 22 | } 23 | 24 | // GetDocumentMetadata returns metadata for entity represented by this event 25 | func (a *BeforeStoreEventArgs) GetDocumentMetadata() *MetadataAsDictionary { 26 | if a.documentMetadata == nil { 27 | a.documentMetadata, _ = a.Session.GetMetadataFor(a.Entity) 28 | } 29 | 30 | return a.documentMetadata 31 | } 32 | -------------------------------------------------------------------------------- /bulk_insert_aborted_exception.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // BulkInsertAbortedError represents "bulk insert aborted" error 4 | type BulkInsertAbortedError struct { 5 | RavenError 6 | } 7 | 8 | func newBulkInsertAbortedError(format string, args ...interface{}) *BulkInsertAbortedError { 9 | res := &BulkInsertAbortedError{ 10 | RavenError: *newRavenError(format, args...), 11 | } 12 | return res 13 | } 14 | -------------------------------------------------------------------------------- /character.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // helpers to make Java porting easier 4 | 5 | func isLetterOrDigit(r rune) bool { 6 | if r >= 'a' && r <= 'z' { 7 | return true 8 | } 9 | if r >= 'A' && r <= 'Z' { 10 | return true 11 | } 12 | if r >= '0' && r <= '9' { 13 | return true 14 | } 15 | return false 16 | } 17 | 18 | func isLetter(r rune) bool { 19 | if r >= 'a' && r <= 'z' { 20 | return true 21 | } 22 | if r >= 'A' && r <= 'Z' { 23 | return true 24 | } 25 | return false 26 | } 27 | -------------------------------------------------------------------------------- /circle_criteria.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // CircleCriteria describes circle criteria 4 | type CircleCriteria struct { 5 | SpatialCriteriaCommon 6 | _radius float64 7 | _latitude float64 8 | _longitude float64 9 | _radiusUnits SpatialUnits 10 | } 11 | 12 | // NewCircleCriteria returns new CircleCriteria 13 | func NewCircleCriteria(radius float64, latitude float64, longitude float64, radiusUnits SpatialUnits, relation SpatialRelation, distErrorPercent float64) *CircleCriteria { 14 | 15 | res := &CircleCriteria{ 16 | _radius: radius, 17 | _latitude: latitude, 18 | _longitude: longitude, 19 | _radiusUnits: radiusUnits, 20 | } 21 | res._relation = relation 22 | res._distanceErrorPct = distErrorPercent 23 | return res 24 | } 25 | 26 | // ToQueryToken creates a token 27 | func (c *CircleCriteria) ToQueryToken(fieldName string, addQueryParameter func(interface{}) string) queryToken { 28 | return c.SpatialCriteriaCommon.toQueryTokenCommon(c, fieldName, addQueryParameter) 29 | } 30 | 31 | // GetShapeToken returns shapeToken 32 | func (c *CircleCriteria) GetShapeToken(addQueryParameter func(interface{}) string) *shapeToken { 33 | return shapeTokenCircle(addQueryParameter(c._radius), addQueryParameter(c._latitude), 34 | addQueryParameter(c._longitude), c._radiusUnits) 35 | } 36 | -------------------------------------------------------------------------------- /class_utils.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "reflect" 4 | 5 | // TODO: verify this is the same as Java 6 | func isPrimitiveOrWrapper(t reflect.Type) bool { 7 | kind := t.Kind() 8 | 9 | /* 10 | Uintptr 11 | Complex64 12 | Complex128 13 | Array 14 | Chan 15 | Func 16 | Interface 17 | Map 18 | Ptr 19 | Slice 20 | Struct 21 | UnsafePointer 22 | */ 23 | switch kind { 24 | case reflect.Bool, 25 | reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, 26 | reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, 27 | reflect.Float32, reflect.Float64, reflect.String: 28 | return true 29 | } 30 | return false 31 | } 32 | 33 | // Go doesn't have enums 34 | func typeIsEnum(t reflect.Type) bool { 35 | return false 36 | } 37 | -------------------------------------------------------------------------------- /clean_closeable.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // Note: we use io.Closer instead of CleanCloseable 4 | 5 | // nilCloser is meant for functions that return io.Closer type and 6 | // want to return nil. 7 | // Instead do: 8 | // var res *nilCloser 9 | // return res 10 | // That way the caller can call Close() without checking for nil 11 | type nilCloser struct { 12 | } 13 | 14 | // Close closes nil closer 15 | func (n *nilCloser) Close() error { 16 | // works even if n is nil 17 | return nil 18 | } 19 | 20 | // funcCloser wraps a function as io.Closer 21 | type funcCloser struct { 22 | fn func() error 23 | } 24 | 25 | // newFuncCloser returns a new funcCloser 26 | func newFuncCloser(fn func() error) *funcCloser { 27 | return &funcCloser{ 28 | fn: fn, 29 | } 30 | } 31 | 32 | // Close calls underlying Close function 33 | func (f *funcCloser) Close() error { 34 | return f.fn() 35 | } 36 | -------------------------------------------------------------------------------- /client_configuration.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // ClientConfiguration represents client configuration 4 | type ClientConfiguration struct { 5 | Etag int64 `json:"Etag"` 6 | IsDisabled bool `json:"Disabled"` 7 | // TODO: should this be *int ? 8 | MaxNumberOfRequestsPerSession int `json:"MaxNumberOfRequestsPerSession"` 9 | ReadBalanceBehavior ReadBalanceBehavior `json:"ReadBalanceBehavior"` 10 | } 11 | -------------------------------------------------------------------------------- /close_subclause_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &closeSubclauseToken{} 6 | 7 | var ( 8 | closeSubclauseTokenInstance = &closeSubclauseToken{} 9 | ) 10 | 11 | type closeSubclauseToken struct { 12 | } 13 | 14 | func (t *closeSubclauseToken) writeTo(writer *strings.Builder) error { 15 | writer.WriteString(")") 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /cmp_x_chg.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // CmpXchg represents data for cmp xchg method 4 | type CmpXchg struct { 5 | MethodCallData 6 | } 7 | 8 | // CmpXchgValue returns CmpXchg for a given key 9 | func CmpXchgValue(key string) *CmpXchg { 10 | cmpXchg := &CmpXchg{} 11 | cmpXchg.args = []interface{}{key} 12 | return cmpXchg 13 | } 14 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | ci: 3 | - !travis 4 | - appveyor 5 | notify: 6 | require_ci_to_pass: yes 7 | 8 | coverage: 9 | precision: 2 10 | round: down 11 | range: "70...100" 12 | 13 | status: 14 | project: yes 15 | patch: yes 16 | changes: no 17 | 18 | parsers: 19 | gcov: 20 | branch_detection: 21 | conditional: yes 22 | loop: yes 23 | method: no 24 | macro: no 25 | 26 | comment: 27 | layout: "header, diff" 28 | behavior: default 29 | require_changes: no 30 | -------------------------------------------------------------------------------- /collection_statistics.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // CollectionStatistics describes collection statistics 4 | type CollectionStatistics struct { 5 | CountOfDocuments int `json:"CountOfDocuments"` 6 | CountOfConflicts int `json:"CountOfConflicts"` 7 | Collections map[string]int `json:"Collections"` 8 | } 9 | -------------------------------------------------------------------------------- /command_type.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // using type alias for easy json serialization 4 | type CommandType = string 5 | 6 | // Note: this is enum in Java but those are serialized to json as strings so 7 | // making them strings is better in Go 8 | const ( 9 | //CommandNone = "NONE" 10 | CommandPut = "PUT" 11 | CommandPatch = "PATCH" 12 | CommandDelete = "DELETE" 13 | CommandAttachmentPut = "ATTACHMENT_PUT" 14 | CommandAttachmentDelete = "ATTACHMENT_DELETE" 15 | CommandClientAnyCommand = "CLIENT_ANY_COMMAND" 16 | CommandClientNotAttachment = "CLIENT_NOT_ATTACHMENT" 17 | CompareExchangePut = "COMPARE_EXCHANGE_PUT" 18 | CompareExchangeDelete = "COMPARE_EXCHANGE_DELETE" 19 | ) 20 | -------------------------------------------------------------------------------- /compact_settings.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // CompactSettings is an argument to CompactDatabaseOperation 4 | type CompactSettings struct { 5 | DatabaseName string `json:"DatabaseName"` 6 | Documents bool `json:"Documents"` 7 | Indexes []string `json:"Indexes,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /conflict_solver.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // ConflictSolver describes how to resolve conflicts 4 | type ConflictSolver struct { 5 | ResolveByCollection map[string]*ScriptResolver `json:"ResolveByCollection"` 6 | ResolveToLatest bool `json:"ResolveToLatest"` 7 | } 8 | -------------------------------------------------------------------------------- /connection_string.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // ConnectionString represents connection string 4 | // used as argument to PutConnectionStringCommand 5 | type ConnectionString struct { 6 | Name string `json:"Name"` 7 | // Note: Java has this as a virtual function getType() 8 | Type ConnectionStringType `json:"Type"` 9 | } 10 | -------------------------------------------------------------------------------- /connection_string_type.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // TODO: only used in ConnectionString which is unused 4 | type ConnectionStringType = string 5 | 6 | const ( 7 | ConnectionStringTypeNone = "None" 8 | ConnectionStringTypeRaven = "Raven" 9 | ConnectionStringTypeSQL = "Sql" 10 | ) 11 | -------------------------------------------------------------------------------- /create_subscription_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | ) 7 | 8 | var ( 9 | _ RavenCommand = &CreateSubscriptionCommand{} 10 | ) 11 | 12 | // CreateSubscriptionCommand represents "create subscription" command 13 | type CreateSubscriptionCommand struct { 14 | RavenCommandBase 15 | 16 | conventions *DocumentConventions 17 | options *SubscriptionCreationOptions 18 | id string 19 | 20 | Result *CreateSubscriptionResult 21 | } 22 | 23 | func newCreateSubscriptionCommand(conventions *DocumentConventions, options *SubscriptionCreationOptions, id string) *CreateSubscriptionCommand { 24 | return &CreateSubscriptionCommand{ 25 | RavenCommandBase: NewRavenCommandBase(), 26 | 27 | conventions: conventions, 28 | options: options, 29 | id: id, 30 | } 31 | } 32 | 33 | func (c *CreateSubscriptionCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 34 | uri := node.URL + "/databases/" + node.Database + "/subscriptions" 35 | 36 | if c.id != "" { 37 | uri += "?id=" + c.id 38 | } 39 | 40 | d, err := json.Marshal(c.options) 41 | if err != nil { 42 | return nil, err 43 | } 44 | 45 | return newHttpPut(uri, d) 46 | } 47 | 48 | func (c *CreateSubscriptionCommand) SetResponse(response []byte, fromCache bool) error { 49 | if len(response) == 0 { 50 | return throwInvalidResponse() 51 | } 52 | return jsonUnmarshal(response, &c.Result) 53 | } 54 | -------------------------------------------------------------------------------- /create_subscription_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // CreateSubscriptionResult represents result for "create subscription" command 4 | type CreateSubscriptionResult struct { 5 | Name string `json:"Name"` 6 | } 7 | -------------------------------------------------------------------------------- /current_index_and_node.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type CurrentIndexAndNode struct { 4 | currentIndex int 5 | currentNode *ServerNode 6 | } 7 | 8 | func NewCurrentIndexAndNode(currentIndex int, currentNode *ServerNode) *CurrentIndexAndNode { 9 | return &CurrentIndexAndNode{ 10 | currentIndex: currentIndex, 11 | currentNode: currentNode, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /database_promotion_status.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type DatabasePromotionStatus = string 4 | 5 | const ( 6 | DatabasePromotionStatusWaitingForFirstPromotion = "WaitingForFirstPromotion" 7 | DatabasePromotionStatusNotResponding = "NotResponding" 8 | DatabasePromotionStatusIndexNotUpToDate = "IndexNotUpToDate" 9 | DatabasePromotionStatusChangeVectorNotMerged = "ChangeVectorNotMerged" 10 | DatabasePromotionStatusWaitingForResponse = "WaitingForResponse" 11 | DatabasePromotionStatusOk = "Ok" 12 | ) 13 | -------------------------------------------------------------------------------- /database_put_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // DatabasePutResult describes server response for e.g. CreateDatabaseCommand 4 | type DatabasePutResult struct { 5 | RaftCommandIndex int64 `json:"RaftCommandIndex"` 6 | Name string `json:"Name"` 7 | DatabaseTopology Topology `json:"Topology"` 8 | NodesAddedTo []string `json:"NodesAddedTo"` 9 | } 10 | -------------------------------------------------------------------------------- /database_record.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // DatabaseRecord represents database record 4 | type DatabaseRecord struct { 5 | DatabaseName string `json:"DatabaseName"` 6 | Disabled bool `json:"Disabled"` 7 | DataDirectory string `json:"DataDirectory,omitempty"` 8 | Settings map[string]string `json:"Settings"` 9 | ConflictSolverConfig *ConflictSolver `json:"ConflictSolverConfig"` 10 | Encrypted bool `json:"Encrypted"` 11 | DatabaseTopology *DatabaseTopology `json:"DatabaseTopology"` 12 | } 13 | 14 | // NewDatabaseRecord returns new database record 15 | func NewDatabaseRecord() *DatabaseRecord { 16 | return &DatabaseRecord{ 17 | Settings: map[string]string{}, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /database_record_with_etag.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // DatabaseRecordWithEtag represents database record with etag 4 | type DatabaseRecordWithEtag struct { 5 | DatabaseRecord 6 | Etag int64 `json:"Etag"` 7 | } 8 | -------------------------------------------------------------------------------- /database_topology.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // DatabaseTopology describes a topology of the database 4 | type DatabaseTopology struct { 5 | Members []string `json:"Members"` 6 | Promotables []string `json:"Promotables"` 7 | Rehabs []string `json:"Rehabs"` 8 | PredefinedMentors map[string]string `json:"PredefinedMentors"` 9 | DemotionReasons map[string]string `json:"DemotionReasons"` 10 | PromotablesStatus map[string]string `json:"PromotablesStatus"` 11 | ReplicationFactor int `json:"ReplicationFactor"` 12 | DynamicNodesDistribution bool `json:"DynamicNodesDistribution"` 13 | Stamp LeaderStamp `json:"Stamp"` 14 | } 15 | -------------------------------------------------------------------------------- /declare_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &declareToken{} 6 | 7 | type declareToken struct { 8 | name string 9 | parameters string 10 | body string 11 | } 12 | 13 | /* 14 | // TODO: why is this unused? Should declareToken be publicly exposed? 15 | func newDeclareToken(name string, body string, parameters string) *declareToken { 16 | return &declareToken{ 17 | name: name, 18 | body: body, 19 | parameters: parameters, 20 | } 21 | } 22 | */ 23 | 24 | func (t *declareToken) writeTo(writer *strings.Builder) error { 25 | 26 | writer.WriteString("declare ") 27 | writer.WriteString("function ") 28 | writer.WriteString(t.name) 29 | writer.WriteString("(") 30 | writer.WriteString(t.parameters) 31 | writer.WriteString(") ") 32 | writer.WriteString("{") 33 | writer.WriteString("\n") 34 | writer.WriteString(t.body) 35 | writer.WriteString("\n") 36 | writer.WriteString("}") 37 | writer.WriteString("\n") 38 | return nil 39 | } 40 | -------------------------------------------------------------------------------- /delete_attachment_command_data.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type DeleteAttachmentCommandData struct { 4 | *CommandData 5 | } 6 | 7 | // NewDeleteAttachmentCommandData creates CommandData for Delete Attachment command 8 | func NewDeleteAttachmentCommandData(documentID string, name string, changeVector *string) (*DeleteAttachmentCommandData, error) { 9 | if stringIsBlank(documentID) { 10 | return nil, newIllegalArgumentError("DocumentId cannot be null or empty") 11 | } 12 | if stringIsBlank(name) { 13 | return nil, newIllegalArgumentError("Name cannot be null or empty") 14 | } 15 | 16 | res := &DeleteAttachmentCommandData{ 17 | &CommandData{ 18 | Type: CommandDelete, 19 | ID: documentID, 20 | Name: name, 21 | ChangeVector: changeVector, 22 | }, 23 | } 24 | return res, nil 25 | } 26 | 27 | func (d *DeleteAttachmentCommandData) serialize(conventions *DocumentConventions) (interface{}, error) { 28 | res := d.baseJSON() 29 | res["Type"] = "AttachmentDELETE" 30 | res["Name"] = d.Name 31 | return res, nil 32 | } 33 | -------------------------------------------------------------------------------- /delete_command_data.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // DeleteCommandData represents data for delete command 4 | type DeleteCommandData struct { 5 | CommandData 6 | } 7 | 8 | // NewDeleteCommandData creates ICommandData for Delete command 9 | func NewDeleteCommandData(id string, changeVector string) ICommandData { 10 | var changeVectorPtr *string 11 | if changeVector != "" { 12 | changeVectorPtr = &changeVector 13 | } 14 | res := &DeleteCommandData{ 15 | CommandData{ 16 | Type: CommandDelete, 17 | ID: id, 18 | ChangeVector: changeVectorPtr, 19 | }, 20 | } 21 | return res 22 | } 23 | 24 | func (d *DeleteCommandData) serialize(conventions *DocumentConventions) (interface{}, error) { 25 | return d.baseJSON(), nil 26 | } 27 | -------------------------------------------------------------------------------- /delete_database_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // DeleteDatabaseResult represents result of Delete Database command 4 | type DeleteDatabaseResult struct { 5 | RaftCommandIndex int64 `json:"RaftCommandIndex"` 6 | PendingDeletes []string `json:"PendingDeletes"` 7 | } 8 | -------------------------------------------------------------------------------- /delete_document_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "net/http" 4 | 5 | var ( 6 | _ RavenCommand = &DeleteDocumentCommand{} 7 | ) 8 | 9 | type DeleteDocumentCommand struct { 10 | RavenCommandBase 11 | 12 | _id string 13 | _changeVector *string 14 | } 15 | 16 | func NewDeleteDocumentCommand(id string, changeVector *string) *DeleteDocumentCommand { 17 | cmd := &DeleteDocumentCommand{ 18 | RavenCommandBase: NewRavenCommandBase(), 19 | 20 | _id: id, 21 | _changeVector: changeVector, 22 | } 23 | cmd.ResponseType = RavenCommandResponseTypeEmpty 24 | return cmd 25 | } 26 | 27 | func (c *DeleteDocumentCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 28 | url := node.URL + "/databases/" + node.Database + "/docs?id=" + urlEncode(c._id) 29 | 30 | request, err := newHttpDelete(url, nil) 31 | if err != nil { 32 | return nil, err 33 | } 34 | addChangeVectorIfNotNull(c._changeVector, request) 35 | return request, nil 36 | 37 | } 38 | -------------------------------------------------------------------------------- /delete_subscription_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var ( 8 | _ RavenCommand = &DeleteSubscriptionCommand{} 9 | ) 10 | 11 | // DeleteSubscriptionCommand describes "delete subscription" command 12 | type DeleteSubscriptionCommand struct { 13 | RavenCommandBase 14 | 15 | name string 16 | } 17 | 18 | func newDeleteSubscriptionCommand(name string) *DeleteSubscriptionCommand { 19 | cmd := &DeleteSubscriptionCommand{ 20 | RavenCommandBase: NewRavenCommandBase(), 21 | 22 | name: name, 23 | } 24 | cmd.ResponseType = RavenCommandResponseTypeEmpty 25 | return cmd 26 | } 27 | 28 | func (c *DeleteSubscriptionCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 29 | url := node.URL + "/databases/" + node.Database + "/subscriptions?taskName=" + urlUtilsEscapeDataString(c.name) 30 | 31 | return newHttpDelete(url, nil) 32 | } 33 | -------------------------------------------------------------------------------- /distinct_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &distinctToken{} 6 | 7 | var ( 8 | distinctTokenInstance = &distinctToken{} 9 | ) 10 | 11 | type distinctToken struct { 12 | } 13 | 14 | func (t *distinctToken) writeTo(writer *strings.Builder) error { 15 | writer.WriteString("distinct") 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /dive-into-raven/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // empty file, exists to avoid output from go test 4 | -------------------------------------------------------------------------------- /dive-into-raven/pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ravendb/ravendb-go-client/2b87f37fe4272af1cd41bd0dfe586f747f24b92e/dive-into-raven/pic.png -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package ravendb implements a driver for RavenDB NOSQL document database. 3 | 4 | For more documentation see https://github.com/ravendb/ravendb-go-client/blob/master/readme.md 5 | */ 6 | package ravendb 7 | -------------------------------------------------------------------------------- /document_change.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // DocumentChange describes a change to the document. Can be used as DatabaseChange. 4 | type DocumentChange struct { 5 | Type DocumentChangeTypes 6 | ID string 7 | CollectionName string 8 | ChangeVector *string 9 | } 10 | 11 | func (c *DocumentChange) String() string { 12 | return c.Type + " on " + c.ID 13 | } 14 | -------------------------------------------------------------------------------- /document_change_types.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type DocumentChangeTypes = string 4 | 5 | const ( 6 | DocumentChangeNone = "None" 7 | DocumentChangePut = "Put" 8 | DocumentChangeDelete = "Delete" 9 | DocumentChangeConflict = "Conflict" 10 | DocumentChangeCommon = "Common" 11 | ) 12 | -------------------------------------------------------------------------------- /document_conflict_exception.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // DocumentConflictError represents document conflict error from the server 4 | type DocumentConflictError struct { 5 | ConflictError 6 | DocID string 7 | LargestEtag int64 8 | } 9 | 10 | func newDocumentConflictError(message string, docID string, etag int64) *DocumentConflictError { 11 | res := &DocumentConflictError{} 12 | res.ConflictError = *newConflictError("%s", message) 13 | res.DocID = docID 14 | res.LargestEtag = etag 15 | return res 16 | } 17 | 18 | func newDocumentConflictErrorFromMessage(message string) *DocumentConflictError { 19 | return newDocumentConflictError(message, "", 0) 20 | } 21 | 22 | func newDocumentConflictErrorFromJSON(js string) error { 23 | var jsonNode map[string]interface{} 24 | err := jsonUnmarshal([]byte(js), &jsonNode) 25 | if err != nil { 26 | return newBadResponseError("Unable to parse server response: %s", err) 27 | } 28 | docID, _ := jsonGetAsText(jsonNode, "DocId") 29 | message, _ := jsonGetAsText(jsonNode, "Message") 30 | largestEtag, _ := jsonGetAsInt64(jsonNode, "LargestEtag") 31 | 32 | return newDocumentConflictError(message, docID, largestEtag) 33 | } 34 | -------------------------------------------------------------------------------- /document_conventions_test.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | type User struct { 11 | ID string 12 | Name string 13 | } 14 | 15 | func TestDefaultGetCollectionName(t *testing.T) { 16 | name := getCollectionNameForTypeOrEntity(&User{}) 17 | assert.Equal(t, "Users", name) 18 | name = getCollectionNameForTypeOrEntity(reflect.TypeOf(&User{})) 19 | assert.Equal(t, "Users", name) 20 | } 21 | -------------------------------------------------------------------------------- /document_query_helper.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | func documentQueryHelperAddSpaceIfNeeded(previousToken queryToken, currentToken queryToken, writer *strings.Builder) { 6 | if previousToken == nil { 7 | return 8 | } 9 | 10 | skip := false 11 | if _, ok := previousToken.(*openSubclauseToken); ok { 12 | skip = true 13 | } else if _, ok := currentToken.(*closeSubclauseToken); ok { 14 | skip = true 15 | } else if currentToken == intersectMarkerTokenInstance { 16 | skip = true 17 | } 18 | if skip { 19 | return 20 | } 21 | writer.WriteString(" ") 22 | } 23 | -------------------------------------------------------------------------------- /documents_by_id.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | // TODO: change to an alias: 6 | // type documentsByID map[string]*documentInfo 7 | 8 | type documentsByID struct { 9 | inner map[string]*documentInfo 10 | } 11 | 12 | func newDocumentsByID() *documentsByID { 13 | return &documentsByID{ 14 | inner: map[string]*documentInfo{}, 15 | } 16 | } 17 | 18 | func (d *documentsByID) getValue(id string) *documentInfo { 19 | id = strings.ToLower(id) 20 | return d.inner[id] 21 | } 22 | 23 | func (d *documentsByID) add(info *documentInfo) { 24 | id := strings.ToLower(info.id) 25 | 26 | if _, ok := d.inner[id]; ok { 27 | return 28 | } 29 | 30 | d.inner[id] = info 31 | } 32 | 33 | func (d *documentsByID) remove(id string) bool { 34 | id = strings.ToLower(id) 35 | if _, ok := d.inner[id]; !ok { 36 | return false 37 | } 38 | delete(d.inner, id) 39 | return true 40 | } 41 | -------------------------------------------------------------------------------- /drop_subscription_connection_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var ( 8 | _ RavenCommand = &DropSubscriptionConnectionCommand{} 9 | ) 10 | 11 | // DropSubscriptionConnectionCommand describes "drop subscription" command 12 | type DropSubscriptionConnectionCommand struct { 13 | RavenCommandBase 14 | 15 | name string 16 | } 17 | 18 | func newDropSubscriptionConnectionCommand(name string) *DropSubscriptionConnectionCommand { 19 | cmd := &DropSubscriptionConnectionCommand{ 20 | RavenCommandBase: NewRavenCommandBase(), 21 | 22 | name: name, 23 | } 24 | cmd.ResponseType = RavenCommandResponseTypeEmpty 25 | return cmd 26 | } 27 | 28 | func (c *DropSubscriptionConnectionCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 29 | url := node.URL + "/databases/" + node.Database + "/subscriptions/drop?name=" + urlUtilsEscapeDataString(c.name) 30 | 31 | return NewHttpPost(url, nil) 32 | } 33 | -------------------------------------------------------------------------------- /duration_serialization_test.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestCanSerializeDuration(t *testing.T) { 11 | tests := []struct { 12 | d time.Duration 13 | exp string 14 | }{ 15 | {time.Hour*24*5 + time.Hour*2, `"5.02:00:00"`}, 16 | {time.Millisecond * 5, `"00:00:00.0050000"`}, 17 | } 18 | for _, test := range tests { 19 | d2 := Duration(test.d) 20 | d, err := jsonMarshal(d2) 21 | assert.NoError(t, err) 22 | got := string(d) 23 | assert.Equal(t, test.exp, got) 24 | } 25 | } 26 | 27 | func TestCanDeserializeDuration(t *testing.T) { 28 | tests := []struct { 29 | s string 30 | exp time.Duration 31 | }{ 32 | {`"5.02:00:00"`, time.Hour*24*5 + time.Hour*2}, 33 | {`"00:00:00.0050000"`, time.Millisecond * 5}, 34 | {`"00:00:00.005000"`, time.Millisecond * 5}, 35 | {`"00:00:00.00500"`, time.Millisecond * 5}, 36 | {`"00:00:00.1"`, time.Millisecond * 100}, 37 | } 38 | for _, test := range tests { 39 | var got Duration 40 | d := []byte(test.s) 41 | err := jsonUnmarshal(d, &got) 42 | assert.NoError(t, err) 43 | exp := Duration(test.exp) 44 | assert.Equal(t, exp, got) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dynamic_spatial_field.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // DynamicSpatialField is an interface for implementing name of the field to 4 | // be queried 5 | type DynamicSpatialField interface { 6 | // ToField returns a name of the field used in queries 7 | ToField(ensureValidFieldName func(string, bool) (string, error)) (string, error) 8 | } 9 | -------------------------------------------------------------------------------- /errors_test.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "errors" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | ) 8 | 9 | func TestErrorWrapping(t *testing.T) { 10 | { 11 | origErr := errors.New("an error") 12 | err := newIllegalStateError("n: %d", 5, origErr) 13 | assert.Equal(t, err.Error(), "n: 5") 14 | assert.Equal(t, origErr, err.wrapped) 15 | } 16 | 17 | { 18 | err := newIllegalArgumentError("just text") 19 | assert.Equal(t, err.Error(), "just text") 20 | assert.Nil(t, err.wrapped) 21 | } 22 | 23 | { 24 | err := newIllegalArgumentError("%d, %s", 3, "hey") 25 | assert.Equal(t, err.Error(), "3, hey") 26 | assert.Nil(t, err.wrapped) 27 | } 28 | 29 | { 30 | err := newSubscriptionDoesNotExistError("") 31 | assert.True(t, isRavenError(err)) 32 | } 33 | 34 | { 35 | err := makeRavenErrorFromName("IndexCompilationException", "message") 36 | _, ok := err.(*IndexCompilationError) 37 | assert.True(t, ok) 38 | assert.Equal(t, "message", err.Error()) 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /event_handler.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type EventHandler interface { 4 | handle(sender interface{}, event interface{}) 5 | } 6 | -------------------------------------------------------------------------------- /examples/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // empty file, exists to avoid output from go test 4 | -------------------------------------------------------------------------------- /examples/pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ravendb/ravendb-go-client/2b87f37fe4272af1cd41bd0dfe586f747f24b92e/examples/pic.png -------------------------------------------------------------------------------- /exceptions_utils.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | func acceptError(action func() error) error { 4 | err := action() 5 | if err != nil { 6 | return unwrapError(err) 7 | } 8 | return nil 9 | } 10 | 11 | func unwrapError(e error) error { 12 | 13 | return e 14 | /* 15 | TODO: implement me 16 | if (e instanceof ExecutionException) { 17 | ExecutionException computationException = (ExecutionException) e; 18 | return unwrapError(computationException.getCause()); 19 | } 20 | 21 | if (e instanceof RuntimeError) { 22 | return (RuntimeError)e; 23 | } 24 | 25 | return new RuntimeError(e); 26 | */ 27 | } 28 | -------------------------------------------------------------------------------- /external_replication.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // ExternalReplication describes external replication 4 | type ExternalReplication struct { 5 | ReplicationNode 6 | TaskID int64 `json:"TaskId"` 7 | Name string `json:"Name"` 8 | ConnectionStringName string `json:"ConnectionStringName"` 9 | MentorName string `json:"MentorName"` 10 | } 11 | 12 | // NewExternalReplication creates ExternalReplication 13 | func NewExternalReplication(database string, connectionStringName string) *ExternalReplication { 14 | return &ExternalReplication{ 15 | ReplicationNode: ReplicationNode{ 16 | Database: database, 17 | }, 18 | ConnectionStringName: connectionStringName, 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /facet.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var _ FacetBase = &Facet{} 4 | 5 | // Facet describes a search facet 6 | type Facet struct { 7 | FacetBaseCommon 8 | 9 | FieldName string `json:"FieldName"` 10 | } 11 | 12 | // NewFacet returns a new Facet 13 | func NewFacet() *Facet { 14 | return &Facet{ 15 | FacetBaseCommon: NewFacetBaseCommon(), 16 | } 17 | } 18 | 19 | // ToFacetToken returns token for this facet 20 | func (f *Facet) ToFacetToken(addQueryParameter func(interface{}) string) (*facetToken, error) { 21 | return createFacetTokenWithFacet(f, addQueryParameter), nil 22 | } 23 | -------------------------------------------------------------------------------- /facet_aggregation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type FacetAggregation = string 4 | 5 | const ( 6 | FacetAggregationNone = "None" 7 | FacetAggregationMax = "Max" 8 | FacetAggregationMin = "Min" 9 | FacetAggregationAverage = "Average" 10 | FacetAggregationSum = "Sum" 11 | ) 12 | -------------------------------------------------------------------------------- /facet_base.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type FacetBase interface { 4 | // those are supplied by each type 5 | ToFacetToken(addQueryParameter func(interface{}) string) (*facetToken, error) 6 | 7 | // those are inherited from FacetBaseCommon 8 | SetDisplayFieldName(string) 9 | GetOptions() *FacetOptions 10 | SetOptions(*FacetOptions) 11 | GetAggregations() map[FacetAggregation]string 12 | } 13 | 14 | type FacetBaseCommon struct { 15 | DisplayFieldName string `json:"DisplayFieldName,omitempty"` 16 | Options *FacetOptions `json:"Options"` 17 | Aggregations map[FacetAggregation]string `json:"Aggregations"` 18 | } 19 | 20 | func NewFacetBaseCommon() FacetBaseCommon { 21 | return FacetBaseCommon{ 22 | Aggregations: make(map[FacetAggregation]string), 23 | } 24 | } 25 | 26 | func (f *FacetBaseCommon) SetDisplayFieldName(displayFieldName string) { 27 | f.DisplayFieldName = displayFieldName 28 | } 29 | 30 | func (f *FacetBaseCommon) GetOptions() *FacetOptions { 31 | return f.Options 32 | } 33 | 34 | func (f *FacetBaseCommon) SetOptions(options *FacetOptions) { 35 | f.Options = options 36 | } 37 | 38 | func (f *FacetBaseCommon) GetAggregations() map[FacetAggregation]string { 39 | return f.Aggregations 40 | } 41 | -------------------------------------------------------------------------------- /facet_options.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "math" 5 | ) 6 | 7 | var ( 8 | // DefaultFacetOptions are default facet options 9 | DefaultFacetOptions = &FacetOptions{} 10 | ) 11 | 12 | // FacetOptions describes options for facet 13 | type FacetOptions struct { 14 | TermSortMode FacetTermSortMode `json:"TermSortMode"` 15 | IncludeRemainingTerms bool `json:"IncludeRemainingTerms"` 16 | Start int `json:"Start"` 17 | PageSize int `json:"PageSize"` 18 | } 19 | 20 | // NewFacetOptions returns new FacetOptions 21 | func NewFacetOptions() *FacetOptions { 22 | return &FacetOptions{ 23 | PageSize: int(math.MaxInt32), 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /facet_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // FacetResults represents results of faceted search 4 | type FacetResult struct { 5 | Name string 6 | Values []*FacetValue 7 | RemainingTerms []string 8 | RemainingTermsCount int 9 | RemainingHits int 10 | } 11 | -------------------------------------------------------------------------------- /facet_setup.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // FacetSetup describes new facet setup 4 | type FacetSetup struct { 5 | ID string 6 | Facets []*Facet `json:"Facets,omitempty"` 7 | // Note: omitempty here is important. If we Send 'null', 8 | // (as opposed to Java's '[]') the server will error out 9 | // when parsing query referencing this setup 10 | RangeFacets []*RangeFacet `json:"RangeFacets,omitempty"` 11 | } 12 | -------------------------------------------------------------------------------- /facet_term_sort_mode.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // FacetTermSortMode describes sort mode for a facet 4 | type FacetTermSortMode = string 5 | 6 | const ( 7 | FacetTermSortModeValueAsc = "ValueAsc" 8 | FacetTermSortModeValueDesc = "ValueDesc" 9 | FacetTermSortModeCountAsc = "CountAsc" 10 | FacetTermSortModeCountDesc = "CountDesc" 11 | ) 12 | -------------------------------------------------------------------------------- /facet_value.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | type FacetValue struct { 10 | Range string 11 | Count int 12 | Sum *float64 13 | Max *float64 14 | Min *float64 15 | Average *float64 16 | } 17 | 18 | func (v *FacetValue) SetSum(sum float64) { 19 | v.Sum = &sum 20 | } 21 | 22 | func (v *FacetValue) SetMax(max float64) { 23 | v.Max = &max 24 | } 25 | 26 | func (v *FacetValue) SetMin(min float64) { 27 | v.Min = &min 28 | } 29 | 30 | func (v *FacetValue) SetAverage(average float64) { 31 | v.Average = &average 32 | } 33 | 34 | func (v *FacetValue) String() string { 35 | msg := v.Range + " - Count: " + strconv.Itoa(v.Count) + ", " 36 | if v.Sum != nil { 37 | msg += fmt.Sprintf("Sum: %f,", *v.Sum) 38 | } 39 | if v.Max != nil { 40 | msg += fmt.Sprintf("Max: %f,", *v.Max) 41 | } 42 | if v.Min != nil { 43 | msg += fmt.Sprintf("Min: %f,", *v.Min) 44 | } 45 | if v.Average != nil { 46 | msg += fmt.Sprintf("Average: %f,", *v.Average) 47 | } 48 | 49 | // TODO: this makes no sense but is in Java code 50 | return strings.TrimSuffix(msg, ";") 51 | } 52 | -------------------------------------------------------------------------------- /field_indexing.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type FieldIndexing string 4 | 5 | const ( 6 | FieldIndexingNo = "No" 7 | FieldIndexingSearch = "Search" 8 | FieldIndexingExact = "Exact" 9 | FieldIndexingDefault = "Default" 10 | ) 11 | -------------------------------------------------------------------------------- /field_storage.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type FieldStorage = string 4 | 5 | const ( 6 | FieldStorageYes = "Yes" 7 | FieldStorageNo = "No" 8 | ) 9 | -------------------------------------------------------------------------------- /field_term_vector.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type FieldTermVector = string 4 | 5 | const ( 6 | FieldTermVectorNo = "No" 7 | FieldTermVectorYes = "Yes" 8 | FieldTermVectorWithPositions = "WithPositions" 9 | FieldTermVectorWithOffsets = "WithOffsets" 10 | FieldTermVectorWithPositionsAndOffsets = "WithPositionsAndOffsets" 11 | ) 12 | -------------------------------------------------------------------------------- /for_tests.go: -------------------------------------------------------------------------------- 1 | // +build for_tests 2 | 3 | package ravendb 4 | 5 | // this file exposes functionality that is only meant to be used 6 | // in tests. This code is only compiled when "-tags for_tests" 7 | // option is used 8 | 9 | func (c *DocumentConventions) GetCollectionName(entityOrType interface{}) string { 10 | return c.getCollectionName(entityOrType) 11 | } 12 | 13 | func (s *DocumentSession) ForTestsSaveChangesGetCommands() ([]ICommandData, error) { 14 | result, err := s.prepareForSaveChanges() 15 | if err != nil { 16 | return nil, err 17 | } 18 | res := append(result.sessionCommands, result.deferredCommands...) 19 | return res, nil 20 | } 21 | -------------------------------------------------------------------------------- /generic_query_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // GenericQueryResult represents query results 4 | type GenericQueryResult struct { 5 | queryResultBase 6 | TotalResults int `json:"TotalResults"` 7 | SkippedResults int `json:"SkippedResults"` 8 | //TBD 4.1 map[string]map[string]List>> highlightings 9 | DurationInMs int64 `json:"DurationInMs"` 10 | ScoreExplanations map[string]string `json:"ScoreExplanation"` 11 | TimingsInMs map[string]float64 `json:"TimingsInMs"` 12 | ResultSize int64 `json:"ResultSize"` 13 | } 14 | -------------------------------------------------------------------------------- /generic_range_facet.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // GenericRangeFacet represents generic range facet 4 | type GenericRangeFacet struct { 5 | FacetBaseCommon 6 | parent FacetBase 7 | Ranges []*RangeBuilder 8 | } 9 | 10 | // NewGenericRangeFacet returns new GenericRangeFacet 11 | // parent is optional, can be nil 12 | func NewGenericRangeFacet(parent FacetBase) *GenericRangeFacet { 13 | return &GenericRangeFacet{ 14 | FacetBaseCommon: NewFacetBaseCommon(), 15 | parent: parent, 16 | } 17 | } 18 | 19 | // GenericRangeFacetParse parses generic range facet 20 | func genericRangeFacetParse(rangeBuilder *RangeBuilder, addQueryParameter func(interface{}) string) (string, error) { 21 | return rangeBuilder.GetStringRepresentation(addQueryParameter) 22 | } 23 | 24 | // ToFacetToken returns facetToken from GenericRangeFacet 25 | func (f *GenericRangeFacet) ToFacetToken(addQueryParameter func(interface{}) string) (*facetToken, error) { 26 | if f.parent != nil { 27 | return f.parent.ToFacetToken(addQueryParameter) 28 | } 29 | 30 | return createFacetTokenWithGenericRangeFacet(f, addQueryParameter) 31 | } 32 | 33 | func (f *GenericRangeFacet) addRange(rng *RangeBuilder) { 34 | f.Ranges = append(f.Ranges, rng) 35 | } 36 | -------------------------------------------------------------------------------- /get_conflicts_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var ( 8 | _ RavenCommand = &GetConflictsCommand{} 9 | ) 10 | 11 | type GetConflictsCommand struct { 12 | RavenCommandBase 13 | 14 | _id string 15 | 16 | Result *GetConflictsResult 17 | } 18 | 19 | func NewGetConflictsCommand(id string) *GetConflictsCommand { 20 | panicIf(id == "", "id cannot be empty") 21 | cmd := &GetConflictsCommand{ 22 | RavenCommandBase: NewRavenCommandBase(), 23 | 24 | _id: id, 25 | } 26 | cmd.IsReadRequest = true 27 | 28 | return cmd 29 | } 30 | 31 | func (c *GetConflictsCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 32 | url := node.URL + "/databases/" + node.Database + "/replication/conflicts?docId=" + c._id 33 | 34 | return newHttpGet(url) 35 | } 36 | 37 | func (c *GetConflictsCommand) SetResponse(response []byte, fromCache bool) error { 38 | if len(response) == 0 { 39 | return throwInvalidResponse() 40 | } 41 | return jsonUnmarshal(response, &c.Result) 42 | } 43 | -------------------------------------------------------------------------------- /get_conflicts_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // GetConflictsResult represents result of "get conflict" command 4 | type GetConflictsResult struct { 5 | ID string `json:"Id"` 6 | Results []*Conflict `json:"Results"` 7 | LargestEtag int64 `json:"LargestEtag"` 8 | } 9 | 10 | // Conflict represents conflict 11 | type Conflict struct { 12 | LastModified Time `json:"LastModified"` 13 | ChangeVector string `json:"ChangeVector"` 14 | Doc map[string]interface{} `json:"Doc"` 15 | } 16 | -------------------------------------------------------------------------------- /get_database_topology_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | "strings" 6 | ) 7 | 8 | var ( 9 | _ RavenCommand = &GetDatabaseTopologyCommand{} 10 | ) 11 | 12 | type GetDatabaseTopologyCommand struct { 13 | RavenCommandBase 14 | 15 | Result *Topology 16 | } 17 | 18 | func NewGetDatabaseTopologyCommand() *GetDatabaseTopologyCommand { 19 | cmd := &GetDatabaseTopologyCommand{ 20 | RavenCommandBase: NewRavenCommandBase(), 21 | } 22 | cmd.IsReadRequest = true 23 | return cmd 24 | } 25 | 26 | func (c *GetDatabaseTopologyCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 27 | url := node.URL + "/topology?name=" + node.Database 28 | if strings.Contains(strings.ToLower(node.URL), ".fiddler") { 29 | // we want to keep the '.fiddler' stuff there so we'll keep tracking request 30 | // so we are going to ask the server to respect it 31 | url += "&localUrl=" + urlUtilsEscapeDataString(node.URL) 32 | } 33 | return newHttpGet(url) 34 | } 35 | 36 | func (c *GetDatabaseTopologyCommand) SetResponse(response []byte, fromCache bool) error { 37 | return jsonUnmarshal(response, &c.Result) 38 | } 39 | -------------------------------------------------------------------------------- /get_documents_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // GetDocumentsResult is a result of GetDocument command 4 | type GetDocumentsResult struct { 5 | Includes map[string]interface{} `json:"Includes"` 6 | Results []map[string]interface{} `json:"Results"` 7 | NextPageStart int `json:"NextPageStart"` 8 | } 9 | -------------------------------------------------------------------------------- /get_identities_operation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var ( 8 | _ IMaintenanceOperation = &GetIdentitiesOperation{} 9 | ) 10 | 11 | type GetIdentitiesOperation struct { 12 | Command *GetIdentitiesCommand 13 | } 14 | 15 | func NewGetIdentitiesOperation() *GetIdentitiesOperation { 16 | return &GetIdentitiesOperation{} 17 | } 18 | 19 | func (o *GetIdentitiesOperation) GetCommand(conventions *DocumentConventions) (RavenCommand, error) { 20 | o.Command = NewGetIdentitiesCommand() 21 | return o.Command, nil 22 | } 23 | 24 | type GetIdentitiesCommand struct { 25 | RavenCommandBase 26 | 27 | Result map[string]int 28 | } 29 | 30 | func NewGetIdentitiesCommand() *GetIdentitiesCommand { 31 | cmd := &GetIdentitiesCommand{ 32 | RavenCommandBase: NewRavenCommandBase(), 33 | } 34 | cmd.IsReadRequest = true 35 | return cmd 36 | } 37 | 38 | func (c *GetIdentitiesCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 39 | url := node.URL + "/databases/" + node.Database + "/debug/identities" 40 | 41 | return newHttpGet(url) 42 | 43 | } 44 | 45 | func (c *GetIdentitiesCommand) SetResponse(response []byte, fromCache bool) error { 46 | return jsonUnmarshal(response, &c.Result) 47 | } 48 | -------------------------------------------------------------------------------- /get_indexing_status_operation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var _ IMaintenanceOperation = &GetIndexingStatusOperation{} 8 | 9 | type GetIndexingStatusOperation struct { 10 | Command *GetIndexingStatusCommand 11 | } 12 | 13 | func NewGetIndexingStatusOperation() *GetIndexingStatusOperation { 14 | return &GetIndexingStatusOperation{} 15 | } 16 | 17 | func (o *GetIndexingStatusOperation) GetCommand(conventions *DocumentConventions) (RavenCommand, error) { 18 | o.Command = NewGetIndexingStatusCommand() 19 | return o.Command, nil 20 | } 21 | 22 | var ( 23 | _ RavenCommand = &GetIndexingStatusCommand{} 24 | ) 25 | 26 | type GetIndexingStatusCommand struct { 27 | RavenCommandBase 28 | 29 | Result *IndexingStatus 30 | } 31 | 32 | func NewGetIndexingStatusCommand() *GetIndexingStatusCommand { 33 | res := &GetIndexingStatusCommand{ 34 | RavenCommandBase: NewRavenCommandBase(), 35 | } 36 | res.IsReadRequest = true 37 | return res 38 | } 39 | 40 | func (c *GetIndexingStatusCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 41 | url := node.URL + "/databases/" + node.Database + "/indexes/status" 42 | 43 | return newHttpGet(url) 44 | } 45 | 46 | func (c *GetIndexingStatusCommand) SetResponse(response []byte, fromCache bool) error { 47 | if response == nil { 48 | return throwInvalidResponse() 49 | } 50 | 51 | return jsonUnmarshal(response, &c.Result) 52 | } 53 | -------------------------------------------------------------------------------- /get_next_operation_id_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var ( 8 | _ RavenCommand = &GetNextOperationIDCommand{} 9 | ) 10 | 11 | type _GetNextOperationIDCommandResponse struct { 12 | ID int64 `json:"Id"` 13 | } 14 | 15 | // GetNextOperationIDCommand represents command for getting next 16 | // id from the server 17 | type GetNextOperationIDCommand struct { 18 | RavenCommandBase 19 | 20 | Result int64 21 | } 22 | 23 | // NewGetNextOperationIDCommand returns GetNextOperationIDCommand 24 | func NewGetNextOperationIDCommand() *GetNextOperationIDCommand { 25 | cmd := &GetNextOperationIDCommand{ 26 | RavenCommandBase: NewRavenCommandBase(), 27 | } 28 | return cmd 29 | } 30 | 31 | func (c *GetNextOperationIDCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 32 | url := node.URL + "/databases/" + node.Database + "/operations/next-operation-id" 33 | return newHttpGet(url) 34 | } 35 | 36 | func (c *GetNextOperationIDCommand) SetResponse(response []byte, fromCache bool) error { 37 | var res _GetNextOperationIDCommandResponse 38 | err := jsonUnmarshal(response, &res) 39 | if err != nil { 40 | return err 41 | } 42 | c.Result = res.ID 43 | return nil 44 | } 45 | -------------------------------------------------------------------------------- /get_operation_state_operation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | type GetOperationStateOperation struct { 8 | id int64 9 | } 10 | 11 | func (o *GetOperationStateOperation) GetCommand(conventions *DocumentConventions) *GetOperationStateCommand { 12 | return NewGetOperationStateCommand(getDefaultConventions(), o.id) 13 | } 14 | 15 | type GetOperationStateCommand struct { 16 | RavenCommandBase 17 | 18 | conventions *DocumentConventions 19 | id int64 20 | 21 | Result map[string]interface{} 22 | } 23 | 24 | func NewGetOperationStateCommand(conventions *DocumentConventions, id int64) *GetOperationStateCommand { 25 | cmd := &GetOperationStateCommand{ 26 | RavenCommandBase: NewRavenCommandBase(), 27 | 28 | conventions: conventions, 29 | id: id, 30 | } 31 | cmd.IsReadRequest = true 32 | 33 | return cmd 34 | } 35 | 36 | func (c *GetOperationStateCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 37 | url := node.URL + "/databases/" + node.Database + "/operations/state?id=" + i64toa(c.id) 38 | return newHttpGet(url) 39 | } 40 | 41 | func (c *GetOperationStateCommand) SetResponse(response []byte, fromCache bool) error { 42 | if len(response) == 0 { 43 | return nil 44 | } 45 | 46 | return jsonUnmarshal(response, &c.Result) 47 | } 48 | -------------------------------------------------------------------------------- /get_request.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | // getRequest represents get request 6 | type getRequest struct { 7 | url string 8 | headers map[string]string 9 | query string 10 | method string 11 | content IContent 12 | } 13 | 14 | func (r *getRequest) getUrlAndQuery() string { 15 | if r.query == "" { 16 | return r.url 17 | } 18 | 19 | if strings.HasPrefix(r.query, "?") { 20 | return r.url + r.query 21 | } 22 | 23 | return r.url + "?" + r.query 24 | } 25 | 26 | type IContent interface { 27 | writeContent() map[string]interface{} 28 | } 29 | -------------------------------------------------------------------------------- /get_response.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "net/http" 4 | 5 | // GetResponse represents result of get request 6 | type GetResponse struct { 7 | Result []byte 8 | Headers map[string]string 9 | StatusCode int 10 | IsForceRetry bool 11 | } 12 | 13 | func (r *GetResponse) requestHasErrors() bool { 14 | switch r.StatusCode { 15 | case 0, 16 | http.StatusOK, 17 | http.StatusCreated, 18 | http.StatusNoContent, 19 | http.StatusNotModified, 20 | http.StatusNonAuthoritativeInfo, 21 | http.StatusNotFound: 22 | return false 23 | default: 24 | return true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /get_revisions_bin_entry_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | "strconv" 6 | ) 7 | 8 | var ( 9 | _ RavenCommand = &GetRevisionsBinEntryCommand{} 10 | ) 11 | 12 | type GetRevisionsBinEntryCommand struct { 13 | RavenCommandBase 14 | 15 | etag int64 16 | pageSize int 17 | 18 | Result *JSONArrayResult 19 | } 20 | 21 | func NewGetRevisionsBinEntryCommand(etag int64, pageSize int) *GetRevisionsBinEntryCommand { 22 | cmd := &GetRevisionsBinEntryCommand{ 23 | RavenCommandBase: NewRavenCommandBase(), 24 | 25 | etag: etag, 26 | pageSize: pageSize, 27 | } 28 | cmd.IsReadRequest = true 29 | return cmd 30 | } 31 | 32 | func (c *GetRevisionsBinEntryCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 33 | etagStr := i64toa(c.etag) 34 | url := node.URL + "/databases/" + node.Database + "/revisions/bin?etag=" + etagStr 35 | 36 | if c.pageSize > 0 { 37 | url += "&pageSize=" + strconv.Itoa(c.pageSize) 38 | } 39 | 40 | return newHttpGet(url) 41 | } 42 | 43 | func (c *GetRevisionsBinEntryCommand) SetResponse(response []byte, fromCache bool) error { 44 | if len(response) == 0 { 45 | return throwInvalidResponse() 46 | } 47 | 48 | return jsonUnmarshal(response, &c.Result) 49 | } 50 | -------------------------------------------------------------------------------- /get_server_wide_operation_state_operation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | type GetServerWideOperationStateOperation struct { 8 | id int64 9 | } 10 | 11 | func (o *GetServerWideOperationStateOperation) GetCommand(conventions *DocumentConventions) *GetServerWideOperationStateCommand { 12 | return NewGetServerWideOperationStateCommand(getDefaultConventions(), o.id) 13 | } 14 | 15 | type GetServerWideOperationStateCommand struct { 16 | RavenCommandBase 17 | 18 | conventions *DocumentConventions 19 | id int64 20 | 21 | Result map[string]interface{} 22 | } 23 | 24 | func NewGetServerWideOperationStateCommand(conventions *DocumentConventions, id int64) *GetServerWideOperationStateCommand { 25 | cmd := &GetServerWideOperationStateCommand{ 26 | RavenCommandBase: NewRavenCommandBase(), 27 | 28 | conventions: conventions, 29 | id: id, 30 | } 31 | cmd.IsReadRequest = true 32 | 33 | return cmd 34 | } 35 | 36 | func (c *GetServerWideOperationStateCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 37 | url := node.URL + "/operations/state?id=" + i64toa(c.id) 38 | return newHttpGet(url) 39 | } 40 | 41 | func (c *GetServerWideOperationStateCommand) SetResponse(response []byte, fromCache bool) error { 42 | if len(response) == 0 { 43 | return nil 44 | } 45 | 46 | return jsonUnmarshal(response, &c.Result) 47 | } 48 | -------------------------------------------------------------------------------- /get_subscription_state_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var ( 8 | _ RavenCommand = &GetSubscriptionStateCommand{} 9 | ) 10 | 11 | // GetSubscriptionStateCommand describes "get subscription state" command 12 | type GetSubscriptionStateCommand struct { 13 | RavenCommandBase 14 | 15 | subscriptionName string 16 | 17 | Result *SubscriptionState 18 | } 19 | 20 | func newGetSubscriptionStateCommand(subscriptionName string) *GetSubscriptionStateCommand { 21 | cmd := &GetSubscriptionStateCommand{ 22 | RavenCommandBase: NewRavenCommandBase(), 23 | 24 | subscriptionName: subscriptionName, 25 | } 26 | cmd.IsReadRequest = true 27 | return cmd 28 | } 29 | 30 | func (c *GetSubscriptionStateCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 31 | url := node.URL + "/databases/" + node.Database + "/subscriptions/state?name=" + urlUtilsEscapeDataString(c.subscriptionName) 32 | 33 | return newHttpGet(url) 34 | } 35 | 36 | func (c *GetSubscriptionStateCommand) SetResponse(response []byte, fromCache bool) error { 37 | if len(response) == 0 { 38 | return throwInvalidResponse() 39 | } 40 | return jsonUnmarshal(response, &c.Result) 41 | } 42 | -------------------------------------------------------------------------------- /get_subscriptions_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | "strconv" 6 | ) 7 | 8 | var ( 9 | _ RavenCommand = &GetSubscriptionsCommand{} 10 | ) 11 | 12 | // GetSubscriptionsCommand describes "delete subscription" command 13 | type GetSubscriptionsCommand struct { 14 | RavenCommandBase 15 | 16 | start int 17 | pageSize int 18 | 19 | Result []*SubscriptionState 20 | } 21 | 22 | func newGetSubscriptionsCommand(start int, pageSize int) *GetSubscriptionsCommand { 23 | cmd := &GetSubscriptionsCommand{ 24 | RavenCommandBase: NewRavenCommandBase(), 25 | 26 | start: start, 27 | pageSize: pageSize, 28 | } 29 | cmd.IsReadRequest = true 30 | return cmd 31 | } 32 | 33 | func (c *GetSubscriptionsCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 34 | url := node.URL + "/databases/" + node.Database + "/subscriptions?start=" + strconv.Itoa(c.start) + "&pageSize=" + strconv.Itoa(c.pageSize) 35 | 36 | return newHttpGet(url) 37 | } 38 | 39 | func (c *GetSubscriptionsCommand) SetResponse(response []byte, fromCache bool) error { 40 | if len(response) == 0 { 41 | return nil 42 | } 43 | var res *GetSubscriptionsResult 44 | if err := jsonUnmarshal(response, &res); err != nil { 45 | return err 46 | } 47 | c.Result = res.Results 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /get_subscriptions_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // GetSubscriptionsResult represents result of "get subscriptions" 4 | type GetSubscriptionsResult struct { 5 | Results []*SubscriptionState `json:"Results"` 6 | } 7 | -------------------------------------------------------------------------------- /get_tcp_info_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var ( 8 | _ RavenCommand = &GetTcpInfoCommand{} 9 | ) 10 | 11 | // GetTcpInfoCommand describes "get tcp info" command 12 | type GetTcpInfoCommand struct { 13 | RavenCommandBase 14 | 15 | tag string 16 | dbName string 17 | requestedNode *ServerNode 18 | 19 | Result *TcpConnectionInfo 20 | } 21 | 22 | // NewGetTcpInfoCommand returns new GetTcpInfoCommand 23 | // dbName is optional 24 | func NewGetTcpInfoCommand(tag, dbName string) *GetTcpInfoCommand { 25 | cmd := &GetTcpInfoCommand{ 26 | RavenCommandBase: NewRavenCommandBase(), 27 | 28 | tag: tag, 29 | dbName: dbName, 30 | } 31 | cmd.IsReadRequest = true 32 | return cmd 33 | } 34 | 35 | func (c *GetTcpInfoCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 36 | url := "" 37 | if c.dbName == "" { 38 | url = node.URL + "/info/tcp?tcp=" + c.tag 39 | } else { 40 | url = node.URL + "/databases/" + c.dbName + "/info/tcp?tag=" + c.tag 41 | } 42 | c.requestedNode = node 43 | return newHttpGet(url) 44 | } 45 | 46 | func (c *GetTcpInfoCommand) SetResponse(response []byte, fromCache bool) error { 47 | if len(response) == 0 { 48 | return throwInvalidResponse() 49 | } 50 | 51 | return jsonUnmarshal(response, &c.Result) 52 | } 53 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ravendb/ravendb-go-client 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/davecgh/go-spew v1.1.1 // indirect 7 | github.com/google/uuid v1.3.0 8 | github.com/gorilla/websocket v1.4.1 9 | github.com/hashicorp/go-multierror v1.1.1 10 | github.com/kjk/httplogproxy v0.0.0-20190214011443-6743ea9a2d3d 11 | github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 12 | github.com/stretchr/testify v1.3.0 13 | ) 14 | -------------------------------------------------------------------------------- /group_by.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // GroupBy represents arguments to "group by" query 4 | type GroupBy struct { 5 | Field string 6 | Method GroupByMethod 7 | } 8 | 9 | // NewGroupByField returns new GroupBy for a field 10 | func NewGroupByField(fieldName string) *GroupBy { 11 | return &GroupBy{ 12 | Field: fieldName, 13 | Method: GroupByMethodNone, 14 | } 15 | } 16 | 17 | // NewGroupByField returns new GroupBy for an array 18 | func NewGroupByArray(fieldName string) *GroupBy { 19 | return &GroupBy{ 20 | Field: fieldName, 21 | Method: GroupByMethodArray, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /group_by_count_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &groupByCountToken{} 6 | 7 | type groupByCountToken struct { 8 | fieldName string 9 | } 10 | 11 | func (t *groupByCountToken) writeTo(writer *strings.Builder) error { 12 | 13 | writer.WriteString("count()") 14 | 15 | if t.fieldName == "" { 16 | return nil 17 | } 18 | 19 | writer.WriteString(" as ") 20 | writer.WriteString(t.fieldName) 21 | return nil 22 | } 23 | -------------------------------------------------------------------------------- /group_by_field.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // GroupByField represents a field by which to group in a query 4 | type GroupByField struct { 5 | FieldName string 6 | ProjectedName string 7 | } 8 | -------------------------------------------------------------------------------- /group_by_key_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &groupByKeyToken{} 6 | 7 | type groupByKeyToken struct { 8 | fieldName string 9 | projectedName string 10 | } 11 | 12 | func newGroupByKeyToken(fieldName string, projectedName string) *groupByKeyToken { 13 | return &groupByKeyToken{ 14 | fieldName: fieldName, 15 | projectedName: projectedName, 16 | } 17 | } 18 | 19 | func createGroupByKeyToken(fieldName string, projectedName string) *groupByKeyToken { 20 | return newGroupByKeyToken(fieldName, projectedName) 21 | } 22 | 23 | func (t *groupByKeyToken) writeTo(writer *strings.Builder) error { 24 | writeQueryTokenField(writer, firstNonEmptyString(t.fieldName, "key()")) 25 | 26 | if t.projectedName == "" || t.projectedName == t.fieldName { 27 | return nil 28 | } 29 | 30 | writer.WriteString(" as ") 31 | writer.WriteString(t.projectedName) 32 | 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /group_by_method.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type GroupByMethod = string 4 | 5 | const ( 6 | GroupByMethodNone = "None" 7 | GroupByMethodArray = "Array" 8 | ) 9 | -------------------------------------------------------------------------------- /group_by_sum_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &groupBySumToken{} 6 | 7 | type groupBySumToken struct { 8 | projectedName string 9 | fieldName string 10 | } 11 | 12 | func newGroupBySumToken(fieldName string, projectedName string) *groupBySumToken { 13 | return &groupBySumToken{ 14 | fieldName: fieldName, 15 | projectedName: projectedName, 16 | } 17 | } 18 | 19 | func createGroupBySumToken(fieldName string, projectedName string) *groupBySumToken { 20 | return newGroupBySumToken(fieldName, projectedName) 21 | } 22 | 23 | func (t *groupBySumToken) writeTo(writer *strings.Builder) error { 24 | writer.WriteString("sum(") 25 | writer.WriteString(t.fieldName) 26 | writer.WriteString(")") 27 | 28 | if t.projectedName == "" { 29 | return nil 30 | } 31 | 32 | writer.WriteString(" as ") 33 | writer.WriteString(t.projectedName) 34 | return nil 35 | } 36 | -------------------------------------------------------------------------------- /group_by_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &groupByToken{} 6 | 7 | type groupByToken struct { 8 | fieldName string 9 | method GroupByMethod 10 | } 11 | 12 | func createGroupByToken(fieldName string, method GroupByMethod) *groupByToken { 13 | return &groupByToken{ 14 | fieldName: fieldName, 15 | method: method, 16 | } 17 | } 18 | 19 | func (t *groupByToken) writeTo(writer *strings.Builder) error { 20 | _method := t.method 21 | if _method != GroupByMethodNone { 22 | writer.WriteString("Array(") 23 | } 24 | writeQueryTokenField(writer, t.fieldName) 25 | if _method != GroupByMethodNone { 26 | writer.WriteString(")") 27 | } 28 | return nil 29 | } 30 | -------------------------------------------------------------------------------- /handling_maps.md: -------------------------------------------------------------------------------- 1 | This document tries to explain how we have to handle maps in Go code because it's a bit special. 2 | 3 | See also https://github.com/ravendb/ravendb-go-client/issues/105 4 | 5 | Maps have to be passed by a pointer to both `Store` and `Load` methods. 6 | 7 | This is different from structs where `Store` takes a `*Foo` and `Load` takes `**Foo`. 8 | 9 | In Go a map value, under the hood, is a pointer. 10 | 11 | However, we don't have access to that pointer (without using hacks that depend on internals of the runtime/compiler, which might change in the future). 12 | 13 | One result of that is that Go only allows to compare map value to a nil but not to another map. 14 | 15 | The only way to have a stable reference to a map is to use a pointer to it. 16 | 17 | This is similar to taking a pointer to a struct but it does look weird. 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /hi_lo_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // HiLoResult is a result of HiLoResult command 4 | type HiLoResult struct { 5 | Prefix string `json:"Prefix"` 6 | Low int64 `json:"Low"` 7 | High int64 `json:"High"` 8 | LastSize int64 `json:"LastSize"` 9 | ServerTag string `json:"ServerTag"` 10 | LastRangeAt *Time `json:"LastRangeAt"` 11 | } 12 | -------------------------------------------------------------------------------- /hi_lo_return_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var ( 8 | _ RavenCommand = &HiLoReturnCommand{} 9 | ) 10 | 11 | // HiLoReturnCommand represents "hi lo return" command 12 | type HiLoReturnCommand struct { 13 | RavenCommandBase 14 | 15 | tag string 16 | last int64 17 | end int64 18 | } 19 | 20 | // NewHiLoReturnCommand returns a new HiLoReturnCommand 21 | func NewHiLoReturnCommand(tag string, last int64, end int64) (*HiLoReturnCommand, error) { 22 | if last < 0 { 23 | return nil, newIllegalArgumentError("last is < 0") 24 | } 25 | if end < 0 { 26 | return nil, newIllegalArgumentError("end is < 0") 27 | } 28 | if tag == "" { 29 | return nil, newIllegalArgumentError("tag cannot be empty") 30 | } 31 | 32 | cmd := &HiLoReturnCommand{ 33 | RavenCommandBase: NewRavenCommandBase(), 34 | 35 | tag: tag, 36 | last: last, 37 | end: end, 38 | } 39 | cmd.IsReadRequest = true 40 | cmd.ResponseType = RavenCommandResponseTypeEmpty 41 | return cmd, nil 42 | } 43 | 44 | func (c *HiLoReturnCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 45 | url := node.URL + "/databases/" + node.Database + "/hilo/return?tag=" + c.tag + "&end=" + i64toa(c.end) + "&last=" + i64toa(c.last) 46 | 47 | return newHttpPut(url, nil) 48 | } 49 | -------------------------------------------------------------------------------- /http_cache_item.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "time" 4 | 5 | type httpCacheItem struct { 6 | changeVector *string // TODO: can probably be string 7 | payload []byte 8 | lastServerUpdate time.Time 9 | generation int // TODO: should this be atomicInteger? 10 | 11 | cache *httpCache 12 | } 13 | 14 | func newHttpCacheItem() *httpCacheItem { 15 | return &httpCacheItem{ 16 | lastServerUpdate: time.Now(), 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /http_extensions.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | "strings" 6 | ) 7 | 8 | func gttpExtensionsGetRequiredEtagHeader(response *http.Response) (*string, error) { 9 | hdr := response.Header.Get(headersEtag) 10 | if hdr == "" { 11 | return nil, newIllegalStateError("Response did't had an ETag header") 12 | } 13 | etag := httpExtensionsEtagHeaderToChangeVector(hdr) 14 | return &etag, nil 15 | } 16 | 17 | func gttpExtensionsGetEtagHeader(response *http.Response) *string { 18 | hdr := response.Header.Get(headersEtag) 19 | if hdr == "" { 20 | return nil 21 | } 22 | res := httpExtensionsEtagHeaderToChangeVector(hdr) 23 | return &res 24 | } 25 | 26 | func gttpExtensionsGetEtagHeaderFromMap(headers map[string]string) *string { 27 | hdr := headers[headersEtag] 28 | if hdr == "" { 29 | return nil 30 | } 31 | res := httpExtensionsEtagHeaderToChangeVector(hdr) 32 | return &res 33 | } 34 | 35 | // TODO: add test 36 | func httpExtensionsEtagHeaderToChangeVector(responseHeader string) string { 37 | panicIf(responseHeader == "", "Response did't had an ETag header") 38 | 39 | if strings.HasPrefix(responseHeader, `"`) { 40 | return responseHeader[1 : len(responseHeader)-1] 41 | } 42 | 43 | return responseHeader 44 | } 45 | 46 | func httpExtensionsGetBooleanHeader(response *http.Response, header string) bool { 47 | hdr := response.Header.Get(header) 48 | return strings.EqualFold(hdr, "true") 49 | } 50 | -------------------------------------------------------------------------------- /i_command_data.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // ICommandData represents command data 4 | type ICommandData interface { 5 | getId() string 6 | getName() string 7 | getChangeVector() *string 8 | getType() CommandType 9 | serialize(conventions *DocumentConventions) (interface{}, error) 10 | } 11 | 12 | // CommandData describes common data for commands 13 | type CommandData struct { 14 | ID string 15 | Name string 16 | ChangeVector *string 17 | Type CommandType 18 | } 19 | 20 | func (d *CommandData) getId() string { 21 | return d.ID 22 | } 23 | 24 | func (d *CommandData) getName() string { 25 | return d.Name 26 | } 27 | 28 | func (d *CommandData) getType() string { 29 | return d.Type 30 | } 31 | 32 | func (d *CommandData) getChangeVector() *string { 33 | return d.ChangeVector 34 | } 35 | 36 | func (d *CommandData) baseJSON() map[string]interface{} { 37 | res := map[string]interface{}{ 38 | "Id": d.ID, 39 | "Type": d.Type, 40 | "ChangeVector": d.ChangeVector, 41 | } 42 | return res 43 | } 44 | -------------------------------------------------------------------------------- /i_lazy_operation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // ILazyOperation defines methods required to implement lazy operation 4 | type ILazyOperation interface { 5 | createRequest() *getRequest 6 | getResult(results interface{}) error 7 | getQueryResult() *QueryResult 8 | isRequiresRetry() bool 9 | handleResponse(response *GetResponse) error 10 | } 11 | -------------------------------------------------------------------------------- /i_maintenance_operation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // For documentation/porting only. Go has no generics so it's the same 4 | // as IMaintenanceOperation 5 | type IVoidMaintenanceOperation = IMaintenanceOperation 6 | 7 | type IMaintenanceOperation interface { 8 | GetCommand(*DocumentConventions) (RavenCommand, error) 9 | } 10 | -------------------------------------------------------------------------------- /i_more_like_this_builder_base.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IMoreLikeThisBuilderBase interface { 4 | UsingAnyDocument() IMoreLikeThisOperations 5 | UsingDocument(documentJson string) IMoreLikeThisOperations 6 | } 7 | -------------------------------------------------------------------------------- /i_more_like_this_builder_for_document_query.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IMoreLikeThisBuilderForDocumentQuery interface { 4 | // Note: it's usingDocument() in Java but conflicts with IMoreLikeThisBuilderBase 5 | UsingDocumentWithBuilder(builder func(*DocumentQuery)) IMoreLikeThisOperations 6 | 7 | UsingAnyDocument() IMoreLikeThisOperations 8 | UsingDocument(string) IMoreLikeThisOperations 9 | } 10 | -------------------------------------------------------------------------------- /i_more_like_this_operations.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IMoreLikeThisOperations interface { 4 | WithOptions(options *MoreLikeThisOptions) IMoreLikeThisOperations 5 | } 6 | -------------------------------------------------------------------------------- /i_operation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IOperation interface { 4 | GetCommand(store *DocumentStore, conventions *DocumentConventions, cache *httpCache) (RavenCommand, error) 5 | } 6 | -------------------------------------------------------------------------------- /i_server_operation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IServerOperation interface { 4 | GetCommand(*DocumentConventions) (RavenCommand, error) 5 | } 6 | -------------------------------------------------------------------------------- /id_type_and_name.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type idTypeAndName struct { 4 | id string 5 | typ CommandType 6 | name string 7 | } 8 | 9 | func newIDTypeAndName(id string, typ CommandType, name string) idTypeAndName { 10 | return idTypeAndName{ 11 | id: id, 12 | typ: typ, 13 | name: name, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /includes_util.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | func includesUtilInclude(document map[string]interface{}, include string, loadID func(string)) { 4 | if stringIsEmpty(include) || document == nil { 5 | return 6 | } 7 | 8 | //TBD: 9 | } 10 | -------------------------------------------------------------------------------- /index_change.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // IndexChange describes a change to the index. Can be used as DatabaseChange. 4 | type IndexChange struct { 5 | Type IndexChangeTypes 6 | Name string 7 | } 8 | -------------------------------------------------------------------------------- /index_change_types.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IndexChangeTypes = string 4 | 5 | const ( 6 | IndexChangeNone = "None" 7 | IndexChangeBatchCompleted = "BatchCompleted" 8 | IndexChangeIndexAdded = "IndexAdded" 9 | IndexChangeIndexRemoved = "IndexRemoved" 10 | IndexChangeIndexDemotedToIdle = "IndexDemotedToIdle" 11 | IndexChangeIndexPromotedFromIdle = "IndexPromotedFromIdle" 12 | IndexChangeIndexDemotedToDisabled = "IndexDemotedToDisabled" 13 | IndexChangeIndexMarkedAsErrored = "IndexMarkedAsErrored" 14 | IndexChangeSideBySideReplace = "SideBySideReplace" 15 | IndexChangeRenamed = "Renamed" 16 | IndexChangeIndexPaused = "IndexPaused" 17 | IndexChangeLockModeChanged = "LockModeChanged" 18 | IndexChangePriorityChanged = "PriorityChanged" 19 | ) 20 | -------------------------------------------------------------------------------- /index_configuration.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // TODO: desugar 4 | type IndexConfiguration = map[string]string 5 | 6 | func NewIndexConfiguration() IndexConfiguration { 7 | return make(map[string]string) 8 | } 9 | -------------------------------------------------------------------------------- /index_creation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | func indexCreationCreateIndexesToAdd(indexCreationTasks []*IndexCreationTask, conventions *DocumentConventions) []*IndexDefinition { 4 | var res []*IndexDefinition 5 | for _, x := range indexCreationTasks { 6 | x.Conventions = conventions 7 | definition := x.CreateIndexDefinition() 8 | definition.Name = x.IndexName 9 | pri := x.Priority 10 | if pri == "" { 11 | pri = IndexPriorityNormal 12 | } 13 | definition.Priority = pri 14 | res = append(res, definition) 15 | } 16 | return res 17 | } 18 | -------------------------------------------------------------------------------- /index_errors.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // IndexErrors describes index errors 4 | type IndexErrors struct { 5 | Name string `json:"Name"` 6 | Errors []*IndexingError `json:"Errors"` 7 | } 8 | -------------------------------------------------------------------------------- /index_field_options.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IndexFieldOptions struct { 4 | Storage FieldStorage `json:"Storage,omitempty"` 5 | Indexing FieldIndexing `json:"Indexing,omitempty"` 6 | TermVector FieldTermVector `json:"TermVector,omitempty"` 7 | Spatial *SpatialOptions `json:"Spatial"` 8 | Analyzer string `json:"Analyzer,omitempty"` 9 | Suggestions bool `json:"Suggestions"` 10 | } 11 | 12 | func NewIndexFieldOptions() *IndexFieldOptions { 13 | return &IndexFieldOptions{} 14 | } 15 | -------------------------------------------------------------------------------- /index_information.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "time" 4 | 5 | type IndexInformation struct { 6 | Name string `json:"Name"` 7 | IsStale bool `json:"IsStale"` 8 | State IndexState `json:"State"` 9 | LockMode IndexLockMode `json:"LockMode"` 10 | Priority IndexPriority `json:"Priority"` 11 | Type IndexType `json:"Type"` 12 | LastIndexingTime Time `json:"LastIndexingTime"` 13 | } 14 | 15 | func (i *IndexInformation) GetLastIndexingTime() time.Time { 16 | return time.Time(i.LastIndexingTime) 17 | } 18 | -------------------------------------------------------------------------------- /index_lock_mode.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IndexLockMode = string 4 | 5 | const ( 6 | IndexLockModeUnlock = "Unlock" 7 | IndexLockModeLockedIgnore = "LockedIgnore" 8 | IndexLockModeLockedError = "LockedError" 9 | ) 10 | -------------------------------------------------------------------------------- /index_priority.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IndexPriority = string 4 | 5 | const ( 6 | IndexPriorityLow = "Low" 7 | IndexPriorityNormal = "Normal" 8 | IndexPriorityHigh = "High" 9 | ) 10 | -------------------------------------------------------------------------------- /index_query_base.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // Note: IndexQueryBase is part of IndexQuery in index_query.go 4 | -------------------------------------------------------------------------------- /index_query_content.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var _ IContent = &IndexQueryContent{} 4 | 5 | type IndexQueryContent struct { 6 | _conventions *DocumentConventions 7 | _query *IndexQuery 8 | } 9 | 10 | func NewIndexQueryContent(conventions *DocumentConventions, query *IndexQuery) *IndexQueryContent { 11 | return &IndexQueryContent{ 12 | _conventions: conventions, 13 | _query: query, 14 | } 15 | } 16 | 17 | func (q *IndexQueryContent) writeContent() map[string]interface{} { 18 | return jsonExtensionsWriteIndexQuery(q._conventions, q._query) 19 | } 20 | -------------------------------------------------------------------------------- /index_query_with_parameters.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // Note: IndexQueryWithParameters is part of IndexQuery in index_query.go 4 | -------------------------------------------------------------------------------- /index_running_status.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IndexRunningStatus = string 4 | 5 | const ( 6 | IndexRunningStatusRunning = "Running" 7 | IndexRunningStatusPaused = "Paused" 8 | IndexRunningStatusDisabled = "Disabled" 9 | ) 10 | -------------------------------------------------------------------------------- /index_state.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IndexState = string 4 | 5 | const ( 6 | IndexStateNormal = "Normal" 7 | IndexStateDisabled = "Disabled" 8 | IndexStateIdle = "Idle" 9 | IndexStateError = "Error" 10 | ) 11 | -------------------------------------------------------------------------------- /index_type.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IndexType = string 4 | 5 | const ( 6 | IndexTypeNone = "None" 7 | IndexTypeAutoMap = "AutoMap" 8 | IndexTypeAutoMapReduce = "AutoMapReduce" 9 | IndexTypeMap = "Map" 10 | IndexTypeMapReduce = "MapReduce" 11 | IndexTypeFaulty = "Faulty" 12 | ) 13 | -------------------------------------------------------------------------------- /indexing_error.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // IndexingError describes indexing error message from the server 4 | type IndexingError struct { 5 | Error string `json:"Error"` 6 | Timestamp Time `json:"Timestamp"` 7 | Document string `json:"Document"` 8 | Action string `json:"Action"` 9 | } 10 | 11 | func (e *IndexingError) String() string { 12 | return "Error: " + e.Error + ", Document: " + e.Document + ", Action: " + e.Action 13 | } 14 | -------------------------------------------------------------------------------- /indexing_status.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type IndexingStatus struct { 4 | Status IndexRunningStatus `json:"Status"` 5 | Indexes []*IndexStatus `json:"Indexes"` 6 | } 7 | 8 | type IndexStatus struct { 9 | Name string `json:"Name"` 10 | Status IndexRunningStatus `json:"Status"` 11 | } 12 | -------------------------------------------------------------------------------- /intersect_marker_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var intersectMarkerTokenInstance queryToken = singleStringToken(",") 4 | -------------------------------------------------------------------------------- /json_array_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // JSONArrayResult describes server's JSON response to batch command 4 | type JSONArrayResult struct { 5 | Results []map[string]interface{} `json:"Results"` 6 | TransactionIndex int64 `json:"TransactionIndex"` 7 | } 8 | 9 | func (r *JSONArrayResult) getResults() []map[string]interface{} { 10 | return r.Results 11 | } 12 | -------------------------------------------------------------------------------- /json_extensions.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | func jsonExtensionsWriteIndexQuery(conventions *DocumentConventions, query *IndexQuery) map[string]interface{} { 4 | res := map[string]interface{}{} 5 | res["Query"] = query.query 6 | if query.pageSize > 0 { 7 | res["PageSize"] = query.pageSize 8 | } 9 | 10 | if query.waitForNonStaleResults { 11 | res["WaitForNonStaleResults"] = query.waitForNonStaleResults 12 | } 13 | 14 | if query.start > 0 { 15 | res["Start"] = query.start 16 | } 17 | 18 | if query.waitForNonStaleResultsTimeout != 0 { 19 | s := durationToTimeSpan(query.waitForNonStaleResultsTimeout) 20 | res["WaitForNonStaleResultsTimeout"] = s 21 | } 22 | 23 | if query.disableCaching { 24 | res["DisableCaching"] = query.disableCaching 25 | } 26 | 27 | if query.skipDuplicateChecking { 28 | res["SkipDuplicateChecking"] = query.skipDuplicateChecking 29 | } 30 | params := query.queryParameters 31 | if params != nil { 32 | res["QueryParameters"] = convertEntityToJSON(params, nil) 33 | } else { 34 | res["QueryParameters"] = nil 35 | } 36 | return res 37 | } 38 | 39 | func tryGetConflict(metadata map[string]interface{}) bool { 40 | v, ok := metadata[MetadataConflict] 41 | if !ok { 42 | return false 43 | } 44 | b, ok := v.(bool) 45 | if !ok { 46 | return false 47 | } 48 | return b 49 | } 50 | -------------------------------------------------------------------------------- /kill_operation_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "net/http" 4 | 5 | var ( 6 | _ RavenCommand = &KillOperationCommand{} 7 | ) 8 | 9 | // KillOperationCommand represents "kill operation" command 10 | type KillOperationCommand struct { 11 | RavenCommandBase 12 | 13 | id string 14 | } 15 | 16 | // NewKillOperationCommand returns new KillOperationCommand 17 | func NewKillOperationCommand(id string) (*KillOperationCommand, error) { 18 | if id == "" { 19 | return nil, newIllegalArgumentError("id cannot be empty") 20 | } 21 | cmd := &KillOperationCommand{ 22 | RavenCommandBase: NewRavenCommandBase(), 23 | 24 | id: id, 25 | } 26 | cmd.ResponseType = RavenCommandResponseTypeEmpty 27 | 28 | return cmd, nil 29 | } 30 | 31 | func (c *KillOperationCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 32 | url := node.URL + "/databases/" + node.Database + "/operations/kill?id=" + c.id 33 | 34 | return NewHttpPost(url, nil) 35 | } 36 | -------------------------------------------------------------------------------- /lazy.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "sync" 4 | 5 | // Lazy represents a lazy operation 6 | type Lazy struct { 7 | // function which, when called, executes lazy operation 8 | valueFactory func(interface{}) error 9 | err error 10 | valueCreated bool 11 | Value interface{} 12 | mu sync.Mutex 13 | } 14 | 15 | func newLazy(valueFactory func(interface{}) error) *Lazy { 16 | return &Lazy{ 17 | valueFactory: valueFactory, 18 | } 19 | } 20 | 21 | // IsValueCreated returns true if lazy value has been created 22 | func (l *Lazy) IsValueCreated() bool { 23 | l.mu.Lock() 24 | defer l.mu.Unlock() 25 | 26 | if l.err != nil { 27 | return false 28 | } 29 | 30 | return l.valueCreated 31 | } 32 | 33 | // GetValue executes lazy operation and ensures the Value is set in result variable 34 | // provided in NewLazy() 35 | func (l *Lazy) GetValue(result interface{}) error { 36 | if result == nil { 37 | return newIllegalArgumentError("result cannot be nil") 38 | } 39 | l.mu.Lock() 40 | defer l.mu.Unlock() 41 | 42 | if !l.valueCreated { 43 | l.err = l.valueFactory(result) 44 | l.valueCreated = true 45 | if l.err != nil { 46 | l.Value = result 47 | } 48 | } 49 | 50 | if l.err != nil { 51 | return l.err 52 | } 53 | 54 | if l.Value == nil { 55 | return nil 56 | } 57 | 58 | // can call with nil to force evaluation of lazy operations 59 | if result != nil { 60 | setInterfaceToValue(result, l.Value) 61 | } 62 | 63 | return nil 64 | } 65 | -------------------------------------------------------------------------------- /leader_stamp.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // LeaderStamp describes leader stamp 4 | type LeaderStamp struct { 5 | Index int64 `json:"Index"` 6 | Term int64 `json:"Term"` 7 | LeadersTicks int64 `json:"LeadersTicks"` 8 | } 9 | -------------------------------------------------------------------------------- /load_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &loadToken{} 6 | 7 | type loadToken struct { 8 | argument string 9 | alias string 10 | } 11 | 12 | func (t *loadToken) writeTo(writer *strings.Builder) error { 13 | writer.WriteString(t.argument) 14 | writer.WriteString(" as ") 15 | writer.WriteString(t.alias) 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /map_util.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | func dupMapStringString(m map[string]string) map[string]string { 4 | if m == nil { 5 | return nil 6 | } 7 | ret := make(map[string]string) 8 | for k, v := range m { 9 | ret[k] = v 10 | } 11 | return ret 12 | } 13 | 14 | func dupMapStringFloat64(m map[string]float64) map[string]float64 { 15 | if m == nil { 16 | return nil 17 | } 18 | ret := make(map[string]float64) 19 | for k, v := range m { 20 | ret[k] = v 21 | } 22 | return ret 23 | } 24 | -------------------------------------------------------------------------------- /method_call.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type MethodCall interface { 4 | } 5 | 6 | type MethodCallData struct { 7 | args []interface{} 8 | accessPath string 9 | } 10 | -------------------------------------------------------------------------------- /modify_ongoing_task_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // ModifyOngoingTaskResult represents a raven server command 4 | // for modyfing task result 5 | type ModifyOngoingTaskResult struct { 6 | TaskID int64 `json:"TaskId"` 7 | RaftCommandIndex int64 `json:"RaftCommandIndex"` 8 | ResponsibleNode string `json:"ResponsibleNode"` 9 | } 10 | -------------------------------------------------------------------------------- /more_like_this_base.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type MoreLikeThisBase interface { 4 | GetOptions() *MoreLikeThisOptions 5 | SetOptions(options *MoreLikeThisOptions) 6 | } 7 | 8 | type MoreLikeThisCommon struct { 9 | options *MoreLikeThisOptions 10 | } 11 | 12 | func (c *MoreLikeThisCommon) GetOptions() *MoreLikeThisOptions { 13 | return c.options 14 | } 15 | 16 | func (c *MoreLikeThisCommon) SetOptions(options *MoreLikeThisOptions) { 17 | c.options = options 18 | } 19 | -------------------------------------------------------------------------------- /more_like_this_builder.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var _ IMoreLikeThisOperations = &MoreLikeThisBuilder{} 4 | var _ IMoreLikeThisBuilderForDocumentQuery = &MoreLikeThisBuilder{} 5 | var _ IMoreLikeThisBuilderBase = &MoreLikeThisBuilder{} 6 | 7 | type MoreLikeThisBuilder struct { 8 | moreLikeThis MoreLikeThisBase 9 | } 10 | 11 | func NewMoreLikeThisBuilder() *MoreLikeThisBuilder { 12 | return &MoreLikeThisBuilder{} 13 | } 14 | 15 | func (b *MoreLikeThisBuilder) GetMoreLikeThis() MoreLikeThisBase { 16 | return b.moreLikeThis 17 | } 18 | 19 | func (b *MoreLikeThisBuilder) UsingAnyDocument() IMoreLikeThisOperations { 20 | b.moreLikeThis = NewMoreLikeThisUsingAnyDocument() 21 | return b 22 | } 23 | 24 | func (b *MoreLikeThisBuilder) UsingDocument(documentJSON string) IMoreLikeThisOperations { 25 | b.moreLikeThis = &MoreLikeThisUsingDocument{ 26 | documentJSON: documentJSON, 27 | } 28 | 29 | return b 30 | } 31 | 32 | func (b *MoreLikeThisBuilder) UsingDocumentWithBuilder(builder func(*DocumentQuery)) IMoreLikeThisOperations { 33 | tmp := NewMoreLikeThisUsingDocumentForDocumentQuery() 34 | tmp.setForDocumentQuery(builder) 35 | b.moreLikeThis = tmp 36 | return b 37 | } 38 | 39 | func (b *MoreLikeThisBuilder) WithOptions(options *MoreLikeThisOptions) IMoreLikeThisOperations { 40 | b.moreLikeThis.SetOptions(options) 41 | 42 | return b 43 | } 44 | -------------------------------------------------------------------------------- /more_like_this_query_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // MoreLikeThisQueryResult describes result of "more like this" operation 4 | type MoreLikeThisQueryResult struct { 5 | queryResultBase 6 | DurationInMs int64 `json:"DurationInMs"` 7 | } 8 | -------------------------------------------------------------------------------- /more_like_this_scope.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type moreLikeThisScope struct { 4 | token *moreLikeThisToken 5 | addQueryParameter func(interface{}) string 6 | onDispose func() 7 | } 8 | 9 | func newMoreLikeThisScope(token *moreLikeThisToken, addQueryParameter func(interface{}) string, onDispose func()) *moreLikeThisScope { 10 | return &moreLikeThisScope{ 11 | token: token, 12 | addQueryParameter: addQueryParameter, 13 | onDispose: onDispose, 14 | } 15 | } 16 | 17 | func (s *moreLikeThisScope) Close() { 18 | if s.onDispose != nil { 19 | s.onDispose() 20 | } 21 | } 22 | 23 | func (s *moreLikeThisScope) withOptions(options *MoreLikeThisOptions) { 24 | if options == nil { 25 | return 26 | } 27 | 28 | // force using *non* entity serializer here: 29 | optionsAsJson := valueToTree(options) 30 | s.token.optionsParameterName = s.addQueryParameter(optionsAsJson) 31 | } 32 | 33 | func (s *moreLikeThisScope) withDocument(document string) { 34 | s.token.documentParameterName = s.addQueryParameter(document) 35 | } 36 | -------------------------------------------------------------------------------- /more_like_this_stop_words.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type MoreLikeThisStopWords struct { 4 | ID string `json:"Id"` 5 | StopWords []string `json:"StopWords"` 6 | } 7 | -------------------------------------------------------------------------------- /more_like_this_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &moreLikeThisToken{} 6 | 7 | type moreLikeThisToken struct { 8 | documentParameterName string 9 | optionsParameterName string 10 | whereTokens []queryToken 11 | } 12 | 13 | func newMoreLikeThisToken() *moreLikeThisToken { 14 | return &moreLikeThisToken{} 15 | } 16 | 17 | func (t *moreLikeThisToken) writeTo(writer *strings.Builder) error { 18 | writer.WriteString("moreLikeThis(") 19 | 20 | if t.documentParameterName == "" { 21 | var prevToken queryToken 22 | for _, whereToken := range t.whereTokens { 23 | documentQueryHelperAddSpaceIfNeeded(prevToken, whereToken, writer) 24 | whereToken.writeTo(writer) 25 | prevToken = whereToken 26 | } 27 | } else { 28 | writer.WriteString("$") 29 | writer.WriteString(t.documentParameterName) 30 | } 31 | 32 | if t.optionsParameterName == "" { 33 | writer.WriteString(")") 34 | return nil 35 | } 36 | 37 | writer.WriteString(", $") 38 | writer.WriteString(t.optionsParameterName) 39 | writer.WriteString(")") 40 | 41 | return nil 42 | } 43 | -------------------------------------------------------------------------------- /more_like_this_using_any_document.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var _ MoreLikeThisBase = &MoreLikeThisUsingAnyDocument{} 4 | 5 | type MoreLikeThisUsingAnyDocument struct { 6 | MoreLikeThisCommon 7 | } 8 | 9 | func NewMoreLikeThisUsingAnyDocument() *MoreLikeThisUsingAnyDocument { 10 | return &MoreLikeThisUsingAnyDocument{} 11 | } 12 | -------------------------------------------------------------------------------- /more_like_this_using_document.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var _ MoreLikeThisBase = &MoreLikeThisUsingDocument{} 4 | 5 | // MoreLikeThisUsingDocument represents more like this with a document 6 | type MoreLikeThisUsingDocument struct { 7 | MoreLikeThisCommon 8 | 9 | documentJSON string 10 | } 11 | -------------------------------------------------------------------------------- /more_like_this_using_document_for_document_query.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var _ MoreLikeThisBase = &MoreLikeThisUsingDocumentForDocumentQuery{} 4 | 5 | type MoreLikeThisUsingDocumentForDocumentQuery struct { 6 | MoreLikeThisCommon 7 | 8 | forDocumentQuery func(*DocumentQuery) 9 | } 10 | 11 | func NewMoreLikeThisUsingDocumentForDocumentQuery() *MoreLikeThisUsingDocumentForDocumentQuery { 12 | return &MoreLikeThisUsingDocumentForDocumentQuery{} 13 | } 14 | 15 | func (m *MoreLikeThisUsingDocumentForDocumentQuery) GetForDocumentQuery() func(*DocumentQuery) { 16 | return m.forDocumentQuery 17 | } 18 | 19 | func (m *MoreLikeThisUsingDocumentForDocumentQuery) setForDocumentQuery(forDocumentQuery func(*DocumentQuery)) { 20 | m.forDocumentQuery = forDocumentQuery 21 | } 22 | -------------------------------------------------------------------------------- /multi_get_operation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // MultiGetOperation represents multi-get operation 4 | type MultiGetOperation struct { 5 | session *InMemoryDocumentSessionOperations 6 | } 7 | 8 | func (o *MultiGetOperation) createRequest(requests []*getRequest) *MultiGetCommand { 9 | return newMultiGetCommand(o.session.GetRequestExecutor().Cache, requests) 10 | } 11 | 12 | // Note: not used 13 | func (o *MultiGetOperation) setResult(result map[string]interface{}) { 14 | // no-op 15 | } 16 | -------------------------------------------------------------------------------- /negate_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var negateTokenInstance queryToken = singleStringToken("not") 4 | -------------------------------------------------------------------------------- /next_identity_for_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var ( 8 | _ RavenCommand = &NextIdentityForCommand{} 9 | ) 10 | 11 | type NextIdentityForCommand struct { 12 | RavenCommandBase 13 | 14 | _id string 15 | 16 | Result int 17 | } 18 | 19 | func NewNextIdentityForCommand(id string) *NextIdentityForCommand { 20 | res := &NextIdentityForCommand{ 21 | RavenCommandBase: NewRavenCommandBase(), 22 | 23 | _id: id, 24 | } 25 | panicIf(id == "", "Id cannot be null") 26 | 27 | return res 28 | } 29 | 30 | func (c *NextIdentityForCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 31 | err := ensureIsNotNullOrString(c._id, "ID") 32 | if err != nil { 33 | return nil, err 34 | } 35 | 36 | url := node.URL + "/databases/" + node.Database + "/identity/next?name=" + urlEncode(c._id) 37 | 38 | return NewHttpPost(url, nil) 39 | } 40 | 41 | func (c *NextIdentityForCommand) SetResponse(response []byte, fromCache bool) error { 42 | if len(response) == 0 { 43 | return throwInvalidResponse() 44 | } 45 | var jsonNode map[string]interface{} 46 | err := jsonUnmarshal(response, &jsonNode) 47 | if err != nil { 48 | return err 49 | } 50 | n, ok := jsonGetAsInt(jsonNode, "NewIdentityValue") 51 | if !ok { 52 | return throwInvalidResponse() 53 | } 54 | c.Result = n 55 | return nil 56 | } 57 | -------------------------------------------------------------------------------- /node_id.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // NodeID describes a node 4 | type NodeID struct { 5 | NodeTag string `json:"NodeTag"` 6 | NodeURL string `json:"NodeUrl"` 7 | ResponsibleNode string `json:"ResponsibleNode"` 8 | } 9 | -------------------------------------------------------------------------------- /open_subclause_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &openSubclauseToken{} 6 | 7 | var ( 8 | openSubclauseTokenInstance = &openSubclauseToken{} 9 | ) 10 | 11 | type openSubclauseToken struct { 12 | } 13 | 14 | func (t *openSubclauseToken) writeTo(writer *strings.Builder) error { 15 | writer.WriteString("(") 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /operation_exception_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // OperationExceptionResult represents an exception information from the server 4 | type OperationExceptionResult struct { 5 | Type string `json:"Type"` 6 | Message string `json:"Message"` 7 | Error string `json:"Error"` 8 | StatusCode int `json:"StatusCode"` 9 | } 10 | -------------------------------------------------------------------------------- /operation_id_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // OperationIDResult is a result of commands like CompactDatabaseCommand 4 | type OperationIDResult struct { 5 | OperationID int64 `json:"OperationId"` 6 | } 7 | -------------------------------------------------------------------------------- /operation_status_change.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // OperationStatusChange describes a change to the operation status. Can be used as DatabaseChange. 4 | type OperationStatusChange struct { 5 | OperationID int64 6 | State map[string]interface{} 7 | } 8 | -------------------------------------------------------------------------------- /ordering_type.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type OrderingType = string 4 | 5 | const ( 6 | OrderingTypeString = "STRING" 7 | OrderingTypeLong = "LONG" 8 | OrderingTypeDouble = "DOUBLE" 9 | OrderingTypeAlphaNumeric = "ALPHA_NUMERIC" 10 | ) 11 | -------------------------------------------------------------------------------- /parameters.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type Parameters = map[string]interface{} 4 | -------------------------------------------------------------------------------- /patch_command_data.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type PatchCommandData struct { 4 | *CommandData 5 | 6 | patch *PatchRequest 7 | patchIfMissing *PatchRequest 8 | } 9 | 10 | // NewPatchCommandData creates CommandData for Delete Attachment command 11 | // TODO: return a concrete type? 12 | func NewPatchCommandData(id string, changeVector *string, patch *PatchRequest, patchIfMissing *PatchRequest) ICommandData { 13 | // TODO: verify args 14 | res := &PatchCommandData{ 15 | CommandData: &CommandData{ 16 | ID: id, 17 | Type: CommandPatch, 18 | ChangeVector: changeVector, 19 | }, 20 | patch: patch, 21 | patchIfMissing: patchIfMissing, 22 | } 23 | return res 24 | } 25 | 26 | func (d *PatchCommandData) serialize(conventions *DocumentConventions) (interface{}, error) { 27 | res := d.baseJSON() 28 | res["Patch"] = d.patch.Serialize() 29 | 30 | if d.patchIfMissing != nil { 31 | res["PatchIfMissing"] = d.patchIfMissing.Serialize() 32 | } 33 | return res, nil 34 | } 35 | -------------------------------------------------------------------------------- /patch_request.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // PatchRequest represents patch request 4 | type PatchRequest struct { 5 | Script string 6 | Values map[string]interface{} 7 | } 8 | 9 | // Serialize serializes PatchRequest to json 10 | func (r *PatchRequest) Serialize() map[string]interface{} { 11 | values := r.Values 12 | if values == nil { 13 | values = map[string]interface{}{} 14 | } 15 | m := map[string]interface{}{ 16 | "Script": r.Script, 17 | "Values": values, 18 | } 19 | return m 20 | } 21 | -------------------------------------------------------------------------------- /patch_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // PatchResult describes server results of patch command 4 | type PatchResult struct { 5 | Status PatchStatus `json:"Status"` 6 | ModifiedDocument map[string]interface{} `json:"ModifiedDocument"` 7 | OriginalDocument map[string]interface{} `json:"OriginalDocument"` 8 | Debug map[string]interface{} `json:"Debug"` 9 | 10 | // TODO: can this ever be null? If not, use string for type 11 | ChangeVector *string `json:"ChangeVector"` 12 | Collection string `json:"Collection"` 13 | } 14 | -------------------------------------------------------------------------------- /patch_status.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type PatchStatus = string 4 | 5 | const ( 6 | PatchStatusDocumentDoesNotExist = "DocumentDoesNotExist" 7 | PatchStatusCreated = "Created" 8 | PatchStatusPatched = "Patched" 9 | PatchStatusSkipped = "Skipped" 10 | PatchStatusNotModified = "NotModified" 11 | ) 12 | -------------------------------------------------------------------------------- /point_field.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var _ DynamicSpatialField = &PointField{} 4 | 5 | type PointField struct { 6 | latitude string 7 | longitude string 8 | } 9 | 10 | func NewPointField(latitude string, longitude string) *PointField { 11 | return &PointField{ 12 | latitude: latitude, 13 | longitude: longitude, 14 | } 15 | } 16 | 17 | func (f *PointField) ToField(ensureValidFieldName func(string, bool) (string, error)) (string, error) { 18 | name1, err := ensureValidFieldName(f.latitude, false) 19 | if err != nil { 20 | return "", err 21 | } 22 | name2, err := ensureValidFieldName(f.longitude, false) 23 | if err != nil { 24 | return "", err 25 | } 26 | return "spatial.point(" + name1 + ", " + name2 + ")", nil 27 | } 28 | -------------------------------------------------------------------------------- /put_command_data_with_json.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // PutCommandDataWithJSON represents data for put command with json 4 | type PutCommandDataWithJSON struct { 5 | *CommandData 6 | document map[string]interface{} 7 | } 8 | 9 | var _ ICommandData = &PutCommandDataWithJSON{} // verify interface match 10 | 11 | // newPutCommandDataWithJSON returns new PutCommandDataWithJSON 12 | func newPutCommandDataWithJSON(id string, changeVector *string, document map[string]interface{}) *PutCommandDataWithJSON { 13 | panicIf(document == nil, "Document cannot be nil") 14 | 15 | res := &PutCommandDataWithJSON{ 16 | CommandData: &CommandData{ 17 | Type: CommandPut, 18 | ID: id, 19 | ChangeVector: changeVector, 20 | }, 21 | document: document, 22 | } 23 | return res 24 | } 25 | 26 | func (d *PutCommandDataWithJSON) serialize(conventions *DocumentConventions) (interface{}, error) { 27 | js := d.baseJSON() 28 | js["Document"] = d.document 29 | return js, nil 30 | } 31 | -------------------------------------------------------------------------------- /put_connection_string_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // PutConnectionStringResult describes result of "put connection" command 4 | type PutConnectionStringResult struct { 5 | Etag int64 `json:"ETag"` 6 | } 7 | -------------------------------------------------------------------------------- /put_document_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var ( 8 | _ RavenCommand = &PutDocumentCommand{} 9 | ) 10 | 11 | type PutDocumentCommand struct { 12 | RavenCommandBase 13 | 14 | _id string 15 | _changeVector *string 16 | _document map[string]interface{} 17 | 18 | Result *PutResult 19 | } 20 | 21 | func NewPutDocumentCommand(id string, changeVector *string, document map[string]interface{}) *PutDocumentCommand { 22 | panicIf(id == "", "Id cannot be null") 23 | panicIf(document == nil, "document cannot be nil") 24 | 25 | cmd := &PutDocumentCommand{ 26 | RavenCommandBase: NewRavenCommandBase(), 27 | 28 | _id: id, 29 | _changeVector: changeVector, 30 | _document: document, 31 | } 32 | return cmd 33 | } 34 | 35 | func (c *PutDocumentCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 36 | url := node.URL + "/databases/" + node.Database + "/docs?id=" + urlEncode(c._id) 37 | 38 | d, err := jsonMarshal(c._document) 39 | if err != nil { 40 | return nil, err 41 | } 42 | request, err := newHttpPut(url, d) 43 | if err != nil { 44 | return nil, err 45 | } 46 | addChangeVectorIfNotNull(c._changeVector, request) 47 | return request, nil 48 | } 49 | 50 | func (c *PutDocumentCommand) SetResponse(response []byte, fromCache bool) error { 51 | return jsonUnmarshal(response, &c.Result) 52 | } 53 | -------------------------------------------------------------------------------- /put_index_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // PutIndexResult represents result of put index command 4 | type PutIndexResult struct { 5 | // Note: don't know how Java does it, but this is sent 6 | // as Index in JSON responses from the server 7 | IndexName string `json:"Index"` 8 | } 9 | -------------------------------------------------------------------------------- /put_indexes_response.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // PutIndexesResponse represents server's response to PutIndexesCommand 4 | type PutIndexesResponse struct { 5 | Results []*PutIndexResult `json:"Results"` 6 | } 7 | -------------------------------------------------------------------------------- /put_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // PutResult describes result of PutDocumentCommand 4 | type PutResult struct { 5 | ID string `json:"Id"` 6 | ChangeVector *string `json:"ChangeVector"` 7 | } 8 | -------------------------------------------------------------------------------- /query_data.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // QueryData represents 4 | type QueryData struct { 5 | // Fields lists fields to be selected from queried document 6 | Fields []string 7 | // Projections lists fields in the result entity 8 | Projections []string 9 | 10 | // TODO: should those be exposed as well? 11 | fromAlias string 12 | declareToken *declareToken 13 | loadTokens []*loadToken 14 | isCustomFunction bool 15 | } 16 | -------------------------------------------------------------------------------- /query_field_util.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | func queryFieldUtilEscapeIfNecessary(name string) string { 4 | if stringIsEmpty(name) || 5 | IndexingFieldNameDocumentID == name || 6 | IndexingFieldNameReduceKeyHash == name || 7 | IndexingFieldNameReduceKeyValue == name || 8 | IndexingFieldsNameSpatialShare == name { 9 | return name 10 | } 11 | 12 | escape := false 13 | insideEscaped := false 14 | 15 | for i, c := range name { 16 | 17 | if c == '\'' || c == '"' { 18 | insideEscaped = !insideEscaped 19 | continue 20 | } 21 | 22 | if i == 0 { 23 | if !isLetter(c) && c != '_' && c != '@' && !insideEscaped { 24 | escape = true 25 | break 26 | } 27 | } else { 28 | if !isLetterOrDigit(c) && c != '_' && c != '-' && c != '@' && c != '.' && c != '[' && c != ']' && !insideEscaped { 29 | escape = true 30 | break 31 | } 32 | } 33 | } 34 | 35 | if escape || insideEscaped { 36 | return "'" + name + "'" 37 | } 38 | 39 | return name 40 | } 41 | -------------------------------------------------------------------------------- /query_operation_options.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "time" 4 | 5 | // QueryOperationOptions represents options for query operation 6 | type QueryOperationOptions struct { 7 | MaxOpsPerSecond int 8 | AllowStale bool 9 | StaleTimeout time.Duration 10 | RetrieveDetails bool 11 | } 12 | -------------------------------------------------------------------------------- /query_operator.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type QueryOperator string 4 | 5 | const ( 6 | QueryOperatorAnd = "And" 7 | QueryOperatorOr = "Or" 8 | ) 9 | -------------------------------------------------------------------------------- /query_operator_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &queryOperatorToken{} 6 | 7 | type queryOperatorToken struct { 8 | queryOperator QueryOperator 9 | } 10 | 11 | var ( 12 | queryOperatorTokenAnd = &queryOperatorToken{ 13 | queryOperator: QueryOperatorAnd, 14 | } 15 | queryOperatorTokenOr = &queryOperatorToken{ 16 | queryOperator: QueryOperatorOr, 17 | } 18 | ) 19 | 20 | func (t *queryOperatorToken) writeTo(writer *strings.Builder) error { 21 | if t.queryOperator == QueryOperatorAnd { 22 | writer.WriteString("and") 23 | return nil 24 | } 25 | 26 | writer.WriteString("or") 27 | return nil 28 | } 29 | -------------------------------------------------------------------------------- /query_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // QueryResults represents results of a query 4 | type QueryResult struct { 5 | GenericQueryResult 6 | } 7 | 8 | func (r *QueryResult) createSnapshot() *QueryResult { 9 | queryResult := *r 10 | 11 | /* TBD 4.1 12 | Map>> highlightings = getHighlightings(); 13 | 14 | if (highlightings != null) { 15 | Map>> newHighlights = new HashMap<>(); 16 | for (Map.Entry>> hightlightEntry : getHighlightings().entrySet()) { 17 | newHighlights.put(hightlightEntry.getKey(), new HashMap<>(hightlightEntry.getValue())); 18 | } 19 | queryResult.setHighlightings(highlightings); 20 | }*/ 21 | 22 | queryResult.ScoreExplanations = dupMapStringString(r.ScoreExplanations) 23 | queryResult.TimingsInMs = dupMapStringFloat64(r.TimingsInMs) 24 | return &queryResult 25 | } 26 | -------------------------------------------------------------------------------- /query_result_base.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // queryResultBase represents results of the query returned by the server 4 | // Note: in Java results and includes are templated but 5 | // in practice they are only ever set to: 6 | // TResult = ArrayNode i.e. []map[string]interface{} 7 | // TInclude = ObjectNode i.e. map[string]interface{} 8 | type queryResultBase struct { 9 | Results []map[string]interface{} `json:"Results"` 10 | Includes map[string]interface{} `json:"Includes"` 11 | IncludedPaths []string `json:"IncludedPaths"` 12 | IsStale bool `json:"IsStale"` 13 | IndexTimestamp *Time `json:"IndexTimestamp"` 14 | IndexName string `json:"IndexName"` 15 | ResultEtag int64 `json:"ResultEtag"` 16 | LastQueryTime *Time `json:"LastQueryTime"` 17 | } 18 | -------------------------------------------------------------------------------- /query_statistics.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "time" 4 | 5 | // TODO: is time.Time here our *Time? 6 | // TODO: needs json annotations? 7 | type QueryStatistics struct { 8 | IsStale bool 9 | DurationInMs int64 10 | TotalResults int 11 | SkippedResults int 12 | Timestamp time.Time 13 | IndexName string 14 | IndexTimestamp time.Time 15 | LastQueryTime time.Time 16 | TimingsInMs map[string]float64 17 | ResultEtag int64 // TODO: *int64 ? 18 | ResultSize int64 19 | ScoreExplanations map[string]string 20 | } 21 | 22 | func NewQueryStatistics() *QueryStatistics { 23 | return &QueryStatistics{ 24 | TimingsInMs: make(map[string]float64), 25 | } 26 | } 27 | 28 | func (s *QueryStatistics) UpdateQueryStats(qr *QueryResult) { 29 | s.IsStale = qr.IsStale 30 | s.DurationInMs = qr.DurationInMs 31 | s.TotalResults = qr.TotalResults 32 | s.SkippedResults = qr.SkippedResults 33 | s.Timestamp = qr.IndexTimestamp.toTime() 34 | s.IndexName = qr.IndexName 35 | s.IndexTimestamp = qr.IndexTimestamp.toTime() 36 | s.TimingsInMs = qr.TimingsInMs 37 | s.LastQueryTime = qr.LastQueryTime.toTime() 38 | s.ResultSize = qr.ResultSize 39 | s.ResultEtag = qr.ResultEtag 40 | s.ScoreExplanations = qr.ScoreExplanations 41 | } 42 | -------------------------------------------------------------------------------- /query_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | func isRqlTokenKeyword(s string) bool { 6 | switch s { 7 | case "as", "select", "where", "load", 8 | "group", "order", "include": 9 | return true 10 | } 11 | return false 12 | } 13 | 14 | // In Java QueryToken is a base class that defines virtual writeTo and provides 15 | // writeField. We make writeField a stand-alone helper function and make queryToken 16 | // an interface 17 | type queryToken interface { 18 | writeTo(*strings.Builder) error 19 | } 20 | 21 | func writeQueryTokenField(writer *strings.Builder, field string) { 22 | isKeyWord := isRqlTokenKeyword(field) 23 | if isKeyWord { 24 | writer.WriteString("'") 25 | writer.WriteString(field) 26 | writer.WriteString("'") 27 | return 28 | } 29 | 30 | writer.WriteString(field) 31 | } 32 | 33 | type singleStringToken string 34 | 35 | func (t singleStringToken) writeTo(writer *strings.Builder) error { 36 | writer.WriteString(string(t)) 37 | return nil 38 | } 39 | -------------------------------------------------------------------------------- /raft_id_generator.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "fmt" 5 | "github.com/google/uuid" 6 | ) 7 | 8 | type IRaftCommand interface { 9 | RaftUniqueRequestId() string 10 | } 11 | 12 | type RaftCommandBase struct { 13 | RavenCommandBase 14 | raftUniqueRequestId string 15 | } 16 | 17 | func RaftId() (string, error) { 18 | newUUID, err := uuid.NewUUID() 19 | if err != nil { 20 | return "", err 21 | } 22 | 23 | return fmt.Sprintf("%v", newUUID), nil 24 | } 25 | 26 | func (cmd *RaftCommandBase) RaftUniqueRequestId() (string, error) { 27 | if cmd.raftUniqueRequestId == "" { 28 | newUUID, err := uuid.NewUUID() 29 | if err != nil { 30 | return "", err 31 | } 32 | cmd.raftUniqueRequestId = fmt.Sprintf("%v", newUUID) 33 | } 34 | return cmd.raftUniqueRequestId, nil 35 | } 36 | -------------------------------------------------------------------------------- /range_facet.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var _ FacetBase = &RangeFacet{} 4 | 5 | // RangeFacet describes range facet 6 | type RangeFacet struct { 7 | FacetBaseCommon 8 | 9 | _parent FacetBase 10 | 11 | Ranges []string `json:"Ranges"` 12 | } 13 | 14 | // NewRangeFacet returns new RangeFacet 15 | // parent is optional (can be nil) 16 | func NewRangeFacet(parent FacetBase) *RangeFacet { 17 | return &RangeFacet{ 18 | FacetBaseCommon: NewFacetBaseCommon(), 19 | _parent: parent, 20 | } 21 | } 22 | 23 | // ToFacetToken converts RangeFacet to a token 24 | func (f *RangeFacet) ToFacetToken(addQueryParameter func(interface{}) string) (*facetToken, error) { 25 | if f._parent != nil { 26 | return f._parent.ToFacetToken(addQueryParameter) 27 | } 28 | 29 | return createFacetTokenWithRangeFacet(f, addQueryParameter) 30 | } 31 | -------------------------------------------------------------------------------- /raven_command_response_type.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type RavenCommandResponseType = string 4 | 5 | const ( 6 | RavenCommandResponseTypeEmpty = "EMPTY" 7 | RavenCommandResponseTypeObject = "OBJECT" 8 | RavenCommandResponseTypeRaw = "RAW" 9 | ) 10 | -------------------------------------------------------------------------------- /raven_connection_string.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // RavenConnectionString represents connection string for raven 4 | type RavenConnectionString struct { 5 | ConnectionString 6 | Database string `json:"Database"` 7 | TopologyDiscoveryUrls []string `json:"TopologyDiscoveryUrls"` 8 | } 9 | 10 | func NewRavenConnectionString() *RavenConnectionString { 11 | res := &RavenConnectionString{} 12 | res.Type = ConnectionStringTypeRaven 13 | return res 14 | } 15 | -------------------------------------------------------------------------------- /read_balance_behavior.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // ReadBalanceBehavior defines the type of read balancing 4 | type ReadBalanceBehavior = string 5 | 6 | const ( 7 | ReadBalanceBehaviorNone = "None" 8 | ReadBalanceBehaviorRoundRobin = "RoundRobin" 9 | ReadBalanceBehaviorFastestNode = "FastestNode" 10 | ) 11 | -------------------------------------------------------------------------------- /replication_node.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // ReplicationNode describes replication node 4 | type ReplicationNode struct { 5 | URL string `json:"Url"` 6 | Database string `json:"Database"` 7 | IsDisabled bool `json:"Disabled"` 8 | } 9 | -------------------------------------------------------------------------------- /requests_helpers.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // TODO: on ServerNode implement: 4 | // response_time, ewma(), is_rate_surpassed() 5 | -------------------------------------------------------------------------------- /response_dispose_handling.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type responseDisposeHandling = string 4 | 5 | const ( 6 | responseDisposeHandlingManually = "MANUALLY" 7 | responseDisposeHandlingAutomatic = "AUTOMATIC" 8 | ) 9 | -------------------------------------------------------------------------------- /response_time_information.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "time" 4 | 5 | // ResponseTimeInformation describes timing information of server requests 6 | type ResponseTimeInformation struct { 7 | totalServerDuration time.Duration 8 | totalClientDuration time.Duration 9 | 10 | durationBreakdown []ResponseTimeItem 11 | } 12 | 13 | func (i *ResponseTimeInformation) computeServerTotal() { 14 | var total time.Duration 15 | for _, rti := range i.durationBreakdown { 16 | total += rti.Duration 17 | } 18 | i.totalServerDuration = total 19 | } 20 | 21 | // ResponseTimeItem represents a duration for executing a given url 22 | type ResponseTimeItem struct { 23 | URL string 24 | Duration time.Duration 25 | } 26 | -------------------------------------------------------------------------------- /revision.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // Revision describes a revision 4 | type Revision struct { 5 | Previous interface{} 6 | Current interface{} 7 | } 8 | -------------------------------------------------------------------------------- /revisions_collection_configuration.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // RevisionsCollectionConfiguration describes configuration for revisions collection 4 | type RevisionsCollectionConfiguration struct { 5 | // Note: in java MinimumRevisionsToKeep is Long, which is ref type 6 | // so by default it's not serialized to JSON if not set 7 | // in Go 0 is default so use "omitempty" to achieve the same effect 8 | MinimumRevisionsToKeep int64 `json:"MinimumRevisionsToKeep,omitempty"` 9 | MinimumRevisionAgeToKeep *Duration `json:"MinimumRevisionAgeToKeep"` 10 | Disabled bool `json:"Disabled"` 11 | PurgeOnDelete bool `json:"PurgeOnDelete"` 12 | } 13 | -------------------------------------------------------------------------------- /revisions_configuration.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // RevisionsConfiguration describes revisions configuration 4 | type RevisionsConfiguration struct { 5 | DefaultConfig *RevisionsCollectionConfiguration `json:"Default"` 6 | 7 | Collections map[string]*RevisionsCollectionConfiguration `json:"Collections"` 8 | } 9 | -------------------------------------------------------------------------------- /script_resolver.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // ScriptResolver describes script resolver 4 | type ScriptResolver struct { 5 | Script string `json:"Script"` 6 | LastModifiedTime Time `json:"LastModifiedTime"` 7 | } 8 | -------------------------------------------------------------------------------- /scripts/appveyor_run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -u -o pipefail -o xtrace 3 | 4 | # comment/uncomment to turn additional logging on/off 5 | #export VERBOSE_LOG=true 6 | #export LOG_FAILED_HTTP_REQUESTS=true 7 | #export LOG_ALL_REQUESTS=true 8 | #export LOG_FAILED_HTTP_REQUESTS_DELAYED=true 9 | #export ENABLE_FAILING_TESTS=true 10 | #export ENABLE_FLAKY_TESTS=true 11 | # must use full absolute path because working directory is direrectory of 12 | # ravendb server executable 13 | wd=`pwd` 14 | export RAVENDB_TEST_CERTIFICATE_PATH="${wd}/certs/server.pfx" 15 | export RAVENDB_TEST_CA_PATH="${wd}/certs/ca.crt" 16 | export RAVENDB_TEST_CLIENT_CERTIFICATE_PATH="${wd}/certs/cert.pem" 17 | export RAVENDB_TEST_HTTPS_SERVER_URL="https://a.javatest11.development.run:8085" 18 | #export RAVENDB_SERVER_VERSION="4.1.3" # see appveyor.yml 19 | 20 | #export NODES_IN_CLUSTER="3" 21 | #export KILL_SERVER_CHANCE="10" 22 | #export SHUFFLE_CLUSTER_NODES=true 23 | 24 | echo "pwd: ${wd}" 25 | echo "GOPATH: ${GOPATH}" 26 | 27 | go test -tags for_tests -v -race -parallel 1 -timeout 30m -coverpkg=github.com/ravendb/ravendb-go-client -covermode=atomic -coverprofile=coverage.txt . ./tests 28 | exitCode=$? 29 | 30 | # Note: this doesn't seem to send code coverage so we do it from travis instead 31 | # upload coverage.txt to codecov.io 32 | # bash <(curl -s https://codecov.io/bash) 33 | 34 | zip -r logs.zip logs 35 | appveyor PushArtifact logs.zip 36 | 37 | exit ${exitCode} 38 | -------------------------------------------------------------------------------- /scripts/appveyor_run_tests_win.bat: -------------------------------------------------------------------------------- 1 | @rem default test -timeout is 10m which sometimes is not enough 2 | 3 | go test -tags for_tests -v -parallel 1 -timeout 20m "-coverpkg=github.com/ravendb/ravendb-go-client" -covermode=atomic "-coverprofile=coverage.txt" . ./tests 4 | 5 | set testerrorlevel=%errorlevel% 6 | 7 | 7z a logs.zip logs 8 | appveyor PushArtifact logs.zip 9 | 10 | exit /b %testerrorlevel% 11 | -------------------------------------------------------------------------------- /scripts/compile.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | 3 | # sanity check: make sure that code and tests do compile 4 | # compiling tests will also compile the code 5 | 6 | go test -tags for_tests -v -c ./tests 7 | go test -v -c ./examples 8 | go test -v -c ./dive-into-raven 9 | 10 | -------------------------------------------------------------------------------- /scripts/download_mac_and_unpack_locally.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -u -e -o pipefail 3 | 4 | rm -rf RavenDB.tar.bz2 5 | 6 | wget -O RavenDB.tar.bz2 https://daily-builds.s3.amazonaws.com/RavenDB-4.1.3-osx-x64.tar.bz2 7 | 8 | # TODO: daily seems broken 9 | # wget -O RavenDB.tar.bz2 https://hibernatingrhinos.com/downloads/RavenDB%20for%20OSX/latest?buildType=nightly 10 | 11 | rm -rf ./RavenDB 12 | tar xvjf RavenDB.tar.bz2 13 | -------------------------------------------------------------------------------- /scripts/loc.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | 3 | python scripts\loc.py 4 | -------------------------------------------------------------------------------- /scripts/mkcert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -u -e -o pipefail -o xtrace 3 | 4 | # This script re-generates self-signing certs in certs directory 5 | # run as: ./scripts/mkcert.sh 6 | # The certificate is valid for 1 year (currently till Jan 2020) 7 | # so if https tests start failing, re-run this script to re-generate the cert 8 | 9 | # on mac must use password https://github.com/dotnet/corefx/issues/24225 10 | # password hard-coded here and in NewSecuredServiceLocator() see --Security.Certificate.Password 11 | RAVEN_Security_Certificate_Password=pwd1234 12 | 13 | rm -rf ./certs 14 | mkdir -p ./certs 15 | cd ./certs 16 | 17 | openssl genrsa -out ca.key 2048 18 | 19 | openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=US/ST=Arizona/L=Nevada/O=RavenDB Test CA/OU=RavenDB test CA/CN=a.javatest11.development.run/emailAddress=ravendbca@example.com" 20 | 21 | openssl genrsa -out localhost.key 2048 22 | 23 | openssl req -new -key localhost.key -out localhost.csr -subj "/C=US/ST=Arizona/L=Nevada/O=RavenDB Test/OU=RavenDB test/CN=a.javatest11.development.run/emailAddress=ravendb@example.com" 24 | 25 | openssl x509 -req -days 365 -extensions ext -extfile ../scripts/test_cert.conf -in localhost.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out localhost.crt 26 | 27 | cat localhost.key localhost.crt > cert.pem 28 | 29 | openssl pkcs12 -passout pass:${RAVEN_Security_Certificate_Password} -export -out server.pfx -inkey localhost.key -in localhost.crt 30 | 31 | -------------------------------------------------------------------------------- /scripts/profile.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | # on mac install powershell: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-6 3 | 4 | $Env:VERBOSE_LOG = "true" 5 | $Env:LOG_HTTP_REQUEST_SUMMARY = "true" 6 | $Env:LOG_FAILED_HTTP_REQUESTS = "true" 7 | # logs output of raven server to stdout, helpful for failing tests 8 | #export LOG_RAVEN_SERVER=true 9 | $Env:LOG_ALL_REQUESTS = "true" 10 | $Env:ENABLE_FAILING_TESTS = "false" 11 | $Env:ENABLE_FLAKY_TESTS = "false" 12 | $Env:ENABLE_NORTHWIND_TESTS = "true" 13 | 14 | # for running tests in a cluster, set to NODES_IN_CLUSTER to 3 15 | # and KILL_SERVER_CHANCE to e.g. 10 (10%) and "SHUFFLE_CLUSTER_NODES" to true 16 | $Env:NODES_IN_CLUSTER = "0" 17 | $Env:KILL_SERVER_CHANCE = "0" 18 | $Env:SHUFFLE_CLUSTER_NODES = "false" 19 | 20 | $Env:ENABLE_PROFILING = "true" 21 | 22 | rm ./tests/cpu.prof 23 | go clean -testcache 24 | go test -tags for_tests -v -timeout 80s ./tests -run ^TestAggressiveCaching$ 25 | ls -l ./tests/cpu.prof 26 | -------------------------------------------------------------------------------- /scripts/run_dive_example.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | 3 | Set-Location .\dive-into-raven 4 | go run main.go log.go $args 5 | Set-Location .. 6 | -------------------------------------------------------------------------------- /scripts/run_example.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | 3 | Set-Location .\examples 4 | go run main.go log.go $args 5 | Set-Location .. 6 | -------------------------------------------------------------------------------- /scripts/run_java_tests.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | 3 | $Env:RAVENDB_JAVA_TEST_SERVER_PATH = "$PSScriptRoot\..\RavenDB\Server\Raven.Server.exe" 4 | $Env:HTTP_PROXY = "http://localhost:8888" 5 | 6 | go run .\cmd\run_java_tests\run_java_tests.go 7 | -------------------------------------------------------------------------------- /scripts/run_server_locally.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | # on mac install powershell: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-6 3 | 4 | # --ServerUrl.Tcp=" + tcpServerURL, 5 | 6 | .\RavenDB\Server\Raven.Server.exe --ServerUrl=http://localhost:8080 --RunInMemory=true --License.Eula.Accepted=true --Setup.Mode=None --Features.Availability=Experimental --non-interactive 7 | -------------------------------------------------------------------------------- /scripts/run_server_locally.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # on mac install powershell: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-6 3 | 4 | # --ServerUrl.Tcp=" + tcpServerURL, 5 | 6 | ./RavenDB/Server/Raven.Server --ServerUrl=http://localhost:8080 --RunInMemory=true --License.Eula.Accepted=true --Setup.Mode=None --non-interactive 7 | -------------------------------------------------------------------------------- /scripts/run_single_test_multiple.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | 3 | # on mac install powershell: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-6 4 | 5 | # this runs a single test 10 times (or until first failure). 6 | # helps find flaky tests 7 | 8 | $Env:VERBOSE_LOG = "true" 9 | $Env:LOG_HTTP_REQUEST_SUMMARY = "true" 10 | $Env:LOG_FAILED_HTTP_REQUESTS = "true" 11 | # logs output of raven server to stdout, helpful for failing tests 12 | #export LOG_RAVEN_SERVER=true 13 | $Env:LOG_ALL_REQUESTS = "true" 14 | $Env:ENABLE_FAILING_TESTS = "false" 15 | $Env:ENABLE_FLAKY_TESTS = "false" 16 | $Env:ENABLE_NORTHWIND_TESTS = "true" 17 | 18 | For ($i=0; $i -lt 10; $i++) { 19 | 20 | go clean -testcache 21 | go test -tags for_tests -v -timeout 50s ./tests -run ^TestChanges$ 22 | 23 | if ($lastexitcode -ne 0) { 24 | exit 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /scripts/run_tests.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env pwsh 2 | # on mac install powershell: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-macos?view=powershell-6 3 | 4 | Function FormatElapsedTime($ts) { 5 | $elapsedTime = "" 6 | 7 | if ( $ts.Minutes -gt 0 ) { 8 | $elapsedTime = [string]::Format( "{0:00} min. {1:00}.{2:00} sec.", $ts.Minutes, $ts.Seconds, $ts.Milliseconds / 10 ); 9 | } 10 | else { 11 | $elapsedTime = [string]::Format( "{0:00}.{1:00} sec.", $ts.Seconds, $ts.Milliseconds / 10 ); 12 | } 13 | 14 | if ($ts.Hours -eq 0 -and $ts.Minutes -eq 0 -and $ts.Seconds -eq 0) { 15 | $elapsedTime = [string]::Format("{0:00} ms.", $ts.Milliseconds); 16 | } 17 | 18 | if ($ts.Milliseconds -eq 0) { 19 | $elapsedTime = [string]::Format("{0} ms", $ts.TotalMilliseconds); 20 | } 21 | 22 | return $elapsedTime 23 | } 24 | 25 | $Env:LOG_HTTP_REQUEST_SUMMARY = "true" 26 | $Env:LOG_FAILED_HTTP_REQUESTS = "true" 27 | $Env:LOG_ALL_REQUESTS = "true" 28 | #$Env:ENABLE_FAILING_TESTS = "true" 29 | #$Env:ENABLE_FLAKY_TESTS = "true" 30 | 31 | # go test -tags for_tests -covermode=atomic -coverprofile=coverage.txt 32 | 33 | $sw = [Diagnostics.Stopwatch]::StartNew() 34 | # -parallel 1 to disable parallel execution of tests 35 | go test -tags for_tests -parallel 1 -race -timeout 20m -v ./tests 36 | Start-Sleep -s 3 37 | $sw.Stop() 38 | FormatElapsedTime $sw.Elapsed 39 | -------------------------------------------------------------------------------- /scripts/test_cert.conf: -------------------------------------------------------------------------------- 1 | [req] 2 | distinguished_name = req_distinguished_name 3 | 4 | [req_distinguished_name] 5 | 6 | [ext] 7 | subjectKeyIdentifier = hash 8 | # this seems to break openssl on mac 9 | # authorityKeyIdentifier = keyid:always 10 | keyUsage = digitalSignature,keyEncipherment 11 | extendedKeyUsage=serverAuth,clientAuth 12 | -------------------------------------------------------------------------------- /scripts/travis_run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -u -e -o pipefail -o xtrace 3 | 4 | # comment/uncomment to turn additional logging on/off 5 | export VERBOSE_LOG=true 6 | export LOG_FAILED_HTTP_REQUESTS=true 7 | export LOG_ALL_REQUESTS=true 8 | export LOG_FAILED_HTTP_REQUESTS_DELAYED=true 9 | #export ENABLE_FAILING_TESTS=true 10 | #export ENABLE_FLAKY_TESTS=true 11 | # must use full absolute path because working directory is direrectory of 12 | # ravendb server executable 13 | wd=`pwd` 14 | export RAVENDB_TEST_CERTIFICATE_PATH="${wd}/certs/server.pfx" 15 | export RAVENDB_TEST_CA_PATH="${wd}/certs/ca.crt" 16 | export RAVENDB_TEST_CLIENT_CERTIFICATE_PATH="${wd}/certs/cert.pem" 17 | export RAVENDB_TEST_HTTPS_SERVER_URL="https://a.javatest11.development.run:8085" 18 | export RAVENDB_SERVER_VERSION="5.1.11" # see .travis.yml 19 | 20 | #export NODES_IN_CLUSTER="3" 21 | #export KILL_SERVER_CHANCE="10" 22 | #export SHUFFLE_CLUSTER_NODES=true 23 | 24 | echo "pwd: ${wd}" 25 | echo "GOPATH: ${GOPATH}" 26 | 27 | # compile examples to catch mistakes there 28 | go test -v -c ./examples 29 | 30 | go test -tags for_tests -v -race -parallel 1 -timeout 30m -coverpkg=github.com/ravendb/ravendb-go-client -covermode=atomic -coverprofile=coverage.txt . ./tests 31 | -------------------------------------------------------------------------------- /search_operator.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type SearchOperator int 4 | 5 | const ( 6 | SearchOperatorUnset SearchOperator = iota 7 | SearchOperatorOr 8 | SearchOperatorAnd 9 | ) 10 | -------------------------------------------------------------------------------- /semaphore.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // Semaphore is a Go implementation of Java's Semaphore 4 | type Semaphore struct { 5 | c chan struct{} 6 | } 7 | 8 | func NewSemaphore(cap int) *Semaphore { 9 | return &Semaphore{ 10 | c: make(chan struct{}, cap), 11 | } 12 | } 13 | 14 | func (s *Semaphore) acquire() { 15 | s.c <- struct{}{} 16 | } 17 | 18 | func (s *Semaphore) release() { 19 | <-s.c 20 | } 21 | -------------------------------------------------------------------------------- /server_node.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | const ( 4 | ServerNodeRoleNone = "None" 5 | ServerNodeRolePromotable = "Promotable" 6 | ServerNodeRoleMember = "Member" 7 | ServerNodeRoleRehab = "Rehab" 8 | ) 9 | 10 | // ServerNode describes a single server node 11 | type ServerNode struct { 12 | URL string `json:"Url"` 13 | Database string `json:"Database"` 14 | ClusterTag string `json:"ClusterTag"` 15 | ServerRole string `json:"ServerRole"` 16 | } 17 | 18 | // NewServerNode creates a new ServerNode 19 | func NewServerNode() *ServerNode { 20 | return &ServerNode{ 21 | ServerRole: ServerNodeRoleNone, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /server_wide_operation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // Note: for simplicity, ServerWideOperation is folded into Operation 4 | 5 | func NewServerWideOperation(requestExecutor *RequestExecutor, conventions *DocumentConventions, id int64) *Operation { 6 | res := NewOperation(requestExecutor, nil, conventions, id) 7 | res.IsServerWide = true 8 | return res 9 | } 10 | -------------------------------------------------------------------------------- /serverwide/certificates/certificate_definition.go: -------------------------------------------------------------------------------- 1 | package certificates 2 | 3 | type SecurityClearance int 4 | 5 | const ( 6 | ClusterAdmin SecurityClearance = iota 7 | ClusterNode 8 | Operator 9 | ValidUser 10 | ) 11 | 12 | type DatabaseAccess int 13 | 14 | const ( 15 | ReadWrite DatabaseAccess = iota 16 | Admin 17 | Read 18 | ) 19 | 20 | func (da DatabaseAccess) String() string { 21 | return []string{"ReadWrite", "Admin", "Read"}[da] 22 | } 23 | 24 | func (sa SecurityClearance) String() string { 25 | return []string{"ClusterAdmin", "ClusterNode", "Operator", "ValidUser"}[sa] 26 | } 27 | -------------------------------------------------------------------------------- /serverwide/operations/operation_add_cluster_node.go: -------------------------------------------------------------------------------- 1 | package operations 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "github.com/ravendb/ravendb-go-client" 7 | "net/http" 8 | "net/url" 9 | "strconv" 10 | "strings" 11 | ) 12 | 13 | type OperationAddClusterNode struct { 14 | Url string `json:"Url"` 15 | Tag string `json:"Tag"` 16 | Watcher bool `json:"Watcher"` 17 | } 18 | 19 | func (operation *OperationAddClusterNode) GetCommand(conventions *ravendb.DocumentConventions) (ravendb.RavenCommand, error) { 20 | return &addNodeCommand{ 21 | RaftCommandBase: ravendb.RaftCommandBase{ 22 | RavenCommandBase: ravendb.RavenCommandBase{ 23 | ResponseType: ravendb.RavenCommandResponseTypeObject, 24 | }, 25 | }, 26 | parent: operation, 27 | }, nil 28 | } 29 | 30 | type addNodeCommand struct { 31 | ravendb.RaftCommandBase 32 | parent *OperationAddClusterNode 33 | } 34 | 35 | func (c *addNodeCommand) CreateRequest(node *ravendb.ServerNode) (*http.Request, error) { 36 | url := node.URL + "/admin/cluster/node?url=" + url.QueryEscape(c.parent.Url) + "&watcher=" + strconv.FormatBool(c.parent.Watcher) 37 | 38 | if len(strings.TrimSpace(c.parent.Tag)) == 0 { 39 | url += fmt.Sprintf("&tag=%s", c.parent.Tag) 40 | } 41 | return http.NewRequest(http.MethodPut, url, nil) 42 | } 43 | 44 | func (c *addNodeCommand) SetResponse(response []byte, fromCache bool) error { 45 | return json.Unmarshal(response, c.parent) 46 | } 47 | -------------------------------------------------------------------------------- /serverwide/operations/operation_add_database_to_node.go: -------------------------------------------------------------------------------- 1 | package operations 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/ravendb/ravendb-go-client" 6 | "net/http" 7 | "net/url" 8 | ) 9 | 10 | type OperationAddDatabaseNode struct { 11 | Name string `json:"Name"` 12 | Node string `json:"Node"` 13 | } 14 | 15 | func (operation *OperationAddDatabaseNode) GetCommand(conventions *ravendb.DocumentConventions) (ravendb.RavenCommand, error) { 16 | return &addDatabaseOperation{ 17 | RaftCommandBase: ravendb.RaftCommandBase{ 18 | RavenCommandBase: ravendb.RavenCommandBase{ 19 | ResponseType: ravendb.RavenCommandResponseTypeObject, 20 | }, 21 | }, 22 | parent: operation, 23 | }, nil 24 | } 25 | 26 | type addDatabaseOperation struct { 27 | ravendb.RaftCommandBase 28 | parent *OperationAddDatabaseNode 29 | } 30 | 31 | func (o *addDatabaseOperation) CreateRequest(node *ravendb.ServerNode) (*http.Request, error) { 32 | base, err := url.Parse(node.URL + "/admin/databases/node?name=") 33 | if err != nil { 34 | return nil, err 35 | } 36 | params := url.Values{} 37 | params.Add("name", o.parent.Name) 38 | params.Add("node", o.parent.Node) 39 | base.RawQuery = params.Encode() 40 | 41 | return http.NewRequest(http.MethodPut, base.String(), nil) 42 | } 43 | 44 | func (c *addDatabaseOperation) SetResponse(response []byte, fromCache bool) error { 45 | return json.Unmarshal(response, c.parent) 46 | } 47 | -------------------------------------------------------------------------------- /serverwide/operations/operation_boostrap.go: -------------------------------------------------------------------------------- 1 | package operations 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/ravendb/ravendb-go-client" 6 | "net/http" 7 | ) 8 | 9 | type OperationBootstrap struct { 10 | } 11 | 12 | func (o *OperationBootstrap) GetCommand(conventions *ravendb.DocumentConventions) (ravendb.RavenCommand, error) { 13 | return &bootstrapCommand{ 14 | RaftCommandBase: ravendb.RaftCommandBase{ 15 | RavenCommandBase: ravendb.RavenCommandBase{ 16 | ResponseType: ravendb.RavenCommandResponseTypeObject, 17 | }, 18 | }, 19 | parent: o, 20 | }, nil 21 | } 22 | 23 | type bootstrapCommand struct { 24 | ravendb.RaftCommandBase 25 | parent *OperationBootstrap 26 | } 27 | 28 | func (c *bootstrapCommand) CreateRequest(node *ravendb.ServerNode) (*http.Request, error) { 29 | url := node.URL + "/admin/cluster/bootstrap" 30 | return ravendb.NewHttpPost(url, []byte{}) 31 | } 32 | 33 | func (c *bootstrapCommand) SetResponse(response []byte, fromCache bool) error { 34 | return json.Unmarshal(response, c.parent) 35 | } 36 | -------------------------------------------------------------------------------- /serverwide/operations/operation_database_health_check.go: -------------------------------------------------------------------------------- 1 | package operations 2 | 3 | import ( 4 | "github.com/ravendb/ravendb-go-client" 5 | "net/http" 6 | ) 7 | 8 | type OperationDatabaseHealthCheck struct {} 9 | 10 | func (operation * OperationDatabaseHealthCheck) GetCommand(conventions *ravendb.DocumentConventions) (ravendb.RavenCommand, error) { 11 | return &getDatabaseHealthCheckOperation{ 12 | RavenCommandBase: ravendb.RavenCommandBase{ 13 | ResponseType: ravendb.RavenCommandResponseTypeEmpty, 14 | }, 15 | }, nil 16 | } 17 | 18 | type getDatabaseHealthCheckOperation struct { 19 | ravendb.RavenCommandBase 20 | } 21 | 22 | func (c *getDatabaseHealthCheckOperation) CreateRequest(node *ravendb.ServerNode) (*http.Request, error) { 23 | url := node.URL + "/databases/" + node.Database + "/healthcheck" 24 | return http.NewRequest(http.MethodGet, url, nil) 25 | } 26 | func (c *getDatabaseHealthCheckOperation) SetResponse(response []byte, fromCache bool) error { 27 | return nil 28 | } 29 | -------------------------------------------------------------------------------- /serverwide/operations/operation_demote_cluster_node.go: -------------------------------------------------------------------------------- 1 | package operations 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/ravendb/ravendb-go-client" 6 | "net/http" 7 | ) 8 | 9 | type OperationDemoteClusterNode struct { 10 | Node string `json:"Node"` 11 | } 12 | 13 | func (operation *OperationDemoteClusterNode) GetCommand(conventions *ravendb.DocumentConventions) (ravendb.RavenCommand, error) { 14 | return &demoteNodeCommand{ 15 | RaftCommandBase: ravendb.RaftCommandBase{ 16 | RavenCommandBase: ravendb.RavenCommandBase{ 17 | ResponseType: ravendb.RavenCommandResponseTypeObject, 18 | }, 19 | }, 20 | parent: operation, 21 | }, nil 22 | } 23 | 24 | type demoteNodeCommand struct { 25 | ravendb.RaftCommandBase 26 | parent *OperationDemoteClusterNode 27 | } 28 | 29 | func (c *demoteNodeCommand) CreateRequest(node *ravendb.ServerNode) (*http.Request, error) { 30 | url := node.URL + "/admin/cluster/demote?nodeTag=" + c.parent.Node 31 | return http.NewRequest(http.MethodPost, url, nil) 32 | } 33 | 34 | func (c *demoteNodeCommand) SetResponse(response []byte, fromCache bool) error { 35 | return json.Unmarshal(response, c.parent) 36 | } 37 | -------------------------------------------------------------------------------- /serverwide/operations/operation_get_build_number.go: -------------------------------------------------------------------------------- 1 | package operations 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/ravendb/ravendb-go-client" 6 | "net/http" 7 | ) 8 | 9 | type OperationGetBuildNumber struct { 10 | BuildVersion int `json:"BuildVersion"` 11 | ProductVersion string `json:"ProductVersion"` 12 | CommitHash string `json:"CommitHash"` 13 | FullVersion string `json:"FullVersion"` 14 | } 15 | 16 | func (operation *OperationGetBuildNumber) GetCommand(conventions *ravendb.DocumentConventions) (ravendb.RavenCommand, error) { 17 | return &getBuildNumber{ 18 | RavenCommandBase: ravendb.RavenCommandBase{ 19 | ResponseType: ravendb.RavenCommandResponseTypeObject, 20 | }, 21 | parent: operation, 22 | }, nil 23 | } 24 | 25 | type getBuildNumber struct { 26 | ravendb.RavenCommandBase 27 | parent *OperationGetBuildNumber 28 | } 29 | 30 | func (c *getBuildNumber) CreateRequest(node *ravendb.ServerNode) (*http.Request, error) { 31 | url := node.URL + "/build/version" 32 | return http.NewRequest(http.MethodGet, url, nil) 33 | } 34 | 35 | func (c *getBuildNumber) SetResponse(response []byte, fromCache bool) error { 36 | return json.Unmarshal(response, c.parent) 37 | } 38 | -------------------------------------------------------------------------------- /serverwide/operations/operation_promote_cluster_node.go: -------------------------------------------------------------------------------- 1 | package operations 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/ravendb/ravendb-go-client" 6 | "net/http" 7 | ) 8 | 9 | type OperationPromoteClusterNode struct { 10 | Node string `json:"Node"` 11 | } 12 | 13 | func NewOperationPromoteClusterNode(node string) *OperationPromoteClusterNode { 14 | return &OperationPromoteClusterNode{ 15 | Node: node, 16 | } 17 | } 18 | func (operation *OperationPromoteClusterNode) GetCommand(conventions *ravendb.DocumentConventions) (ravendb.RavenCommand, error) { 19 | return &promoteNodeCommand{ 20 | RaftCommandBase: ravendb.RaftCommandBase{ 21 | RavenCommandBase: ravendb.RavenCommandBase{ 22 | ResponseType: ravendb.RavenCommandResponseTypeObject, 23 | }, 24 | }, 25 | parent: operation, 26 | }, nil 27 | } 28 | 29 | type promoteNodeCommand struct { 30 | ravendb.RaftCommandBase 31 | parent *OperationPromoteClusterNode 32 | } 33 | 34 | func (c *promoteNodeCommand) CreateRequest(node *ravendb.ServerNode) (*http.Request, error) { 35 | url := node.URL + "/admin/cluster/promote?nodeTag=" + c.parent.Node 36 | return http.NewRequest(http.MethodPost, url, nil) 37 | } 38 | 39 | func (c *promoteNodeCommand) SetResponse(response []byte, fromCache bool) error { 40 | return json.Unmarshal(response, c.parent) 41 | } 42 | -------------------------------------------------------------------------------- /serverwide/operations/operation_remove_cluster_node.go: -------------------------------------------------------------------------------- 1 | package operations 2 | 3 | import ( 4 | "encoding/json" 5 | "github.com/ravendb/ravendb-go-client" 6 | "net/http" 7 | ) 8 | 9 | type RemoveClusterNode struct { 10 | Node string `json:"Node"` 11 | Tag string `json:"Tag"` 12 | } 13 | 14 | func NewRemovePromoteClusterNode(node string) *OperationPromoteClusterNode { 15 | return &OperationPromoteClusterNode{ 16 | Node: node, 17 | } 18 | } 19 | 20 | func (operation *RemoveClusterNode) GetCommand(conventions *ravendb.DocumentConventions) (ravendb.RavenCommand, error) { 21 | return &removeNodeCommand{ 22 | RaftCommandBase: ravendb.RaftCommandBase{ 23 | RavenCommandBase: ravendb.RavenCommandBase{ 24 | ResponseType: ravendb.RavenCommandResponseTypeObject, 25 | }, 26 | }, 27 | parent: operation, 28 | }, nil 29 | } 30 | 31 | type removeNodeCommand struct { 32 | ravendb.RaftCommandBase 33 | parent *RemoveClusterNode 34 | } 35 | 36 | func (c *removeNodeCommand) CreateRequest(node *ravendb.ServerNode) (*http.Request, error) { 37 | url := node.URL + "/admin/cluster/node?nodeTag=" + c.parent.Tag 38 | return http.NewRequest(http.MethodDelete, url, nil) 39 | } 40 | func (c *removeNodeCommand) SetResponse(response []byte, fromCache bool) error { 41 | return json.Unmarshal(response, c.parent) 42 | } 43 | -------------------------------------------------------------------------------- /session_created_event_args.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SessionCreatedEventArgs represents session created event args 4 | type SessionCreatedEventArgs struct { 5 | Session *InMemoryDocumentSessionOperations 6 | } 7 | -------------------------------------------------------------------------------- /session_info.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SessionInfo describes a session 4 | type SessionInfo struct { 5 | SessionID int 6 | lastClusterTransactionIndex *int64 7 | } 8 | -------------------------------------------------------------------------------- /session_options.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SessionOptions describes session options 4 | type SessionOptions struct { 5 | Database string 6 | RequestExecutor *RequestExecutor 7 | TransactionMode int 8 | DisableAtomicDocumentWritesInClusterWideTransaction *bool 9 | } 10 | 11 | func assertTransactionMode(transactionMode int) error { 12 | if transactionMode == TransactionMode_SingleNode || transactionMode == TransactionMode_ClusterWide { 13 | return nil 14 | } 15 | 16 | return newIllegalStateError("transactionMode has to be set as `TransactionMode_SingleNode` or 'TransactionMode_ClusterWide`.") 17 | } 18 | -------------------------------------------------------------------------------- /shape_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &shapeToken{} 6 | 7 | type shapeToken struct { 8 | shape string 9 | } 10 | 11 | func shapeTokenCircle(radiusParameterName string, latitudeParameterName string, longitudeParameterName string, radiusUnits SpatialUnits) *shapeToken { 12 | if radiusUnits == "" { 13 | shape := "spatial.circle($" + radiusParameterName + ", $" + latitudeParameterName + ", $" + longitudeParameterName + ")" 14 | return &shapeToken{shape: shape} 15 | } 16 | 17 | if radiusUnits == SpatialUnitsKilometers { 18 | shape := "spatial.circle($" + radiusParameterName + ", $" + latitudeParameterName + ", $" + longitudeParameterName + ", 'Kilometers')" 19 | return &shapeToken{shape: shape} 20 | } 21 | shape := "spatial.circle($" + radiusParameterName + ", $" + latitudeParameterName + ", $" + longitudeParameterName + ", 'Miles')" 22 | return &shapeToken{shape: shape} 23 | } 24 | 25 | func shapeTokenWkt(shapeWktParameterName string) *shapeToken { 26 | shape := "spatial.wkt($" + shapeWktParameterName + ")" 27 | return &shapeToken{shape: shape} 28 | } 29 | 30 | func (t *shapeToken) writeTo(writer *strings.Builder) error { 31 | writer.WriteString(t.shape) 32 | return nil 33 | } 34 | -------------------------------------------------------------------------------- /size.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // Size describes size of entity on disk 4 | type Size struct { 5 | SizeInBytes int64 `json:"SizeInBytes"` 6 | HumaneSize string `json:"HumaneSize"` 7 | } 8 | -------------------------------------------------------------------------------- /spatial_field_type.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SpatialFieldType describe spatial field 4 | type SpatialFieldType = string 5 | 6 | const ( 7 | SpatialFieldGeography = "Geography" 8 | SpatialFieldCartesian = "Cartesian" 9 | ) 10 | -------------------------------------------------------------------------------- /spatial_options.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | const ( 4 | //about 4.78 meters at equator, should be good enough (see: http://unterbahn.com/2009/11/metric-dimensions-of-geohash-partitions-at-the-equator/) 5 | SpatialOptionsDefaultGeohashLevel = 9 6 | //about 4.78 meters at equator, should be good enough 7 | SpatialOptionsDefaultQuadTreeLevel = 23 8 | ) 9 | 10 | /// SpatialOptions describes spatial options 11 | type SpatialOptions struct { 12 | Type SpatialFieldType `json:"Type"` 13 | Strategy SpatialSearchStrategy `json:"Strategy"` 14 | MaxTreeLevel int `json:"MaxTreeLevel"` 15 | MinX float64 `json:"MinX"` 16 | MaxX float64 `json:"MaxX"` 17 | MinY float64 `json:"MinY"` 18 | MaxY float64 `json:"MaxY"` 19 | 20 | // Circle radius units, only used for geography indexes 21 | Units SpatialUnits `json:"Units"` 22 | } 23 | 24 | // NewSpatialOptions returns new SpatialOptions with default values 25 | func NewSpatialOptions() *SpatialOptions { 26 | return &SpatialOptions{ 27 | Type: SpatialFieldGeography, 28 | Strategy: SpatialSearchStrategyGeohashPrefixTree, 29 | MaxTreeLevel: SpatialOptionsDefaultGeohashLevel, 30 | MinX: -180, 31 | MaxX: 180, 32 | MinY: -90, 33 | MaxY: 90, 34 | Units: SpatialUnitsKilometers, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /spatial_relation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type SpatialRelation = string 4 | 5 | const ( 6 | SpatialRelationWithin = "Within" 7 | SpatialRelationContains = "Contains" 8 | SpatialRelationDisjoin = "Disjoint" 9 | SpatialRelationIntersects = "Intersects" 10 | ) 11 | -------------------------------------------------------------------------------- /spatial_search_strategy.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SpatialSearchStrategy represents spatial search strategy 4 | type SpatialSearchStrategy = string 5 | 6 | const ( 7 | SpatialSearchStrategyGeohashPrefixTree = "GeohashPrefixTree" 8 | SpatialSearchStrategyQuadPrefixTree = "QuadPrefixTree" 9 | SpatialSearchStrategyBoundingBox = "BoundingBox" 10 | ) 11 | -------------------------------------------------------------------------------- /spatial_units.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SpatialUnits describes units used for spatial queries 4 | type SpatialUnits = string 5 | 6 | const ( 7 | SpatialUnitsKilometers = "Kilometers" 8 | SpatialUnitsMiles = "Miles" 9 | ) 10 | -------------------------------------------------------------------------------- /start_indexing_operation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var _ IVoidMaintenanceOperation = &StartIndexingOperation{} 8 | 9 | type StartIndexingOperation struct { 10 | Command *StartIndexingCommand 11 | } 12 | 13 | func NewStartIndexingOperation() *StartIndexingOperation { 14 | return &StartIndexingOperation{} 15 | } 16 | 17 | func (o *StartIndexingOperation) GetCommand(conventions *DocumentConventions) (RavenCommand, error) { 18 | o.Command = NewStartIndexingCommand() 19 | return o.Command, nil 20 | } 21 | 22 | var ( 23 | _ RavenCommand = &StartIndexingCommand{} 24 | ) 25 | 26 | type StartIndexingCommand struct { 27 | RavenCommandBase 28 | } 29 | 30 | func NewStartIndexingCommand() *StartIndexingCommand { 31 | cmd := &StartIndexingCommand{ 32 | RavenCommandBase: NewRavenCommandBase(), 33 | } 34 | cmd.ResponseType = RavenCommandResponseTypeEmpty 35 | return cmd 36 | } 37 | 38 | func (c *StartIndexingCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 39 | url := node.URL + "/databases/" + node.Database + "/admin/indexes/start" 40 | 41 | return NewHttpPost(url, nil) 42 | } 43 | -------------------------------------------------------------------------------- /starts_with_args.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // StartsWithArgs contains arguments for functions that return documents 4 | // matching one or more options. 5 | // StartsWith is required, other fields are optional. 6 | type StartsWithArgs struct { 7 | StartsWith string // TODO: Prefix? 8 | Matches string 9 | Start int 10 | PageSize int 11 | StartAfter string 12 | 13 | Exclude string 14 | } 15 | -------------------------------------------------------------------------------- /stop_indexing_operation.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var _ IVoidMaintenanceOperation = &StopIndexingOperation{} 8 | 9 | type StopIndexingOperation struct { 10 | Command *StopIndexingCommand 11 | } 12 | 13 | func NewStopIndexingOperation() *StopIndexingOperation { 14 | return &StopIndexingOperation{} 15 | } 16 | 17 | func (o *StopIndexingOperation) GetCommand(conventions *DocumentConventions) (RavenCommand, error) { 18 | o.Command = NewStopIndexingCommand() 19 | return o.Command, nil 20 | } 21 | 22 | var ( 23 | _ RavenCommand = &StopIndexingCommand{} 24 | ) 25 | 26 | type StopIndexingCommand struct { 27 | RavenCommandBase 28 | } 29 | 30 | func NewStopIndexingCommand() *StopIndexingCommand { 31 | cmd := &StopIndexingCommand{ 32 | RavenCommandBase: NewRavenCommandBase(), 33 | } 34 | cmd.ResponseType = RavenCommandResponseTypeEmpty 35 | return cmd 36 | } 37 | 38 | func (c *StopIndexingCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 39 | url := node.URL + "/databases/" + node.Database + "/admin/indexes/stop" 40 | 41 | return NewHttpPost(url, nil) 42 | } 43 | -------------------------------------------------------------------------------- /stream_command.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "net/http" 5 | ) 6 | 7 | var ( 8 | _ RavenCommand = &StreamCommand{} 9 | ) 10 | 11 | type StreamCommand struct { 12 | RavenCommandBase 13 | 14 | _url string 15 | 16 | Result *StreamResultResponse 17 | } 18 | 19 | func NewStreamCommand(url string) *StreamCommand { 20 | // TODO: validate url 21 | cmd := &StreamCommand{ 22 | RavenCommandBase: NewRavenCommandBase(), 23 | 24 | _url: url, 25 | } 26 | cmd.IsReadRequest = true 27 | return cmd 28 | } 29 | 30 | func (c *StreamCommand) CreateRequest(node *ServerNode) (*http.Request, error) { 31 | url := node.URL + "/databases/" + node.Database + "/" + c._url 32 | return newHttpGet(url) 33 | } 34 | 35 | func (c *StreamCommand) processResponse(cache *httpCache, response *http.Response, url string) (responseDisposeHandling, error) { 36 | 37 | // TODO: return an error if response.Body is nil 38 | streamResponse := &StreamResultResponse{ 39 | Response: response, 40 | Stream: response.Body, 41 | } 42 | c.Result = streamResponse 43 | 44 | return responseDisposeHandlingManually, nil 45 | } 46 | -------------------------------------------------------------------------------- /stream_query_statistics.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "time" 4 | 5 | type StreamQueryStatistics struct { 6 | IndexName string `json:"IndexName"` 7 | IsStale bool `json:"IsStale"` 8 | IndexTimestamp time.Time `json:"IndexTimestamp"` 9 | TotalResults int `json:"TotalResults"` 10 | ResultEtag int64 `json:"ResultEtag"` 11 | } 12 | -------------------------------------------------------------------------------- /stream_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // StreamResult represents result of stream iterator 4 | type StreamResult struct { 5 | ID string 6 | ChangeVector *string 7 | Metadata *MetadataAsDictionary 8 | Document interface{} 9 | } 10 | -------------------------------------------------------------------------------- /stream_result_response.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | ) 7 | 8 | type StreamResultResponse struct { 9 | Response *http.Response `json:"Response"` 10 | Stream io.Reader `json:"Stream"` 11 | } 12 | -------------------------------------------------------------------------------- /string_distance_types.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type StringDistanceTypes = string 4 | 5 | const ( 6 | StringDistanceNone = "None" 7 | StringDistanceDefault = "Default" 8 | StringDistanceLevenshtein = "Levenshtein" 9 | StringDistanceJaroWinkler = "JaroWinkler" 10 | StringDistanceNGram = "NGram" 11 | ) 12 | -------------------------------------------------------------------------------- /string_utils.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "unicode" 4 | 5 | // Go port of org.apache.commons.lang3.StringUtils 6 | 7 | // TODO: replace with direct code 8 | func stringIsEmpty(s string) bool { 9 | return s == "" 10 | } 11 | 12 | // TODO: replace with direct code 13 | func stringIsNotEmpty(s string) bool { 14 | return s != "" 15 | } 16 | 17 | func stringIsWhitespace(s string) bool { 18 | for _, c := range s { 19 | if !unicode.IsSpace(c) { 20 | return false 21 | } 22 | } 23 | return true 24 | } 25 | 26 | func stringIsBlank(s string) bool { 27 | for _, c := range s { 28 | if c != ' ' { 29 | return false 30 | } 31 | } 32 | return true 33 | } 34 | 35 | func stringIsNotBlank(s string) bool { 36 | return !stringIsBlank(s) 37 | } 38 | -------------------------------------------------------------------------------- /subscription_connection_client_message.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SubscriptionClientMessageType describes type of subscription client message 4 | type SubscriptionClientMessageType = string 5 | 6 | const ( 7 | SubscriptionClientMessageNone = "None" 8 | SubscriptionClientMessageAcknowledge = "Acknowledge" 9 | SubscriptionClientMessageDisposedNotification = "DisposedNotification" 10 | ) 11 | 12 | // SubscriptionConnectionClientMessage describes a subscription connection message 13 | type SubscriptionConnectionClientMessage struct { 14 | Type SubscriptionClientMessageType `json:"Type"` 15 | ChangeVector *string `json:"ChangeVector"` 16 | } 17 | -------------------------------------------------------------------------------- /subscription_creation_options.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SubscriptionCreationOptions describes options for creating a subscription 4 | type SubscriptionCreationOptions struct { 5 | // must omitempty Name or else the server will try to find a subscription 6 | // with empty name 7 | Name string `json:"Name,omitempty"` 8 | Query string `json:"Query"` 9 | ChangeVector *string `json:"ChangeVector"` 10 | MentorNode string `json:"MentorNode,omitempty"` 11 | } 12 | -------------------------------------------------------------------------------- /subscription_opening_strategy.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SubscriptionOpeningStrategy describes opening strategy for subscriptions 4 | type SubscriptionOpeningStrategy = string 5 | 6 | const ( 7 | // SubscriptionOpeningStrategyOpenIfFree: 8 | // The client will successfully open a subscription only if there isn't any other currently connected client. 9 | // Otherwise it will end up with SubscriptionInUseError 10 | SubscriptionOpeningStrategyOpenIfFree = "OpenIfFree" 11 | // SubscriptionOpeningStrategyTakeOver: 12 | // The connecting client will successfully open a subscription even if there is another active subscription's consumer. 13 | // If the new client takes over an existing client then the existing one will get a SubscriptionInUseException. 14 | // 15 | // The subscription will always be held by the last connected client. 16 | SubscriptionOpeningStrategyTakeOver = "TakeOver" 17 | // SubscriptionOpeningStrategyWaitForFree: 18 | // If the client currently cannot open the subscription because it is used by another client but it will wait for that client 19 | // to complete and keep attempting to gain the subscription 20 | SubscriptionOpeningStrategyWaitForFree = "WaitForFree" 21 | ) 22 | -------------------------------------------------------------------------------- /subscription_state.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SubscriptionState describes state of subscription 4 | type SubscriptionState struct { 5 | Query string `json:"Query"` 6 | ChangeVectorForNextBatchStartingPoint *string `json:"ChangeVectorForNextBatchStartingPoint"` 7 | SubscriptionID int64 `json:"SubscriptionId"` 8 | SubscriptionName string `json:"SubscriptionName"` 9 | MentorNode string `json:"MentorNode"` 10 | NodeTag string `json:"NodeTag"` 11 | LastBatchAckTime Time `json:"LastBatchAckTime"` 12 | LastClientConnectionTime Time `json:"LastClientConnectionTime"` 13 | Disabled bool `json:"Disabled"` 14 | } 15 | -------------------------------------------------------------------------------- /subscription_state_with_node_details.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SubscriptionStateWithNodeDetails describes subscription state with node details 4 | type SubscriptionStateWithNodeDetails struct { 5 | SubscriptionState 6 | ResponsibleNode NodeID 7 | } 8 | -------------------------------------------------------------------------------- /subscription_tryout.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SubscriptionTryout describes subscription tryout 4 | type SubscriptionTryout struct { 5 | changeVector *string 6 | query string 7 | } 8 | -------------------------------------------------------------------------------- /subscription_worker_options.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "time" 4 | 5 | // SubscriptionWorkerOptions describes options for subscription worker 6 | type SubscriptionWorkerOptions struct { 7 | SubscriptionName string `json:"SubscriptionName"` 8 | TimeToWaitBeforeConnectionRetry Duration `json:"TimeToWaitBeforeConnectionRetry"` 9 | IgnoreSubscriberErrors bool `json:"IgnoreSubscriberErrors"` 10 | Strategy SubscriptionOpeningStrategy `json:"Strategy"` 11 | MaxDocsPerBatch int `json:"MaxDocsPerBatch"` 12 | MaxErroneousPeriod Duration `json:"MaxErroneousPeriod"` 13 | CloseWhenNoDocsLeft bool `json:"CloseWhenNoDocsLeft"` 14 | } 15 | 16 | // NewSubscriptionWorkerOptions returns new SubscriptionWorkerOptions 17 | func NewSubscriptionWorkerOptions(subscriptionName string) *SubscriptionWorkerOptions { 18 | panicIf(subscriptionName == "", "SubscriptionName cannot be null or empty") 19 | return &SubscriptionWorkerOptions{ 20 | Strategy: SubscriptionOpeningStrategyOpenIfFree, 21 | MaxDocsPerBatch: 4096, 22 | TimeToWaitBeforeConnectionRetry: Duration(time.Second * 5), 23 | MaxErroneousPeriod: Duration(time.Minute * 5), 24 | SubscriptionName: subscriptionName, 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /suggest_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &suggestToken{} 6 | 7 | type suggestToken struct { 8 | fieldName string 9 | termParameterName string 10 | optionsParameterName string 11 | } 12 | 13 | func (t *suggestToken) writeTo(writer *strings.Builder) error { 14 | writer.WriteString("suggest(") 15 | writer.WriteString(t.fieldName) 16 | writer.WriteString(", $") 17 | writer.WriteString(t.termParameterName) 18 | 19 | if t.optionsParameterName != "" { 20 | writer.WriteString(", $") 21 | writer.WriteString(t.optionsParameterName) 22 | } 23 | 24 | writer.WriteString(")") 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /suggestion_base.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // for documentation purposes only 4 | // TODO: could be simplified. We really only need SuggestionWithTerms, which is a superset 5 | // of SuggestionWithTerm 6 | type SuggestionBase interface { 7 | SetOptions(*SuggestionOptions) 8 | } 9 | 10 | type SuggestionCommon struct { 11 | Field string 12 | Options *SuggestionOptions 13 | } 14 | 15 | func (s *SuggestionCommon) SetOptions(options *SuggestionOptions) { 16 | s.Options = options 17 | } 18 | -------------------------------------------------------------------------------- /suggestion_builder.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SuggestionsBuilder helps to build argument to SuggestUsing 4 | type SuggestionBuilder struct { 5 | term *SuggestionWithTerm 6 | terms *SuggestionWithTerms 7 | } 8 | 9 | func NewSuggestionBuilder() *SuggestionBuilder { 10 | return &SuggestionBuilder{} 11 | } 12 | 13 | func (b *SuggestionBuilder) ByField(fieldName string, term string, terms ...string) *SuggestionBuilder { 14 | panicIf(fieldName == "", "fieldName cannot be empty") 15 | panicIf(term == "", "term cannot be empty") 16 | if len(terms) > 0 { 17 | b.terms = NewSuggestionWithTerms(fieldName) 18 | b.terms.Terms = append([]string{term}, terms...) 19 | } else { 20 | b.term = NewSuggestionWithTerm(fieldName) 21 | b.term.Term = term 22 | } 23 | return b 24 | } 25 | 26 | func (b *SuggestionBuilder) GetSuggestion() SuggestionBase { 27 | if b.term != nil { 28 | return b.term 29 | } 30 | 31 | return b.terms 32 | } 33 | 34 | func (b *SuggestionBuilder) WithOptions(options *SuggestionOptions) *SuggestionBuilder { 35 | b.GetSuggestion().SetOptions(options) 36 | 37 | return b 38 | } 39 | -------------------------------------------------------------------------------- /suggestion_options.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var ( 4 | SuggestionOptionsDefaultOptions = NewSuggestionOptions() 5 | SuggestionOptionsDefaultAccuracy = float32(0.5) 6 | SuggestionOptionsDefaultPageSize = 15 7 | SuggestionOptionsDefaultDistance = StringDistanceLevenshtein 8 | SuggestionOptionsDefaultSortMode = SuggestionSortModePopularity 9 | ) 10 | 11 | type SuggestionOptions struct { 12 | PageSize int 13 | 14 | Distance StringDistanceTypes 15 | 16 | Accuracy float32 17 | 18 | SortMode SuggestionSortMode 19 | } 20 | 21 | func NewSuggestionOptions() *SuggestionOptions { 22 | return &SuggestionOptions{ 23 | SortMode: SuggestionOptionsDefaultSortMode, 24 | Distance: SuggestionOptionsDefaultDistance, 25 | Accuracy: SuggestionOptionsDefaultAccuracy, 26 | PageSize: SuggestionOptionsDefaultPageSize, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /suggestion_query_base.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // SuggestionQueryBase is folded into SuggestionDocumentQuery 4 | -------------------------------------------------------------------------------- /suggestion_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type SuggestionResult struct { 4 | Name string `json:"Name"` 5 | Suggestions []string `json:"Suggestions"` 6 | } 7 | -------------------------------------------------------------------------------- /suggestion_sort_mode.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type SuggestionSortMode = string 4 | 5 | const ( 6 | SuggestionSortModeNone = "None" 7 | SuggestionSortModePopularity = "Popularity" 8 | ) 9 | -------------------------------------------------------------------------------- /suggestion_with_term.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var _ SuggestionBase = &SuggestionWithTerm{} 4 | 5 | type SuggestionWithTerm struct { 6 | SuggestionCommon 7 | Term string 8 | } 9 | 10 | func NewSuggestionWithTerm(field string) *SuggestionWithTerm { 11 | res := &SuggestionWithTerm{} 12 | res.Field = field 13 | return res 14 | } 15 | -------------------------------------------------------------------------------- /suggestion_with_terms.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var _ SuggestionBase = &SuggestionWithTerms{} 4 | 5 | type SuggestionWithTerms struct { 6 | SuggestionCommon 7 | Terms []string 8 | } 9 | 10 | func NewSuggestionWithTerms(field string) *SuggestionWithTerms { 11 | res := &SuggestionWithTerms{} 12 | res.Field = field 13 | return res 14 | } 15 | -------------------------------------------------------------------------------- /tcp_connection_header_response.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type tcpConnectionHeaderResponse struct { 4 | Status tcpConnectionStatus `json:"Status"` 5 | Message string `json:"Message"` 6 | Version int `json:"Version"` 7 | } 8 | -------------------------------------------------------------------------------- /tcp_connection_info.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // TcpConnectionInfo describes tpc connection 4 | type TcpConnectionInfo struct { 5 | Port int `json:"Port"` 6 | URL string `json:"Url"` 7 | Certificate *string `json:"Certificate"` 8 | } 9 | -------------------------------------------------------------------------------- /tcp_connection_status.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type tcpConnectionStatus = string 4 | 5 | const ( 6 | tcpConnectionStatusOk = "Ok" 7 | tcpConnectionStatusAuthorizationFailed = "AuthorizationFailed" 8 | tcpConnectionStatusTcpVersionMismatch = "TcpVersionMismatch" 9 | ) 10 | -------------------------------------------------------------------------------- /tcp_negotiate_parameters.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type tcpNegotiateParameters struct { 4 | operation operationTypes 5 | version int 6 | database string 7 | sourceNodeTag string 8 | destinationNodeTag string 9 | destinationUrl string 10 | 11 | readResponseAndGetVersionCallback func(string) int 12 | } 13 | -------------------------------------------------------------------------------- /terms_query_result.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // TermsQueryResult represents results of terms query 4 | type TermsQueryResult struct { 5 | Terms []string `json:"Terms"` 6 | ResultEtag int64 `json:"ResultEtag"` 7 | IndexName string `json:"IndexName"` 8 | } 9 | -------------------------------------------------------------------------------- /tests/address_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | type Address struct { 4 | ID string 5 | Country string `json:"country"` 6 | City string `json:"city"` 7 | Street string `json:"street"` 8 | ZipCode int `json:"zipCode"` 9 | } 10 | -------------------------------------------------------------------------------- /tests/capturing_cread_closer_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | ) 7 | 8 | // CapturingReadCloser is a reader that captures data that was read from 9 | // underlying reader 10 | type CapturingReadCloser struct { 11 | tee io.Reader 12 | orig io.ReadCloser 13 | capturedData bytes.Buffer 14 | wasClosed bool 15 | } 16 | 17 | // Read reads data from reader 18 | func (rc *CapturingReadCloser) Read(p []byte) (int, error) { 19 | panicIf(rc.wasClosed, "reading after being closed") 20 | return rc.tee.Read(p) 21 | } 22 | 23 | // Close closes a reader 24 | func (rc *CapturingReadCloser) Close() error { 25 | rc.wasClosed = true 26 | return rc.orig.Close() 27 | } 28 | 29 | // NewCapturingReadCloser returns a new capturing reader 30 | func NewCapturingReadCloser(orig io.ReadCloser) *CapturingReadCloser { 31 | res := &CapturingReadCloser{ 32 | orig: orig, 33 | } 34 | res.tee = io.TeeReader(orig, &res.capturedData) 35 | return res 36 | } 37 | -------------------------------------------------------------------------------- /tests/cert/test_cert.conf: -------------------------------------------------------------------------------- 1 | [req] 2 | distinguished_name = req_distinguished_name 3 | 4 | [req_distinguished_name] 5 | 6 | [ext] 7 | subjectKeyIdentifier = hash 8 | authorityKeyIdentifier = keyid:always 9 | keyUsage = digitalSignature,keyEncipherment 10 | extendedKeyUsage=serverAuth,clientAuth -------------------------------------------------------------------------------- /tests/company_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | type Company struct { 4 | AccountsReceivable float64 5 | ID string 6 | Name string 7 | Desc string 8 | Email string 9 | Address1 string 10 | Address2 string 11 | Address3 string 12 | Contacts []*Contact 13 | Phone int 14 | Type CompanyType 15 | EmployeesIds []string 16 | } 17 | -------------------------------------------------------------------------------- /tests/company_type_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | type CompanyType string 4 | 5 | const ( 6 | CompanyType_PUBLIC = "public" 7 | CompanyType_PRIVATE = "private" 8 | ) 9 | -------------------------------------------------------------------------------- /tests/contact_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | type Contact struct { 4 | ID string 5 | FirstName string 6 | Surname string 7 | Email string 8 | } 9 | -------------------------------------------------------------------------------- /tests/employee_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | // Employee represents an employee 4 | type Employee struct { 5 | ID string 6 | FirstName string 7 | LastName string 8 | } 9 | 10 | func NewEmployee() *Employee { 11 | return &Employee{} 12 | } 13 | -------------------------------------------------------------------------------- /tests/expiration_operation_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "github.com/ravendb/ravendb-go-client" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | ) 8 | 9 | func expirationConfigurationOperation(t *testing.T, driver *RavenTestDriver) { 10 | store := driver.getDocumentStoreMust(t) 11 | defer store.Close() 12 | 13 | configureExpiration := ravendb.ExpirationConfiguration{ 14 | Disabled: false, 15 | } 16 | 17 | opExpiration, err := ravendb.NewConfigureExpirationOperationWithConfiguration(&configureExpiration) 18 | assert.NoError(t, err) 19 | 20 | err = store.Maintenance().Send(opExpiration) 21 | assert.NoError(t, err) 22 | 23 | lastRaftEtag := *opExpiration.Command.Result.RaftCommandIndex 24 | assert.NotNil(t, lastRaftEtag) 25 | 26 | var deleteFrequency int64 = 60 27 | opExpiration, err = ravendb.NewConfigureExpirationOperation(false, &deleteFrequency, nil) 28 | assert.NoError(t, err) 29 | 30 | err = store.Maintenance().Send(opExpiration) 31 | assert.NoError(t, err) 32 | 33 | assert.NotNil(t, *opExpiration.Command.Result.RaftCommandIndex) 34 | assert.NotEqual(t, lastRaftEtag, *opExpiration.Command.Result.RaftCommandIndex) 35 | } 36 | 37 | func TestExpirationConfiguration(t *testing.T) { 38 | driver := createTestDriver(t) 39 | destroy := func() { destroyDriver(t, driver) } 40 | defer recoverTest(t, destroy) 41 | expirationConfigurationOperation(t, driver) 42 | } 43 | -------------------------------------------------------------------------------- /tests/geek_person_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | type GeekPerson struct { 4 | Name string `json:"Name"` 5 | FavoritePrimes []int `json:"FavoritePrimes"` 6 | FavoriteVeryLargePrimes []int64 `json:"FavoriteVeryLargePrimes"` 7 | } 8 | -------------------------------------------------------------------------------- /tests/get_database_record_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "github.com/ravendb/ravendb-go-client" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | ) 8 | 9 | func getDatabaseRecordCanGetDatabaseRecord(t *testing.T, driver *RavenTestDriver) { 10 | var err error 11 | store := driver.getDocumentStoreMust(t) 12 | defer store.Close() 13 | 14 | op := ravendb.NewGetDatabaseRecordOperation(store.GetDatabase()) 15 | err = store.Maintenance().Server().Send(op) 16 | assert.NoError(t, err) 17 | assert.Equal(t, op.Command.Result.DatabaseName, store.GetDatabase()) 18 | } 19 | 20 | func TestGetDatabaseRecord(t *testing.T) { 21 | driver := createTestDriver(t) 22 | destroy := func() { destroyDriver(t, driver) } 23 | defer recoverTest(t, destroy) 24 | 25 | // matches order of Java tests 26 | getDatabaseRecordCanGetDatabaseRecord(t, driver) 27 | } 28 | -------------------------------------------------------------------------------- /tests/get_next_operation_id_command_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ravendb/ravendb-go-client" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func getNextOperationIdCommandTestCanGetNextOperationId(t *testing.T, driver *RavenTestDriver) { 11 | var err error 12 | store := driver.getDocumentStoreMust(t) 13 | defer store.Close() 14 | 15 | command := ravendb.NewGetNextOperationIDCommand() 16 | err = store.GetRequestExecutor("").ExecuteCommand(command, nil) 17 | assert.NoError(t, err) 18 | assert.NotNil(t, command.Result) 19 | } 20 | 21 | func TestGetNextOperationIDCommand(t *testing.T) { 22 | driver := createTestDriver(t) 23 | destroy := func() { destroyDriver(t, driver) } 24 | defer recoverTest(t, destroy) 25 | 26 | // follows execution order of java tests 27 | getNextOperationIdCommandTestCanGetNextOperationId(t, driver) 28 | } 29 | -------------------------------------------------------------------------------- /tests/get_tcp_info_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "testing" 5 | 6 | ravendb "github.com/ravendb/ravendb-go-client" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func getTcpInfoTestCanGetTcpInfo(t *testing.T, driver *RavenTestDriver) { 11 | store := driver.getDocumentStoreMust(t) 12 | defer store.Close() 13 | 14 | command := ravendb.NewGetTcpInfoCommand("test", "") 15 | err := store.GetRequestExecutor("").ExecuteCommand(command, nil) 16 | assert.NoError(t, err) 17 | result := command.Result 18 | assert.NotNil(t, result) 19 | assert.Nil(t, result.Certificate) 20 | // Note: in Java this tests for non-nil but Port is not sent 21 | // in Json, so don't quite understand that. Unless Java check 22 | // is bogus 23 | assert.Equal(t, 0, result.Port) 24 | assert.NotEmpty(t, result.URL) 25 | } 26 | 27 | func TestGetTcpInfo(t *testing.T) { 28 | driver := createTestDriver(t) 29 | destroy := func() { destroyDriver(t, driver) } 30 | defer recoverTest(t, destroy) 31 | 32 | getTcpInfoTestCanGetTcpInfo(t, driver) 33 | } 34 | -------------------------------------------------------------------------------- /tests/get_topology_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "testing" 5 | 6 | ravendb "github.com/ravendb/ravendb-go-client" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func getTopologyTestCanGetTopology(t *testing.T, driver *RavenTestDriver) { 11 | var err error 12 | store := driver.getDocumentStoreMust(t) 13 | defer store.Close() 14 | 15 | command := ravendb.NewGetDatabaseTopologyCommand() 16 | err = store.GetRequestExecutor("").ExecuteCommand(command, nil) 17 | assert.NoError(t, err) 18 | result := command.Result 19 | assert.NotNil(t, result) 20 | 21 | assert.NotEqual(t, result.Etag, "") 22 | assert.Equal(t, len(result.Nodes), 1) 23 | serverNode := result.Nodes[0] 24 | assert.Equal(t, serverNode.URL, store.GetUrls()[0]) 25 | assert.Equal(t, serverNode.Database, store.GetDatabase()) 26 | assert.Equal(t, serverNode.ClusterTag, "A") 27 | assert.Equal(t, serverNode.ServerRole, ravendb.ServerNodeRoleMember) 28 | } 29 | 30 | func TestGetTopology(t *testing.T) { 31 | driver := createTestDriver(t) 32 | destroy := func() { destroyDriver(t, driver) } 33 | defer recoverTest(t, destroy) 34 | 35 | getTopologyTestCanGetTopology(t, driver) 36 | } 37 | -------------------------------------------------------------------------------- /tests/https_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func httpsTestCanConnectWithCertificate(t *testing.T, driver *RavenTestDriver) { 10 | var err error 11 | store := driver.getSecuredDocumentStoreMust(t) 12 | defer store.Close() 13 | 14 | { 15 | newSession := openSessionMust(t, store) //may need to run the IDE from administrator 16 | user1 := &User{} 17 | user1.setLastName("user1") 18 | err = newSession.StoreWithID(user1, "users/1") 19 | assert.NoError(t, err) 20 | err = newSession.SaveChanges() 21 | assert.NoError(t, err) 22 | } 23 | } 24 | 25 | func TestHttps(t *testing.T) { 26 | driver := createTestDriver(t) 27 | destroy := func() { destroyDriver(t, driver) } 28 | defer recoverTest(t, destroy) 29 | 30 | // matches order of java tests 31 | httpsTestCanConnectWithCertificate(t, driver) 32 | } 33 | -------------------------------------------------------------------------------- /tests/non_null_time.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "testing" 5 | "time" 6 | 7 | "github.com/ravendb/ravendb-go-client" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestNonNilTimeError(t *testing.T) { 12 | driver := createTestDriver(t) 13 | test_case_string_non_nil_error(t, driver) 14 | } 15 | 16 | func test_case_string_non_nil_error(t *testing.T, driver *RavenTestDriver) { 17 | 18 | id := "customer1" 19 | 20 | var err error 21 | store := driver.getDocumentStoreMust(t) 22 | defer store.Close() 23 | 24 | var time time.Time 25 | time, err = ravendb.ParseTime("2006-01-02T15:04:05.9999999Z") 26 | rtime := ravendb.Time(time) 27 | 28 | obj := &CustomerNilTime{ 29 | ID: id, 30 | CreatedAt: &rtime, 31 | } 32 | 33 | { 34 | session := openSessionMust(t, store) 35 | err = session.Store(obj) 36 | assert.NoError(t, err) 37 | session.SaveChanges() 38 | session.Close() 39 | } 40 | 41 | { 42 | session := openSessionMust(t, store) 43 | var customer *CustomerNilTime 44 | err = session.Load(&customer, id) 45 | 46 | assert.True(t, customer.CreatedAt != nil) 47 | 48 | session.Close() 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/nullable_time.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ravendb/ravendb-go-client" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | // Note: must rename as it conflicts with Order in order_test.go 11 | type CustomerNilTime struct { 12 | ID string `json:"Id"` 13 | CreatedAt *ravendb.Time `json:"createdAt"` 14 | } 15 | 16 | func TestNilTimeError(t *testing.T) { 17 | driver := createTestDriver(t) 18 | test_case_string_nil_error(t, driver) 19 | } 20 | 21 | func test_case_nil_time_error(t *testing.T, driver *RavenTestDriver) { 22 | 23 | id := "customer1" 24 | 25 | var err error 26 | store := driver.getDocumentStoreMust(t) 27 | defer store.Close() 28 | 29 | obj := &CustomerNilTime{ 30 | ID: id, 31 | CreatedAt: nil, 32 | } 33 | 34 | { 35 | session := openSessionMust(t, store) 36 | err = session.Store(obj) 37 | assert.NoError(t, err) 38 | session.SaveChanges() 39 | session.Close() 40 | } 41 | 42 | { 43 | session := openSessionMust(t, store) 44 | var customer *CustomerNilTime 45 | err = session.Load(&customer, id) 46 | 47 | assert.True(t, customer.CreatedAt == nil) 48 | 49 | session.Close() 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/operation_database_health_check_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "github.com/ravendb/ravendb-go-client" 5 | "github.com/ravendb/ravendb-go-client/serverwide/operations" 6 | "github.com/stretchr/testify/assert" 7 | "testing" 8 | ) 9 | 10 | func getDatabaseHealthCheckTest(t *testing.T, driver *RavenTestDriver) { 11 | var err error 12 | store := driver.getDocumentStoreMust(t) 13 | defer store.Close() 14 | operation := operations.OperationDatabaseHealthCheck{} 15 | err = store.Maintenance().Send(&operation) 16 | assert.NoError(t, err) 17 | 18 | secondOperation := operations.OperationDatabaseHealthCheck{} 19 | err = store.Maintenance().ForDatabase("does_not_exists").Send(&secondOperation) 20 | _, ok := err.(*ravendb.DatabaseDoesNotExistError) 21 | assert.True(t, ok) 22 | assert.EqualError(t, err, err.(*ravendb.DatabaseDoesNotExistError).ErrorStr) 23 | } 24 | 25 | func TestGetDatabaseHealthCheckTest(t *testing.T) { 26 | driver := createTestDriver(t) 27 | destroy := func() { destroyDriver(t, driver) } 28 | defer recoverTest(t, destroy) 29 | 30 | getDatabaseHealthCheckTest(t, driver) 31 | } 32 | -------------------------------------------------------------------------------- /tests/operation_get_cluster_topology_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "github.com/ravendb/ravendb-go-client/serverwide/operations" 5 | "github.com/stretchr/testify/assert" 6 | "testing" 7 | ) 8 | 9 | func getClusterTopologyTestCanGetTopology(t *testing.T, driver *RavenTestDriver) { 10 | var err error 11 | store := driver.getDocumentStoreMust(t) 12 | defer store.Close() 13 | operation := operations.OperationGetClusterTopology{} 14 | err = store.Maintenance().Server().Send(&operation) 15 | assert.NoError(t, err) 16 | 17 | assert.NotEmpty(t, operation.Leader) 18 | assert.NotEmpty(t, operation.NodeTag) 19 | 20 | topology := operation.Topology 21 | assert.NotNil(t, topology) 22 | assert.NotEmpty(t, topology.TopologyID) 23 | assert.Equal(t, 1, len(topology.Members)) 24 | assert.Equal(t, 0, len(topology.Watchers)) 25 | assert.Equal(t, 0, len(topology.Promotables)) 26 | } 27 | 28 | func TestGetClusterTopology(t *testing.T) { 29 | driver := createTestDriver(t) 30 | destroy := func() { destroyDriver(t, driver) } 31 | defer recoverTest(t, destroy) 32 | 33 | getClusterTopologyTestCanGetTopology(t, driver) 34 | } 35 | -------------------------------------------------------------------------------- /tests/operation_put_certificate_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ravendb/ravendb-go-client/serverwide/certificates" 6 | "github.com/stretchr/testify/assert" 7 | "os" 8 | "testing" 9 | ) 10 | 11 | func putCertificateTest(t *testing.T, driver *RavenTestDriver) { 12 | var err error 13 | 14 | store := driver.getSecuredDocumentStoreMust(t) 15 | assert.NotNil(t, store) 16 | defer store.Close() 17 | 18 | path := os.Getenv("RAVENDB_TEST_CA_PATH") 19 | if !fileExists(path) { 20 | fmt.Printf("Didn't find cert.crt file at '%s'. Set RAVENDB_TEST_CA_PATH env variable\n", path) 21 | os.Exit(1) 22 | } 23 | 24 | certificate := loadTestCaCertificate(path) 25 | assert.NotNil(t, certificate) 26 | fmt.Printf("Loaded client certificate from '%s'\n", path) 27 | 28 | certName := "Admin Certificate" 29 | operation := certificates.OperationPutCertificate{ 30 | CertName: certName, 31 | CertBytes: certificate.Raw, 32 | SecurityClearance: certificates.ClusterAdmin.String(), 33 | Permissions: nil, 34 | } 35 | 36 | err = store.Maintenance().Server().Send(&operation) 37 | assert.NoError(t, err) 38 | 39 | } 40 | 41 | func TestPutCertificateTest(t *testing.T) { 42 | driver := createTestDriver(t) 43 | destroy := func() { 44 | destroyDriver(t, driver) 45 | } 46 | 47 | defer recoverTest(t, destroy) 48 | 49 | putCertificateTest(t, driver) 50 | } 51 | -------------------------------------------------------------------------------- /tests/order_line_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | type OrderLine struct { 4 | Product string `json:"product"` 5 | ProductName string `json:"productName"` 6 | PricePerUnit float64 `json:"pricePerUnit"` 7 | Quantity int `json:"quantity"` 8 | Discount float64 `json:"discount"` 9 | } 10 | -------------------------------------------------------------------------------- /tests/order_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | ravendb "github.com/ravendb/ravendb-go-client" 5 | ) 6 | 7 | type Order struct { 8 | ID string 9 | Company string `json:"company"` 10 | Employee string `json:"employee"` 11 | OrderedAt ravendb.Time `json:"orderedAt"` 12 | RequireAt ravendb.Time `json:"requireAt"` 13 | ShippedAt ravendb.Time `json:"shippedAt"` 14 | ShipTo *Address `json:"shipTo"` 15 | ShipVia string `json:"shipVia"` 16 | Freight float64 `json:"freight"` 17 | Lines []*OrderLine `json:"lines"` 18 | } 19 | -------------------------------------------------------------------------------- /tests/person_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | // Person represents a person 4 | type Person struct { 5 | ID string 6 | Name string 7 | AddressId string `json:"AddressId"` 8 | } 9 | -------------------------------------------------------------------------------- /tests/post_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import "time" 4 | 5 | type Post struct { 6 | ID string 7 | Title string `json:"title,omitempty"` 8 | Desc string `json:"desc,omitempty"` 9 | Comments []*Post `json:"comments"` 10 | AttachmentIds string `json:"attachmentIds,omitempty"` 11 | CreatedAt time.Time `json:"createdAt,omitempty"` 12 | } 13 | -------------------------------------------------------------------------------- /tests/put_document_command_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ravendb/ravendb-go-client" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func putDocumentCommandCanPutDocumentUsingCommand(t *testing.T, driver *RavenTestDriver) { 11 | var err error 12 | store := driver.getDocumentStoreMust(t) 13 | defer store.Close() 14 | 15 | user := &User{} 16 | user.setName("Marcin") 17 | user.Age = 30 18 | 19 | node, err := entityToDocument(user) 20 | assert.NoError(t, err) 21 | 22 | command := ravendb.NewPutDocumentCommand("users/1", nil, node) 23 | err = store.GetRequestExecutor("").ExecuteCommand(command, nil) 24 | assert.NoError(t, err) 25 | 26 | result := command.Result 27 | assert.Equal(t, "users/1", result.ID) 28 | 29 | assert.NotNil(t, result.ChangeVector) 30 | 31 | { 32 | session := openSessionMust(t, store) 33 | var loadedUser *User 34 | err = session.Load(&loadedUser, "users/1") 35 | assert.NoError(t, err) 36 | assert.Equal(t, "Marcin", *loadedUser.Name) 37 | session.Close() 38 | } 39 | } 40 | 41 | func TestPutDocumentCommand(t *testing.T) { 42 | driver := createTestDriver(t) 43 | destroy := func() { destroyDriver(t, driver) } 44 | defer recoverTest(t, destroy) 45 | 46 | putDocumentCommandCanPutDocumentUsingCommand(t, driver) 47 | } 48 | -------------------------------------------------------------------------------- /tests/ravendb_10566_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | ravendb "github.com/ravendb/ravendb-go-client" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func ravendb10566_shouldBeAvailable(t *testing.T, driver *RavenTestDriver) { 12 | var err error 13 | store := driver.getDocumentStoreMust(t) 14 | defer store.Close() 15 | 16 | var name string 17 | var mu sync.Mutex 18 | 19 | afterSaveChanges := func(event *ravendb.AfterSaveChangesEventArgs) { 20 | meta := event.GetDocumentMetadata() 21 | 22 | nameI, ok := meta.Get("Name") 23 | assert.True(t, ok) 24 | 25 | mu.Lock() 26 | defer mu.Unlock() 27 | name = nameI.(string) 28 | } 29 | store.AddAfterSaveChangesListener(afterSaveChanges) 30 | 31 | { 32 | session := openSessionMust(t, store) 33 | 34 | user := &User{} 35 | user.setName("Oren") 36 | 37 | err = session.StoreWithID(user, "users/oren") 38 | assert.NoError(t, err) 39 | 40 | metadata, err := session.Advanced().GetMetadataFor(user) 41 | assert.NoError(t, err) 42 | metadata.Put("Name", "FooBar") 43 | 44 | err = session.SaveChanges() 45 | assert.NoError(t, err) 46 | 47 | session.Close() 48 | } 49 | 50 | assert.Equal(t, name, "FooBar") 51 | } 52 | 53 | func TestRavenDB10566(t *testing.T) { 54 | driver := createTestDriver(t) 55 | destroy := func() { destroyDriver(t, driver) } 56 | defer recoverTest(t, destroy) 57 | 58 | // matches Java's order 59 | ravendb10566_shouldBeAvailable(t, driver) 60 | } 61 | -------------------------------------------------------------------------------- /tests/ravendb_14989_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "github.com/ravendb/ravendb-go-client" 5 | "github.com/stretchr/testify/assert" 6 | "strings" 7 | "testing" 8 | ) 9 | 10 | func ravendb14989_should_work(t *testing.T, driver *RavenTestDriver) { 11 | store := driver.getDocumentStoreMust(t) 12 | { 13 | session := openSessionMustWithOptions(t, store, &ravendb.SessionOptions{ 14 | Database: "", 15 | RequestExecutor: nil, 16 | TransactionMode: ravendb.TransactionMode_ClusterWide, 17 | DisableAtomicDocumentWritesInClusterWideTransaction: nil, 18 | }) 19 | 20 | name := "egor" 21 | user := &User{ 22 | Name: &name, 23 | } 24 | 25 | assert.NotNil(t, session.Advanced().ClusterTransaction()) 26 | 27 | _, err := session.Advanced().ClusterTransaction().CreateCompareExchangeValue(strings.Repeat("e", 513), user) 28 | assert.NoError(t, err) 29 | 30 | err = session.SaveChanges() 31 | 32 | assert.Error(t, err) 33 | 34 | assert.True(t, strings.Contains(err.Error(), "CompareExchangeKeyTooBigException")) 35 | } 36 | } 37 | 38 | func TestRavenDB14989(t *testing.T) { 39 | driver := createTestDriver(t) 40 | destroy := func() { destroyDriver(t, driver) } 41 | defer recoverTest(t, destroy) 42 | 43 | // matches the order of Java tests 44 | ravendb14989_should_work(t, driver) 45 | } 46 | -------------------------------------------------------------------------------- /tests/string_nil_save_changes_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | // Note: must rename as it conflicts with Order in order_test.go 10 | type CustomerNilReference struct { 11 | ID string `json:"Id"` 12 | Reference *string `json:"reference"` 13 | Name string `json:"name"` 14 | } 15 | 16 | func TestStringNilError(t *testing.T) { 17 | driver := createTestDriver(t) 18 | test_case_string_nil_error(t, driver) 19 | } 20 | 21 | func test_case_string_nil_error(t *testing.T, driver *RavenTestDriver) { 22 | 23 | id := "customer1" 24 | reference := "reference" 25 | 26 | var err error 27 | store := driver.getDocumentStoreMust(t) 28 | defer store.Close() 29 | 30 | obj := &CustomerNilReference{ 31 | ID: id, 32 | Name: "customer_name", 33 | } 34 | 35 | { 36 | session := openSessionMust(t, store) 37 | err = session.Store(obj) 38 | assert.NoError(t, err) 39 | session.SaveChanges() 40 | session.Close() 41 | } 42 | 43 | { 44 | session := openSessionMust(t, store) 45 | var customer *CustomerNilReference 46 | err = session.Load(&customer, id) 47 | 48 | customer.Reference = &reference 49 | 50 | session.SaveChanges() 51 | 52 | session.Close() 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tests/user_test.go: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import "reflect" 4 | 5 | var ( 6 | userType = reflect.TypeOf(&User{}) 7 | ) 8 | 9 | type User struct { 10 | ID string 11 | Name *string `json:"name"` 12 | LastName *string `json:"lastName"` 13 | AddressID string `json:"addressId,omitempty"` 14 | Count int `json:"count"` 15 | Age int `json:"age"` 16 | } 17 | 18 | func (u *User) setName(name string) { 19 | u.Name = &name 20 | } 21 | 22 | func (u *User) setLastName(lastName string) { 23 | u.LastName = &lastName 24 | } 25 | 26 | func (u *User) setAge(age int) { 27 | u.Age = age 28 | } 29 | -------------------------------------------------------------------------------- /time_test.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "encoding/json" 5 | "strings" 6 | "testing" 7 | "time" 8 | 9 | "github.com/stretchr/testify/assert" 10 | ) 11 | 12 | func TestTime(t *testing.T) { 13 | { 14 | var tt time.Time 15 | d, err := json.Marshal(Time(tt)) 16 | assert.NoError(t, err) 17 | s := string(d) 18 | assert.Equal(t, `"0001-01-01T00:00:00.0000000Z"`, s) 19 | } 20 | 21 | { 22 | tt := time.Now() 23 | d, err := json.Marshal(Time(tt)) 24 | assert.NoError(t, err) 25 | s := string(d) 26 | parts := strings.Split(s, ".") 27 | fracPart := parts[len(parts)-1] 28 | assert.Equal(t, 9, len(fracPart)) // 9 = 7 digits + Z + " 29 | assert.True(t, strings.HasSuffix(s, `Z"`)) 30 | } 31 | 32 | { 33 | tt, err := time.Parse("2006-01-02T15:04:05.9999999Z", "2018-12-17T18:08:34.069973Z") 34 | assert.NoError(t, err) 35 | d, err := json.Marshal(Time(tt)) 36 | assert.NoError(t, err) 37 | s := string(d) 38 | parts := strings.Split(s, ".") 39 | fracPart := parts[len(parts)-1] 40 | assert.Equal(t, 9, len(fracPart)) // 9 = 7 digits + Z + " 41 | assert.True(t, strings.HasSuffix(s, `Z"`)) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /time_utils.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // TODO: implementation could be improved 9 | func durationToTimeSpan(duration time.Duration) string { 10 | tm := int64(duration / time.Millisecond) 11 | millis := tm % 1000 12 | tm = tm / 1000 // seconds 13 | seconds := tm % 60 14 | tm = tm / 60 // in minutes 15 | minutes := tm % 60 16 | tm = tm / 60 // in hours 17 | hours := tm % 24 18 | tm = tm / 24 // in days 19 | days := tm 20 | 21 | s := "" 22 | 23 | if days > 0 { 24 | s += fmt.Sprintf("%d.", days) 25 | } 26 | s += fmt.Sprintf("%02d:", hours) 27 | s += fmt.Sprintf("%02d:", minutes) 28 | s += fmt.Sprintf("%02d", seconds) 29 | if millis > 0 { 30 | s += fmt.Sprintf(".%03d0000", millis) 31 | } 32 | return s 33 | } 34 | -------------------------------------------------------------------------------- /topology.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // Topology describes server nodes 4 | type Topology struct { 5 | Nodes []*ServerNode `json:"Nodes"` 6 | Etag int64 `json:"Etag"` 7 | } 8 | -------------------------------------------------------------------------------- /true_token.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "strings" 4 | 5 | var _ queryToken = &trueToken{} 6 | 7 | var trueTokenInstance = &trueToken{} 8 | 9 | type trueToken struct { 10 | } 11 | 12 | func (t *trueToken) writeTo(writer *strings.Builder) error { 13 | writer.WriteString("true") 14 | return nil 15 | } 16 | -------------------------------------------------------------------------------- /url_utils.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import "net/url" 4 | 5 | // TODO: this is more complicated in Java code. Not sure if warranted 6 | func urlUtilsEscapeDataString(stringToEscape string) string { 7 | if len(stringToEscape) == 0 { 8 | return stringToEscape 9 | } 10 | return url.QueryEscape(stringToEscape) 11 | /* 12 | var position int 13 | char[] dest = escapeString(stringToEscape, 0, stringToEscape.length(), null, position, false); 14 | if (dest == null) { 15 | return stringToEscape; 16 | } 17 | return new string(dest, 0, position.value); 18 | 19 | panic("NYI") 20 | return stringToEscape 21 | */ 22 | } 23 | -------------------------------------------------------------------------------- /util.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | var ( 10 | // if true, does verbose logging. 11 | LogVerbose = false 12 | ) 13 | 14 | func dbg(format string, args ...interface{}) { 15 | if LogVerbose { 16 | fmt.Printf(format, args...) 17 | } 18 | } 19 | 20 | func must(err error) { 21 | if err != nil { 22 | panic(err) 23 | } 24 | } 25 | 26 | func panicIf(cond bool, format string, args ...interface{}) { 27 | if cond { 28 | err := fmt.Errorf(format, args...) 29 | must(err) 30 | } 31 | } 32 | 33 | func i64toa(n int64) string { 34 | return strconv.FormatInt(n, 10) 35 | } 36 | 37 | func min(i1, i2 int) int { 38 | if i1 < i2 { 39 | return i1 40 | } 41 | return i2 42 | } 43 | 44 | func firstNonNilString(s1, s2 *string) *string { 45 | if s1 != nil { 46 | return s1 47 | } 48 | return s2 49 | } 50 | 51 | func firstNonEmptyString(s1, s2 string) string { 52 | if s1 != "" { 53 | return s1 54 | } 55 | return s2 56 | } 57 | 58 | func firstNonZero(i1, i2 int) int { 59 | if i1 != 0 { 60 | return i1 61 | } 62 | return i2 63 | } 64 | 65 | func deepCopy(v interface{}) interface{} { 66 | // TODO: implement me 67 | return v 68 | } 69 | 70 | func builderWriteInt(b *strings.Builder, n int) { 71 | b.WriteString(strconv.Itoa(n)) 72 | } 73 | 74 | func builderWriteFloat64(b *strings.Builder, f float64) { 75 | b.WriteString(fmt.Sprintf("%f", f)) 76 | } 77 | -------------------------------------------------------------------------------- /uuid.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | import ( 4 | "crypto/rand" 5 | "encoding/hex" 6 | ) 7 | 8 | // implements generating random uuid4 that mimics python's uuid.uuid4() 9 | // it doesn't try to fully UUIDv4 compliant 10 | 11 | // UUID represents a random 16-byte number 12 | type UUID struct { 13 | data [16]byte 14 | } 15 | 16 | // NewUUID creates a new UUID 17 | func NewUUID() *UUID { 18 | res := &UUID{} 19 | n, _ := rand.Read(res.data[:]) 20 | panicIf(n != 16, "rand.Read() returned %d, expected 16", n) 21 | return res 22 | } 23 | 24 | // String returns xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx representation 25 | func (u *UUID) String() string { 26 | buf := make([]byte, 36) 27 | 28 | hex.Encode(buf[0:8], u.data[0:4]) 29 | buf[8] = '-' 30 | hex.Encode(buf[9:13], u.data[4:6]) 31 | buf[13] = '-' 32 | hex.Encode(buf[14:18], u.data[6:8]) 33 | buf[18] = '-' 34 | hex.Encode(buf[19:23], u.data[8:10]) 35 | buf[23] = '-' 36 | hex.Encode(buf[24:], u.data[10:]) 37 | 38 | return string(buf) 39 | } 40 | 41 | // Hex returns hex-encoded version. 42 | // Equivalent of python's uuid.uuid4().hex 43 | func (u *UUID) Hex() string { 44 | dst := make([]byte, 32) 45 | n := hex.Encode(dst, u.data[:]) 46 | panicIf(n != 32, "hex.Encode() returned %d, expected 32", n) 47 | return string(dst) 48 | } 49 | -------------------------------------------------------------------------------- /where_operator.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type whereOperator int 4 | 5 | const ( 6 | whereOperatorEquals whereOperator = iota 7 | whereOperatorNotEquals 8 | whereOperatorGreaterThan 9 | whereOperatorGreaterThanOrEqual 10 | whereOperatorLessThan 11 | whereOperatorLessThanOrEqual 12 | whereOperatorIn 13 | whereOperatorAllIn 14 | whereOperatorBetween 15 | whereOperatorSearch 16 | whereOperatorLucene 17 | whereOperatorStartsWith 18 | whereOperatorEndsWith 19 | whereOperatorExists 20 | whereOperatorSpatialWithin 21 | whereOperatorSpatialContains 22 | whereOperatorSpatialDisjoint 23 | whereOperatorSpatialIntersects 24 | whereOperatorRegex 25 | ) 26 | -------------------------------------------------------------------------------- /where_params.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | // whereParams are parameters for the Where Equals call 4 | type whereParams struct { 5 | fieldName string 6 | value interface{} 7 | allowWildcards bool 8 | isNestedPath bool 9 | isExact bool 10 | } 11 | -------------------------------------------------------------------------------- /wkt_criteria.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | type WktCriteria struct { 4 | SpatialCriteriaCommon 5 | _shapeWkt string 6 | } 7 | 8 | func NewWktCriteria(shapeWkt string, relation SpatialRelation, distErrorPercent float64) *WktCriteria { 9 | res := &WktCriteria{ 10 | _shapeWkt: shapeWkt, 11 | } 12 | res._relation = relation 13 | res._distanceErrorPct = distErrorPercent 14 | return res 15 | } 16 | 17 | func (c *WktCriteria) ToQueryToken(fieldName string, addQueryParameter func(interface{}) string) queryToken { 18 | return c.SpatialCriteriaCommon.toQueryTokenCommon(c, fieldName, addQueryParameter) 19 | } 20 | 21 | func (c *WktCriteria) GetShapeToken(addQueryParameter func(interface{}) string) *shapeToken { 22 | return shapeTokenWkt(addQueryParameter(c._shapeWkt)) 23 | } 24 | -------------------------------------------------------------------------------- /wkt_field.go: -------------------------------------------------------------------------------- 1 | package ravendb 2 | 3 | var _ DynamicSpatialField = &WktField{} 4 | 5 | type WktField struct { 6 | wkt string 7 | } 8 | 9 | func NewWktField(wkt string) *WktField { 10 | return &WktField{ 11 | wkt: wkt, 12 | } 13 | } 14 | 15 | func (f *WktField) ToField(ensureValidFieldName func(string, bool) (string, error)) (string, error) { 16 | name, err := ensureValidFieldName(f.wkt, false) 17 | if err != nil { 18 | return "", err 19 | } 20 | return "spatial.wkt(" + name + ")", nil 21 | } 22 | --------------------------------------------------------------------------------