Class: RakeAudit::Adapters::MongoAdapter

Inherits:
Base
  • Object
show all
Defined in:
lib/rake_audit/adapters/mongo_adapter.rb

Overview

Persists and queries TaskExecutionRecord instances via MongoDB.

Uses the MongoDB Ruby driver directly. Documents are stored in the rake_task_executions collection and Mongo’s native _id (ObjectId) is used as the record identifier for Web UI links.

Instance Method Summary collapse

Methods inherited from Base

#stats

Constructor Details

#initialize(client:) ⇒ MongoAdapter

Returns a new instance of MongoAdapter.

Parameters:

  • client (Mongo::Client)

    a connected MongoDB client instance.



16
17
18
19
# File 'lib/rake_audit/adapters/mongo_adapter.rb', line 16

def initialize(client:)
  super()
  @client = client
end

Instance Method Details

#average_duration_msFloat?

Returns:

  • (Float, nil)


77
78
79
80
81
82
# File 'lib/rake_audit/adapters/mongo_adapter.rb', line 77

def average_duration_ms
  result = collection.aggregate([
                                  { '$group' => { '_id' => nil, 'avg' => { '$avg' => '$duration_ms' } } }
                                ]).first
  result ? result['avg'] : nil
end

#countInteger

Returns:

  • (Integer)


66
67
68
# File 'lib/rake_audit/adapters/mongo_adapter.rb', line 66

def count
  collection.count_documents({})
end

#count_by_status(status) ⇒ Integer

Parameters:

  • status (String)

Returns:

  • (Integer)


72
73
74
# File 'lib/rake_audit/adapters/mongo_adapter.rb', line 72

def count_by_status(status)
  collection.count_documents('status' => status)
end

#find(id) ⇒ RakeAudit::Adapters::ExecutionRecord

Parameters:

  • id (String)

    string representation of a Mongo ObjectId.

Returns:

Raises:



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/rake_audit/adapters/mongo_adapter.rb', line 52

def find(id)
  # Skip the require when BSON is already defined (e.g. stubbed in tests).
  require 'bson' unless defined?(BSON)
  object_id = BSON::ObjectId.from_string(id.to_s)
  doc = collection.find(_id: object_id).first
  raise RakeAudit::RecordNotFound, "Couldn't find execution with id=#{id}" unless doc

  to_execution_record(doc)
rescue ArgumentError
  # BSON::ObjectId::Invalid inherits from ArgumentError — invalid id string.
  raise RakeAudit::RecordNotFound, "Couldn't find execution with id=#{id}"
end

#query(filters: {}, page: nil, per_page: 25) ⇒ Kaminari::PaginatableArray

Parameters:

  • filters (Hash) (defaults to: {})

    pre-validated non-blank filter values.

  • page (Integer, String, nil) (defaults to: nil)
  • per_page (Integer) (defaults to: 25)

Returns:

  • (Kaminari::PaginatableArray)


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/rake_audit/adapters/mongo_adapter.rb', line 32

def query(filters: {}, page: nil, per_page: 25)
  require 'kaminari'
  filter      = build_filter(filters)
  total       = collection.count_documents(filter)
  current     = [page.to_i, 1].max
  cursor      = collection.find(filter)
                          .sort(started_at: -1)
                          .skip((current - 1) * per_page)
                          .limit(per_page)

  records = cursor.map { |doc| to_execution_record(doc) }
  Kaminari
    .paginate_array(records, total_count: total)
    .page(current)
    .per(per_page)
end

#save(record) ⇒ Object

Insert the record into the executions collection.

Parameters:



24
25
26
# File 'lib/rake_audit/adapters/mongo_adapter.rb', line 24

def save(record)
  collection.insert_one(record.to_h)
end

#top_failed_tasks(limit: 10) ⇒ Array<Array(String, Integer)>

Parameters:

  • limit (Integer) (defaults to: 10)

Returns:

  • (Array<Array(String, Integer)>)


86
87
88
89
90
91
92
93
# File 'lib/rake_audit/adapters/mongo_adapter.rb', line 86

def top_failed_tasks(limit: 10)
  collection.aggregate([
                         { '$match' => { 'status' => 'failure' } },
                         { '$group'  => { '_id' => '$task_name', 'count' => { '$sum' => 1 } } },
                         { '$sort'   => { 'count' => -1 } },
                         { '$limit'  => limit }
                       ]).map { |doc| [doc['_id'], doc['count']] }
end