Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.0 Queries: Base query class (meta, dates, caching) #6331

Closed
35 tasks done
JJJ opened this issue Jan 26, 2018 · 10 comments
Closed
35 tasks done

3.0 Queries: Base query class (meta, dates, caching) #6331

JJJ opened this issue Jan 26, 2018 · 10 comments
Assignees
Milestone

Comments

@JJJ
Copy link
Contributor

JJJ commented Jan 26, 2018

Tracking issue: #4576

Pull request: #6333

TL;DR

Transition Payments/Discounts/Logs/Notes/Orders/Order-Items post-types to custom component database tables, most paired with meta. Architect a traditional WordPress query interface that's simple and DRY for all of them to maintain developer happiness.

Summary

One technical challenge for EDD3 is the introduction of approximately 12 new database tables (for a total of 14.) The reason for this move is to ultimately provide a more scalable application without a requirement for third-party horizontal scaling techniques (multiple servers; WordPress drop-in plugins; cache/db/lb/web/etc...)

By scaling the databases horizontally by default, EDD can better control the flow of data internally without compromising performance. Put another way, by not storing everything as a custom post type & post-meta, EDD can avoid hurting the performance of other post-type related data, while also improving its own efficiency.

It's a win-win for everyone, but with a hidden caveat...

We learned first-hand (via BuddyPress and Multisite) that the above approach works well-enough at providing a stable foundation for scaling a complex WordPress application, but we also learned having more than a half-dozen different interfaces for interacting with new & unique components in WordPress is a hugely negative experience for traditional WordPress developers.

Each new component/meta relationship is a new hurdle to jump, and too many hurdles leaves developers exhausted and unhappy.

I'm proposing (and working on) a mostly-magic base query-class for all custom database tables to extend, that will automatically make every new table queryable using the same basic parameters, provide object caching for those individual items, without compromising either application performance or developer joy.

Kinda like an ORM, but without the need to relearn the WordPress way of querying for things.

How does it work?

  1. Component classes provide an array of column definitions and other component attributes
  2. Column definitions help determine the shape of the component item
  3. That shape helps define the queryable columns
  4. Queries are cached by an md5 hash of parameters used
  5. Items are cached by their ID

Components

Here is the master list of components, alphabetically. Each will get checked when complete:

  • Customers
  • Discounts
  • Logs (General)
  • Logs (API Requests, No Meta)
  • Logs (Downloads, No Meta)
  • Notes
  • Orders
  • Order Items (Linked to Orders)

Orders (Previously Payments)

Table/schema completed (see #6277)

Query vars

  • id
  • id__in
  • id__not_on
  • number
  • number__in
  • number__not_in
  • status
  • status__in
  • status__not_in
  • user_id
  • user__in
  • user__not_in
  • customer_id
  • customer__in
  • customer__not_in
  • email
  • email__in
  • email__not_in
  • gateway
  • gateway__in
  • gateway__not_in
  • payment_key
  • payment_key__in
  • payment_key__not_in
  • date_created_query
  • date_completed_query
  • meta_query
@JJJ JJJ self-assigned this Jan 26, 2018
@JJJ JJJ added this to the 3.0 milestone Jan 26, 2018
@pippinsplugins
Copy link
Contributor

Add gateway, gateway_in, and gateway__not_in please.

JJJ added a commit that referenced this issue Jan 26, 2018
@JJJ
Copy link
Contributor Author

JJJ commented Jan 26, 2018

Add gateway, gateway_in, and gateway__not_in please.

Added.

JJJ added a commit that referenced this issue Jan 26, 2018
@cklosowski
Copy link
Contributor

@JJJ looks like gateway came out as gateway_key in the list above, is that intended?

@JJJ
Copy link
Contributor Author

JJJ commented Jan 26, 2018

looks like gateway came out as gateway_key in the list above, is that intended?

Copy/pasta. Fixed.

JJJ added a commit that referenced this issue Jan 26, 2018
Adjust `EDD_DB_Order_Query` to be a subclass of this new class, and define the database columns in a new helper class: `EDD_DB_Column`.

`EDD_DB_Column` might be temporary, or not really necessary, but it did help me structure and scaffold much of the automation that's happening now.

See #6331.
@JJJ
Copy link
Contributor Author

JJJ commented Jan 26, 2018

Crud; I included a file that was part of a different stash, so I'm gonna clean that up quick.

@JJJ
Copy link
Contributor Author

JJJ commented Jan 26, 2018

OK, here's where this is at now:

  • wp_edd_orders has full support for querying single/__in/__not_in most columns
  • date_created and date_completed have WP_Date_Query support
  • meta_query support is in via WP_Meta_Query
  • The base EDD_DB_Query class is the base class that other query classes can extend. It automatically sets up what type of queries are possible based on database column definitions. It's a lot like EDD_DB but on steroids to be more DRY.
  • Check out EDD_DB_Order_Query for how sparse each query class will now be, if we choose to go this route. (I think there's opportunity to make this even cleaner once I get the base object classes in.)
  • There's a lot to like, and a lot to be critical of, so reviews from @sunnyratilal @cklosowski @pippinsplugins are encouraged. Very much WIP still, emphasis on W.
  • This is, basically, a kill 8 birds with 1 stone approach to querying all of our new database tables.

@JJJ JJJ changed the title 3.0 Orders: Query class, Meta query, Date queries, Caching 3.0 Queries: Base query class (meta, dates, caching) Jan 29, 2018
JJJ added a commit that referenced this issue Jan 29, 2018
* Explicitly define vars as `public` so they are accessible to list filtering APIs
* Remove smart column methods (premature optimization)
* Sanitize vars from arguments provided
* General odds & ends clean-up

See #6331, #6333.
JJJ added a commit that referenced this issue Jan 29, 2018
JJJ added a commit that referenced this issue Jan 29, 2018
Also update the alias to `o` for `orders`.

See #6331, #6333.
JJJ added a commit that referenced this issue Jan 29, 2018
JJJ added a commit that referenced this issue Jan 29, 2018
JJJ added a commit that referenced this issue Jan 30, 2018
JJJ added a commit that referenced this issue Jan 30, 2018
JJJ added a commit that referenced this issue Jan 30, 2018
JJJ added a commit that referenced this issue Jan 30, 2018
JJJ added a commit that referenced this issue Jan 30, 2018
JJJ added a commit that referenced this issue Jan 30, 2018
(Needs updated docs.)

See #6331, #6333.
sunnyratilal added a commit that referenced this issue Apr 6, 2018
sunnyratilal added a commit that referenced this issue Apr 6, 2018
sunnyratilal added a commit that referenced this issue Apr 6, 2018
* Do not allow direct instanation of core objects; only the query class can instantiate objects.

* All protected properties can no longer be directly accessed. A getter is required.

* See #6331
sunnyratilal added a commit that referenced this issue Apr 6, 2018
sunnyratilal added a commit that referenced this issue Apr 9, 2018
JJJ added a commit that referenced this issue Apr 15, 2018
JJJ added a commit that referenced this issue Apr 15, 2018
We'll use this to automatically set the datetime value when an item is modified.

See #6331.
JJJ added a commit that referenced this issue Apr 15, 2018
JJJ added a commit that referenced this issue Apr 15, 2018
JJJ added a commit that referenced this issue Apr 15, 2018
This commit simplifies some column logic, removes a few class properties, adds a `get_column_field()` method, and automatically saves created and modified times when adding & updating items.

See #6331.
JJJ added a commit that referenced this issue Apr 15, 2018
This will eventually use Carbon (or a utility function) but it's easy to use `gmtime()` to get going.

See #6331.
JJJ added a commit that referenced this issue Apr 15, 2018
These were previously public while we determined the class properties.

See #6331.
JJJ added a commit that referenced this issue Apr 16, 2018
This prevents the saving of unknown fields, and avoids needing to blacklist fields like nonces & referrers.

See #6331.
@sunnyratilal
Copy link
Contributor

Closing out as this has been completed. Any bugs found during alpha/beta testing should be opened as new issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants