anki_record 0.3.1 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.rubocop.yml +2 -7
  4. data/CHANGELOG.md +13 -1
  5. data/Gemfile +4 -0
  6. data/Gemfile.lock +9 -2
  7. data/README.md +79 -132
  8. data/anki_record.gemspec +2 -2
  9. data/lib/anki_record/anki21_database/anki21_database.rb +138 -0
  10. data/lib/anki_record/anki21_database/anki21_database_attributes.rb +31 -0
  11. data/lib/anki_record/anki21_database/anki21_database_constructors.rb +52 -0
  12. data/lib/anki_record/anki2_database/anki2_database.rb +44 -0
  13. data/lib/anki_record/anki_package/anki_package.rb +110 -176
  14. data/lib/anki_record/card/card.rb +17 -33
  15. data/lib/anki_record/card/card_attributes.rb +3 -34
  16. data/lib/anki_record/card_template/card_template.rb +2 -2
  17. data/lib/anki_record/card_template/card_template_attributes.rb +11 -11
  18. data/lib/anki_record/collection/collection.rb +20 -154
  19. data/lib/anki_record/collection/collection_attributes.rb +2 -30
  20. data/lib/anki_record/deck/deck.rb +11 -10
  21. data/lib/anki_record/deck/deck_attributes.rb +6 -8
  22. data/lib/anki_record/deck/deck_defaults.rb +1 -1
  23. data/lib/anki_record/deck_options_group/deck_options_group.rb +8 -6
  24. data/lib/anki_record/deck_options_group/deck_options_group_attributes.rb +5 -7
  25. data/lib/anki_record/helpers/anki_guid_helper.rb +20 -0
  26. data/lib/anki_record/media/media.rb +36 -0
  27. data/lib/anki_record/note/note.rb +62 -88
  28. data/lib/anki_record/note/note_attributes.rb +19 -18
  29. data/lib/anki_record/note_field/note_field.rb +3 -3
  30. data/lib/anki_record/note_field/note_field_attributes.rb +9 -9
  31. data/lib/anki_record/note_type/note_type.rb +13 -14
  32. data/lib/anki_record/note_type/note_type_attributes.rb +17 -21
  33. data/lib/anki_record/version.rb +1 -1
  34. metadata +11 -6
  35. data/lib/anki_record/helpers/data_query_helper.rb +0 -15
@@ -2,14 +2,14 @@
2
2
 
3
3
  require "securerandom"
4
4
 
5
+ require_relative "../helpers/anki_guid_helper"
5
6
  require_relative "../helpers/checksum_helper"
6
7
  require_relative "../helpers/time_helper"
7
8
  require_relative "note_attributes"
8
9
 
9
- # rubocop:disable Metrics/ClassLength
10
10
  module AnkiRecord
11
11
  ##
12
- # Represents an Anki note.
12
+ # Note represents Anki notes, which are the main thing that Anki Record is intended to create or update.
13
13
  class Note
14
14
  include Helpers::ChecksumHelper
15
15
  include NoteAttributes
@@ -17,40 +17,67 @@ module AnkiRecord
17
17
  include Helpers::SharedConstantsHelper
18
18
 
19
19
  ##
20
- # Instantiates a note of type +note_type+ and belonging to deck +deck+.
21
- def initialize(note_type: nil, deck: nil, collection: nil, data: nil)
20
+ # Instantiates a note of type +note_type+ and belonging to deck +deck+
21
+ def initialize(note_type: nil, deck: nil, anki21_database: nil, data: nil)
22
22
  if note_type && deck
23
- setup_instance_variables_for_new_note(note_type: note_type, deck: deck)
24
- elsif collection && data
25
- setup_instance_variables_from_existing(collection: collection,
26
- note_data: data[:note_data], cards_data: data[:cards_data])
23
+ setup_new_note(note_type:, deck:)
24
+ elsif anki21_database && data
25
+ setup_existing_note(anki21_database:,
26
+ note_data: data[:note_data], cards_data: data[:cards_data])
27
27
  else
28
28
  raise ArgumentError
29
29
  end
30
30
  end
31
31
 
32
- private
32
+ ##
33
+ # Saves the note and its cards
34
+ def save
35
+ anki21_database.find_note_by(id: @id) ? update_note_in_collection_anki21 : insert_new_note_in_collection_anki21
36
+ true
37
+ end
38
+
39
+ ##
40
+ # Overrides BasicObject#method_missing and creates "ghost methods"
41
+ #
42
+ # The ghost methods are the setters and getters for the note field values.
43
+ #
44
+ # For example, if the note type has a field called "front" then there will be two ghost methods: front and front=.
45
+ def method_missing(method_name, field_content = nil)
46
+ raise NoMethodError, "##{method_name} is not defined or a ghost method" unless respond_to_missing? method_name
47
+
48
+ method_name = method_name.to_s
49
+ return @field_contents[method_name] unless method_name.end_with?("=")
33
50
 
34
- def setup_instance_variables_for_new_note(note_type:, deck:)
35
- raise ArgumentError unless note_type.collection == deck.collection
51
+ @field_contents[method_name.chomp("=")] = field_content
52
+ end
36
53
 
37
- setup_collaborator_object_instance_variables_for_new_note(note_type: note_type, deck: deck)
38
- setup_simple_instance_variables_for_new_note
54
+ ##
55
+ # This allows #respond_to? to be accurate for the ghost methods created by #method_missing.
56
+ def respond_to_missing?(method_name, *)
57
+ method_name = method_name.to_s
58
+ if method_name.end_with?("=")
59
+ note_type.snake_case_field_names.include?(method_name.chomp("="))
60
+ else
61
+ note_type.snake_case_field_names.include?(method_name)
39
62
  end
63
+ end
64
+
65
+ private
66
+
67
+ # rubocop:disable Metrics/AbcSize
68
+ # rubocop:disable Metrics/MethodLength
69
+ def setup_new_note(note_type:, deck:)
70
+ raise ArgumentError unless note_type.anki21_database == deck.anki21_database
40
71
 
41
- def setup_collaborator_object_instance_variables_for_new_note(note_type:, deck:)
42
72
  @note_type = note_type
43
73
  @deck = deck
44
- @collection = deck.collection
74
+ @anki21_database = note_type.anki21_database
45
75
  @field_contents = setup_empty_field_contents_hash
46
76
  @cards = @note_type.card_templates.map do |card_template|
47
- Card.new(note: self, card_template: card_template)
77
+ Card.new(note: self, card_template:)
48
78
  end
49
- end
50
-
51
- def setup_simple_instance_variables_for_new_note
52
79
  @id = milliseconds_since_epoch
53
- @guid = globally_unique_id
80
+ @guid = Helpers::AnkiGuidHelper.globally_unique_id
54
81
  @last_modified_timestamp = seconds_since_epoch
55
82
  @usn = NEW_OBJECT_USN
56
83
  @tags = []
@@ -58,20 +85,23 @@ module AnkiRecord
58
85
  @data = ""
59
86
  end
60
87
 
61
- def setup_instance_variables_from_existing(collection:, note_data:, cards_data:)
62
- setup_collaborator_object_instance_variables_from_existing(collection: collection, note_data: note_data,
63
- cards_data: cards_data)
64
- setup_simple_instance_variables_from_existing(note_data: note_data)
65
- end
66
-
67
- def setup_collaborator_object_instance_variables_from_existing(collection:, note_data:, cards_data:)
68
- @collection = collection
69
- @note_type = collection.find_note_type_by id: note_data["mid"]
70
- @field_contents = setup_field_contents_hash_from_existing(note_data: note_data)
88
+ def setup_existing_note(anki21_database:, note_data:, cards_data:)
89
+ @anki21_database = anki21_database
90
+ @note_type = anki21_database.find_note_type_by id: note_data["mid"]
91
+ @field_contents = setup_field_contents_hash_from_existing(note_data:)
71
92
  @cards = @note_type.card_templates.map.with_index do |_card_template, index|
72
93
  Card.new(note: self, card_data: cards_data[index])
73
94
  end
95
+ @id = note_data["id"]
96
+ @guid = note_data["guid"]
97
+ @last_modified_timestamp = note_data["mod"]
98
+ @usn = note_data["usn"]
99
+ @tags = note_data["tags"].split
100
+ @flags = note_data["flags"]
101
+ @data = note_data["data"]
74
102
  end
103
+ # rubocop:enable Metrics/AbcSize
104
+ # rubocop:enable Metrics/MethodLength
75
105
 
76
106
  def setup_field_contents_hash_from_existing(note_data:)
77
107
  field_contents = setup_empty_field_contents_hash
@@ -82,37 +112,14 @@ module AnkiRecord
82
112
  field_contents
83
113
  end
84
114
 
85
- def setup_simple_instance_variables_from_existing(note_data:)
86
- @id = note_data["id"]
87
- @guid = note_data["guid"]
88
- @last_modified_timestamp = note_data["mod"]
89
- @usn = note_data["usn"]
90
- @tags = note_data["tags"].split
91
- @flags = note_data["flags"]
92
- @data = note_data["data"]
93
- end
94
-
95
115
  def setup_empty_field_contents_hash
96
116
  field_contents = {}
97
117
  note_type.snake_case_field_names.each { |field_name| field_contents[field_name] = "" }
98
118
  field_contents
99
119
  end
100
120
 
101
- public
102
-
103
- ##
104
- # Saves the note to the collection.anki21 database.
105
- #
106
- # This also saves the note's cards.
107
- def save
108
- collection.find_note_by(id: @id) ? update_note_in_collection_anki21 : insert_new_note_in_collection_anki21
109
- true
110
- end
111
-
112
- private
113
-
114
121
  def update_note_in_collection_anki21
115
- statement = @collection.anki_package.prepare <<~SQL
122
+ statement = anki21_database.prepare <<~SQL
116
123
  update notes set guid = ?, mid = ?, mod = ?, usn = ?, tags = ?,
117
124
  flds = ?, sfld = ?, csum = ?, flags = ?, data = ? where id = ?
118
125
  SQL
@@ -123,7 +130,7 @@ module AnkiRecord
123
130
  end
124
131
 
125
132
  def insert_new_note_in_collection_anki21
126
- statement = @collection.anki_package.prepare <<~SQL
133
+ statement = anki21_database.prepare <<~SQL
127
134
  insert into notes (id, guid, mid, mod, usn, tags, flds, sfld, csum, flags, data)
128
135
  values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
129
136
  SQL
@@ -133,38 +140,6 @@ module AnkiRecord
133
140
  cards.each(&:save)
134
141
  end
135
142
 
136
- public
137
-
138
- ##
139
- # Overrides BasicObject#method_missing and creates "ghost methods".
140
- #
141
- # The ghost methods are the setters and getters for the note field values.
142
- def method_missing(method_name, field_content = nil)
143
- raise NoMethodError, "##{method_name} is not defined or a ghost method" unless respond_to_missing? method_name
144
-
145
- method_name = method_name.to_s
146
- return @field_contents[method_name] unless method_name.end_with?("=")
147
-
148
- @field_contents[method_name.chomp("=")] = field_content
149
- end
150
-
151
- ##
152
- # This allows #respond_to? to be accurate for the ghost methods created by #method_missing.
153
- def respond_to_missing?(method_name, *)
154
- method_name = method_name.to_s
155
- if method_name.end_with?("=")
156
- note_type.snake_case_field_names.include?(method_name.chomp("="))
157
- else
158
- note_type.snake_case_field_names.include?(method_name)
159
- end
160
- end
161
-
162
- private
163
-
164
- def globally_unique_id
165
- SecureRandom.uuid.slice(5...15)
166
- end
167
-
168
143
  def field_values_separated_by_us
169
144
  # The ASCII control code represented by hexadecimal 1F is the Unit Separator (US)
170
145
  note_type.snake_case_field_names.map { |field_name| @field_contents[field_name] }.join("\x1F")
@@ -175,4 +150,3 @@ module AnkiRecord
175
150
  end
176
151
  end
177
152
  end
178
- # rubocop:enable Metrics/ClassLength
@@ -1,56 +1,57 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AnkiRecord
4
- # Module with the Note class's attribute readers, writers, and accessors.
4
+ # Module with Note's attribute readers, writers, and accessors.
5
5
  module NoteAttributes
6
+ attr_reader :anki21_database # :nodoc:
7
+
6
8
  ##
7
- # The note's id.
9
+ # The note's id
8
10
  attr_reader :id
9
11
 
10
12
  ##
11
- # The note's globally unique id.
12
- attr_reader :guid
13
+ # The note's globally unique id
14
+ #
15
+ # This is used by Anki to match an imported note to an existing note and
16
+ # update it rather than duplicate the note.
17
+ attr_accessor :guid
13
18
 
14
19
  ##
15
- # The number of seconds since the 1970 epoch at which the note was last modified.
20
+ # The number of seconds since the 1970 epoch when the note was last modified.
16
21
  attr_reader :last_modified_timestamp
17
22
 
18
23
  ##
19
- # The note's update sequence number.
24
+ # The note's update sequence number
20
25
  attr_reader :usn
21
26
 
22
27
  ##
23
- # The note's tags, as an array. The tags are strings.
28
+ # The note's tags, as an array of strings
24
29
  attr_reader :tags
25
30
 
26
31
  ##
27
- # The note's field contents, as a hash.
32
+ # The note's field contents as a hash
28
33
  attr_reader :field_contents
29
34
 
30
35
  ##
31
- # The note's deck object.
36
+ # The note's deck.
32
37
  #
33
- # When the note is saved, the cards will belong to this deck.
38
+ # When the note is saved, the note will belong to this deck
34
39
  attr_reader :deck
35
40
 
36
41
  ##
37
- # The note's note type object.
42
+ # The note's note type
38
43
  attr_reader :note_type
39
44
 
40
45
  ##
41
- # The note's collection object.
42
- attr_reader :collection
43
-
44
- ##
45
- # The note's card objects, as an array.
46
+ # The note's card objects, as an array
46
47
  attr_reader :cards
47
48
 
48
49
  ##
49
- # Corresponds to the flags column in the collection.anki21 notes table.
50
+ # Corresponds to the flags column in the collection.anki21 notes table
50
51
  attr_reader :flags
51
52
 
52
53
  ##
53
- # Corresponds to the data column in the collection.anki21 notes table.
54
+ # Corresponds to the data column in the collection.anki21 notes table
54
55
  attr_reader :data
55
56
  end
56
57
  end
@@ -5,7 +5,7 @@ require_relative "note_field_defaults"
5
5
 
6
6
  module AnkiRecord
7
7
  ##
8
- # NoteField represents a field of an Anki note type.
8
+ # NoteField represents a field of an Anki note type
9
9
  class NoteField
10
10
  include NoteFieldAttributes
11
11
  include NoteFieldDefaults
@@ -17,9 +17,9 @@ module AnkiRecord
17
17
 
18
18
  @note_type = note_type
19
19
  if args
20
- setup_note_field_instance_variables_from_existing(args: args)
20
+ setup_note_field_instance_variables_from_existing(args:)
21
21
  else
22
- setup_note_field_instance_variables_for_new_field(name: name)
22
+ setup_note_field_instance_variables_for_new_field(name:)
23
23
  end
24
24
 
25
25
  @note_type.add_note_field self
@@ -2,38 +2,38 @@
2
2
 
3
3
  module AnkiRecord
4
4
  ##
5
- # Module with the NoteField class's attribute readers, writers, and accessors.
5
+ # Module with NoteField class's attribute readers, writers, and accessors.
6
6
  module NoteFieldAttributes
7
7
  ##
8
- # The field's note type.
8
+ # The field's note type
9
9
  attr_reader :note_type
10
10
 
11
11
  ##
12
- # The field's name.
12
+ # The field's name
13
13
  attr_accessor :name
14
14
 
15
15
  ##
16
- # A boolean that indicates if the field is sticky.
16
+ # A boolean that indicates if the field is sticky
17
17
  attr_accessor :sticky
18
18
 
19
19
  ##
20
- # A boolean that indicates if the field is right to left.
20
+ # A boolean that indicates if the field is right to left
21
21
  attr_accessor :right_to_left
22
22
 
23
23
  ##
24
- # The field's font style used when editing.
24
+ # The field's font style used when editing
25
25
  attr_accessor :font_style
26
26
 
27
27
  ##
28
- # The field's font size used when editing.
28
+ # The field's font size used when editing
29
29
  attr_accessor :font_size
30
30
 
31
31
  ##
32
- # The field's description.
32
+ # The field's description
33
33
  attr_accessor :description
34
34
 
35
35
  ##
36
- # 0 for the first field of the note type, 1 for the second, etc.
36
+ # 0 for the first field of the note type, 1 for the second, etc
37
37
  attr_reader :ordinal_number
38
38
  end
39
39
  end
@@ -10,8 +10,6 @@ require_relative "note_type_defaults"
10
10
  module AnkiRecord
11
11
  ##
12
12
  # NoteType represents an Anki note type (also called a model).
13
- #
14
- # The attributes are documented in the NoteTypeAttributes module.
15
13
  class NoteType
16
14
  include Helpers::SharedConstantsHelper
17
15
  include Helpers::TimeHelper
@@ -21,28 +19,29 @@ module AnkiRecord
21
19
  NOTE_TYPES_WITHOUT_TAGS_AND_VERS_VALUES = ["Basic", "Basic (and reversed card)",
22
20
  "Basic (optional reversed card)", "Basic (type in the answer)"].freeze
23
21
 
24
- def initialize(collection:, name: nil, args: nil)
22
+ ##
23
+ # Instantiates a new note type belonging to +anki21_database+ with name +name+
24
+ def initialize(anki21_database:, name: nil, args: nil)
25
25
  raise ArgumentError unless (name && args.nil?) || (args && args["name"])
26
26
 
27
- @collection = collection
27
+ @anki21_database = anki21_database
28
28
 
29
29
  if args
30
- setup_note_type_instance_variables_from_existing(args: args)
30
+ setup_note_type_instance_variables_from_existing(args:)
31
31
  else
32
- setup_instance_variables_for_new_note_type(name: name)
32
+ setup_instance_variables_for_new_note_type(name:)
33
33
  end
34
34
 
35
- @collection.add_note_type self
36
- save
35
+ @anki21_database.add_note_type self
37
36
  end
38
37
 
39
38
  ##
40
39
  # Saves the note type to the collection.anki21 database
41
40
  def save
42
- collection_models_hash = collection.models_json
41
+ collection_models_hash = anki21_database.models_json
43
42
  collection_models_hash[@id] = to_h
44
43
  sql = "update col set models = ? where id = ?"
45
- collection.anki_package.prepare(sql).execute([JSON.generate(collection_models_hash), collection.id])
44
+ anki21_database.prepare(sql).execute([JSON.generate(collection_models_hash), anki21_database.collection.id])
46
45
  end
47
46
 
48
47
  def to_h # :nodoc:
@@ -68,7 +67,7 @@ module AnkiRecord
68
67
  end
69
68
 
70
69
  def snake_case_field_names # :nodoc:
71
- field_names_in_order.map { |field_name| field_name.downcase.gsub(" ", "_") }
70
+ field_names_in_order.map { |field_name| field_name.downcase.tr(" ", "_") }
72
71
  end
73
72
 
74
73
  ##
@@ -78,7 +77,7 @@ module AnkiRecord
78
77
  end
79
78
 
80
79
  def snake_case_sort_field_name # :nodoc:
81
- sort_field_name.downcase.gsub(" ", "_")
80
+ sort_field_name.downcase.tr(" ", "_")
82
81
  end
83
82
 
84
83
  ##
@@ -109,8 +108,8 @@ module AnkiRecord
109
108
  private
110
109
 
111
110
  def setup_note_type_instance_variables_from_existing(args:)
112
- setup_collaborator_object_instance_variables_from_existing(args: args)
113
- setup_simple_instance_variables_from_existing(args: args)
111
+ setup_collaborator_object_instance_variables_from_existing(args:)
112
+ setup_simple_instance_variables_from_existing(args:)
114
113
  end
115
114
 
116
115
  def setup_collaborator_object_instance_variables_from_existing(args:)
@@ -2,70 +2,68 @@
2
2
 
3
3
  module AnkiRecord
4
4
  ##
5
- # Module with the NoteType class's attribute readers, writers, and accessors.
5
+ # Module with the NoteType class's attribute readers, writers, and accessors
6
6
  module NoteTypeAttributes
7
- ##
8
- # The note type's collection object.
9
- attr_reader :collection
7
+ attr_reader :anki21_database, :latex_svg, :tags, :req, :vers
10
8
 
11
9
  ##
12
- # The note type's id.
10
+ # The note type's id
13
11
  attr_reader :id
14
12
 
15
13
  ##
16
- # The note type's name.
14
+ # The note type's name
17
15
  attr_accessor :name
18
16
 
19
17
  ##
20
- # A boolean that indicates if this note type is a cloze-deletion note type.
18
+ # A boolean that indicates if this note type is a cloze-deletion note type
21
19
  attr_accessor :cloze
22
20
 
23
21
  ##
24
- # The number of seconds since the 1970 epoch at which the note type was last modified.
22
+ # The number of seconds since the 1970 epoch at which the note type was last modified
25
23
  attr_reader :last_modified_timestamp
26
24
 
27
25
  ##
28
- # The note type's update sequence number.
26
+ # The note type's update sequence number
29
27
  attr_reader :usn
30
28
 
31
29
  ##
32
- # The note type's sort field.
30
+ # The note type's sort field
33
31
  attr_reader :sort_field
34
32
 
35
33
  ##
36
- # The note type's CSS.
34
+ # The note type's CSS
37
35
  attr_accessor :css
38
36
 
39
37
  ##
40
- # The note type's LaTeX preamble.
38
+ # The note type's LaTeX preamble
41
39
  attr_reader :latex_preamble
42
40
 
43
41
  ##
44
- # The note type's LaTeX postamble.
42
+ # The note type's LaTeX postamble
45
43
  attr_reader :latex_postamble
46
44
 
47
45
  ##
48
- # The note type's card template objects, as an array.
46
+ # The note type's card template objects, as an array
49
47
  attr_reader :card_templates
50
48
 
51
49
  ##
52
- # The note type's field objects, as an array.
50
+ # The note type's field objects, as an array
53
51
  attr_reader :note_fields
54
52
 
55
53
  ##
56
- # The note type's deck's id.
54
+ # The note type's deck's id
57
55
  attr_reader :deck_id
58
56
 
59
57
  ##
60
- # The note type's deck.
58
+ # The note type's deck
61
59
  def deck
62
60
  return nil unless @deck_id
63
61
 
64
- @collection.find_deck_by id: @deck_id
62
+ anki21_database.find_deck_by id: @deck_id
65
63
  end
66
64
 
67
65
  ##
68
- # Sets the note type's deck object.
66
+ # Sets the note type's deck object
69
67
  def deck=(deck)
70
68
  unless deck.instance_of?(AnkiRecord::Deck)
71
69
  raise ArgumentError,
@@ -74,7 +72,5 @@ module AnkiRecord
74
72
 
75
73
  @deck_id = deck.id
76
74
  end
77
-
78
- attr_reader :latex_svg, :tags, :req, :vers
79
75
  end
80
76
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AnkiRecord
4
- VERSION = "0.3.1" # :nodoc:
4
+ VERSION = "0.4" # :nodoc:
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anki_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: '0.4'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyle Rego
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-29 00:00:00.000000000 Z
11
+ date: 2023-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip
@@ -38,8 +38,8 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.3'
41
- description: " A Ruby library which provides a programmatic interface to Anki flashcard
42
- decks (.apkg files/zipped Anki SQLite databases).\n"
41
+ description: " Anki Record lets you create Anki deck packages or update existing
42
+ ones with the Ruby programming language.\n"
43
43
  email:
44
44
  - regoky@outlook.com
45
45
  executables: []
@@ -57,6 +57,10 @@ files:
57
57
  - Rakefile
58
58
  - anki_record.gemspec
59
59
  - lib/anki_record.rb
60
+ - lib/anki_record/anki21_database/anki21_database.rb
61
+ - lib/anki_record/anki21_database/anki21_database_attributes.rb
62
+ - lib/anki_record/anki21_database/anki21_database_constructors.rb
63
+ - lib/anki_record/anki2_database/anki2_database.rb
60
64
  - lib/anki_record/anki_package/anki_package.rb
61
65
  - lib/anki_record/card/card.rb
62
66
  - lib/anki_record/card/card_attributes.rb
@@ -70,10 +74,11 @@ files:
70
74
  - lib/anki_record/deck/deck_defaults.rb
71
75
  - lib/anki_record/deck_options_group/deck_options_group.rb
72
76
  - lib/anki_record/deck_options_group/deck_options_group_attributes.rb
77
+ - lib/anki_record/helpers/anki_guid_helper.rb
73
78
  - lib/anki_record/helpers/checksum_helper.rb
74
- - lib/anki_record/helpers/data_query_helper.rb
75
79
  - lib/anki_record/helpers/shared_constants_helper.rb
76
80
  - lib/anki_record/helpers/time_helper.rb
81
+ - lib/anki_record/media/media.rb
77
82
  - lib/anki_record/note/note.rb
78
83
  - lib/anki_record/note/note_attributes.rb
79
84
  - lib/anki_record/note_field/note_field.rb
@@ -109,5 +114,5 @@ requirements: []
109
114
  rubygems_version: 3.4.6
110
115
  signing_key:
111
116
  specification_version: 4
112
- summary: Automate Anki flashcard editing with the Ruby programming language.
117
+ summary: Create and update Anki deck packages with Ruby.
113
118
  test_files: []
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AnkiRecord
4
- module Helpers
5
- module DataQueryHelper # :nodoc:
6
- def note_cards_data_for_note_id(sql_able:, id:)
7
- note_data = sql_able.prepare("select * from notes where id = ?").execute([id]).first
8
- return nil unless note_data
9
-
10
- cards_data = sql_able.prepare("select * from cards where nid = ?").execute([id]).to_a
11
- { note_data: note_data, cards_data: cards_data }
12
- end
13
- end
14
- end
15
- end