Skip to content

RobertoMike/Baradum

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

53 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Welcome to Baradum

Maven Central License Test Coverage

Baradum is a powerful library that simplifies filtering and sorting in your Java/Kotlin applications. It allows you to dynamically filter and sort database queries using URL parameters or request body, eliminating the need for complex conditional logic.

πŸš€ What's New in Latest Version

  • 🎯 Type-Safe Kotlin API: Use property references (User::name) for compile-time safety
  • πŸ“… Enhanced DateFilter: Support for LocalDate, LocalDateTime, java.util.Date, SQL dates with custom patterns
  • πŸ”’ New Comparison Filters: GreaterFilter and LessFilter with configurable equality
  • πŸ—οΈ Builder Patterns: Fluent APIs for complex filter configurations
  • πŸ“š Comprehensive Documentation: Complete API reference and migration guides
  • πŸ”§ Multiple Backend Support: Hefesto (HefestoSQL) and QueryDSL integrations

πŸ“‹ Table of Contents

πŸ“¦ Installation

Module Overview

Baradum is split into multiple modules for flexibility:

Module Purpose Dependencies
baradum-core Core filtering/sorting logic None (standalone)
baradum-hefesto HefestoSQL integration baradum-core, HefestoSQL
baradum-querydsl QueryDSL integration baradum-core, QueryDSL 5.0+
apache-tomcat Spring Boot auto-config baradum-core, Spring Boot

Core Library

MavenGradle
<!-- Core + Hefesto (Hibernate/HefestoSQL) -->
<dependency>
    <groupId>io.github.robertomike</groupId>
    <artifactId>baradum-hefesto</artifactId>
    <version>3.0.0</version>
</dependency>

<!-- OR QueryDSL (Type-safe queries) -->
<dependency>
    <groupId>io.github.robertomike</groupId>
    <artifactId>baradum-querydsl</artifactId>
    <version>3.0.0</version>
</dependency>
dependencies {
    // Hefesto (Hibernate/HefestoSQL)
    implementation 'io.github.robertomike:baradum-hefesto:3.0.0'
    
    // OR QueryDSL (Type-safe queries)
    implementation 'io.github.robertomike:baradum-querydsl:3.0.0'
}

Spring Boot Integration

MavenGradle
<!-- Spring Boot 3 (Jakarta) -->
<dependency>
  <groupId>io.github.robertomike</groupId>
  <artifactId>baradum-apache-tomcat</artifactId>
  <version>3.0.0</version>
</dependency>
dependencies {
    // Spring Boot 3 (Jakarta)
    implementation 'io.github.robertomike:baradum-apache-tomcat:3.0.0'
}

QueryDSL Module (NEW in 3.0.0)

For type-safe queries with QueryDSL 5.0+ and Jakarta Persistence:

MavenGradle
<dependency>
  <groupId>io.github.robertomike</groupId>
  <artifactId>baradum-querydsl</artifactId>
  <version>3.0.0</version>
</dependency>
dependencies {
    implementation 'io.github.robertomike:baradum-querydsl:3.0.0'
}

Features:

  • βœ… Full QueryDSL integration with type-safe queries
  • βœ… Extension functions for Q-classes: QUser.user.baradum(em)
  • βœ… Jakarta Persistence (JPA 3.0+) support
  • βœ… 11.76x performance boost with global caching
  • βœ… Comprehensive test coverage (90+ tests)

Quick Example:

val users = QUser.user
    .baradum(entityManager)
    .allowedFilters(
        ExactFilter(User::name),
        GreaterFilter(User::age, orEqual = true)
    )
    .withParams(request.parameterMap)
    .get()

See baradum-querydsl/README.md for complete documentation.

πŸ† Test Coverage

Module Coverage Tests Status
baradum-core 83.8% 327 tests βœ… Excellent
baradum-hefesto 82.7% 198 tests βœ… Excellent
baradum-querydsl 74.1% 91 tests βœ… Good
Overall 80.9% 616 tests βœ… Very Good

All core functionality is thoroughly tested with unit and integration tests.

🎯 Quick Start

The Problem

Without Baradum (Traditional Approach):

@GetMapping("/users")
public List<User> getUsers(
    @RequestParam(required = false) Long categoryId,
    @RequestParam(required = false) Integer minAge,
    @RequestParam(required = false) Integer maxAge
) {
    if (categoryId != null && minAge != null && maxAge != null) {
        return repository.findByCategoryIdAndAgeGreaterThanEqualAndAgeLessThanEqual(
            categoryId, minAge, maxAge
        );
    }
    if (categoryId != null && minAge != null) {
        return repository.findByCategoryIdAndAgeGreaterThanEqual(categoryId, minAge);
    }
    if (minAge != null && maxAge != null) {
        return repository.findByAgeGreaterThanEqualAndAgeLessThanEqual(minAge, maxAge);
    }
    // ... 5 more conditional branches
    return repository.findAll();
}

The Solution

With Baradum:

@GetMapping("/users")
public List<User> getUsers() {
    return Baradum.make(User.class)
        .allowedFilters("categoryId")
        .allowedFilters(new IntervalFilter("age"))
        .page();
}

Kotlin with Type Safety:

@GetMapping("/users")
fun getUsers(): List<User> {
    return Baradum.make(User::class.java)
        .allowedFilters(
            ExactFilter(User::categoryId),
            IntervalFilter(User::age)
        )
        .page()
}

URL Usage:

  • ?categoryId=2 β†’ Filters by categoryId = 2
  • ?age=18-65 β†’ Filters by age >= 18 AND age <= 65
  • ?categoryId=2&age=18-65 β†’ Both filters applied

πŸ“š Filter Types

Core Filters

Filter Purpose Example URL SQL Result
ExactFilter Exact matching ?status=ACTIVE status = 'ACTIVE'
PartialFilter LIKE search ?name=john name LIKE 'john%'
SearchFilter Multi-field OR ?search=john name LIKE '%john%' OR email LIKE '%john%'
EnumFilter Enum values ?status=ACTIVE,PENDING status IN ('ACTIVE', 'PENDING')
IntervalFilter Numeric ranges ?age=18-65 age >= 18 AND age <= 65
InFilter Multiple values ?country=US,CA,MX country IN ('US', 'CA', 'MX')
IsNullFilter NULL checks ?deletedAt=null deletedAt IS NULL

Comparison Filters

Filter Purpose Example URL SQL Result
ComparisonFilter Flexible operators ?price=>100 price > 100
GreaterFilter Greater than ?age=18 age > 18 or age >= 18
LessFilter Less than ?age=65 age < 65 or age <= 65

Date & Time Filters

Filter Purpose Example URL SQL Result
DateFilter Date filtering ?date=2024-01-01|2024-12-31 date BETWEEN '2024-01-01' AND '2024-12-31'
Comparison ?date=>2024-01-01 date > '2024-01-01'

Advanced

Filter Purpose Example Description
CustomFilter Lambda logic See docs Custom filtering logic

🎭 Kotlin Property References (Type-Safe API)

Use Kotlin property references for compile-time safety:

data class User(
    val id: Long,
    val name: String,
    val email: String,
    val age: Int,
    val status: Status,
    val createdAt: LocalDateTime
)

@GetMapping("/users")
fun getUsers(): List<User> {
    return Baradum.make(User::class.java)
        .allowedFilters(
            ExactFilter(User::id),                              // ?id=123
            PartialFilter(User::name, "search"),                // ?search=john
            EnumFilter(User::status, Status::class.java),       // ?status=ACTIVE
            IntervalFilter(User::age),                          // ?age=18-65
            DateFilter.forLocalDateTime(User::createdAt),       // ?createdAt=>2024-01-01
            GreaterFilter(User::age, "minAge", orEqual = true), // ?minAge=18
            LessFilter(User::age, "maxAge", orEqual = true)     // ?maxAge=65
        )
        .allowedSort(User::name, User::createdAt)
        .page()
}

Benefits:

  • βœ… Compile-time field validation
  • βœ… Refactoring support
  • βœ… IDE auto-completion
  • βœ… Type safety

πŸ“… Date Filtering

Multiple Date Types Supported

// LocalDate (default)
DateFilter("createdAt")

// LocalDateTime with custom pattern
DateFilter.forLocalDateTime("updatedAt", "dd/MM/yyyy HH:mm:ss")

// java.util.Date
DateFilter.forUtilDate("birthDate", "MM-dd-yyyy")

// SQL Date
DateFilter.forSqlDate("startDate")

// SQL Timestamp
DateFilter.forSqlTimestamp("eventTime")

// Builder pattern
DateFilter.builder("eventDate")
    .useLocalDate()
    .withPattern("yyyy/MM/dd")
    .build()

Date Filtering Examples

URL Parameter SQL Result
?date=2024-01-01 date = '2024-01-01'
?date=2024-01-01|2024-12-31 date >= '2024-01-01' AND date <= '2024-12-31'
?date=>2024-01-01 date > '2024-01-01'
?date=>=2024-01-01 date >= '2024-01-01'
?date=<2024-12-31 date < '2024-12-31'
?date=<=2024-12-31 date <= '2024-12-31'

πŸ“Š Sorting

Simple Sorting

return Baradum.make(User.class)
    .allowedSort("name", "createdAt")
    .get();

URL Examples:

  • ?sort=name β†’ ORDER BY name ASC
  • ?sort=-name β†’ ORDER BY name DESC
  • ?sort=name,-createdAt β†’ ORDER BY name ASC, createdAt DESC

Custom Field Names

.allowedSort(new OrderBy("alias", "actual_field_name"))

Kotlin Property References

.allowedSort(User::name, User::createdAt, User::email)

πŸ“ Body-Based Filtering

For complex filtering scenarios, use JSON body:

{
    "filters": [
        {
            "field": "id",
            "value": "1",
            "operator": "EQUAL"
        },
        {
            "field": "name",
            "value": "abc%",
            "operator": "LIKE",
            "type": "OR"
        },
        {
            "field": "status",
            "operator": "IS_NULL",
            "type": "AND"
        },
        {
            "subFilters": [
                {
                    "field": "status",
                    "value": "ACTIVE,INACTIVE",
                    "operator": "IN",
                    "type": "OR"
                }
            ]
        }
    ],
    "sorts": [
        {
            "field": "id"
        },
        {
            "field": "name",
            "sort": "DESC"
        }
    ]
}

βš™οΈ Configuration

Spring Boot (Auto-Configuration)

No configuration needed! Spring Boot 2 & 3 are auto-configured.

Manual Configuration

public class BaradumConfig {
    @Bean
    public void configureBaradum(HttpServletRequest request) {
        // For Apache Tomcat 9 (Spring Boot 2)
        new AutoConfigurationSpring2(request);
        
        // For Apache Tomcat 10 (Spring Boot 3)
        new AutoConfigurationSpring3(request);
    }
}

Custom Request Implementation

public class MyCustomRequest extends BasicRequest<HttpServletRequest> {
    public MyCustomRequest(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String findParamByName(String name) {
        return getRequest().getParameter(name);
    }

    @Override
    public String getMethod() {
        return getRequest().getMethod();
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return getRequest().getReader();
    }
}

// Configure Baradum
Baradum.setRequest(new MyCustomRequest(request));

πŸ“– Documentation

πŸ’‘ Examples

E-commerce Product Filtering

@GetMapping("/products")
fun getProducts(): Page<Product> {
    return Baradum.make(Product::class.java)
        .allowedFilters(
            ExactFilter(Product::category),
            PartialFilter(Product::name, "search"),
            GreaterFilter(Product::price, "minPrice", orEqual = true),
            LessFilter(Product::price, "maxPrice", orEqual = true),
            EnumFilter(Product::status, ProductStatus::class.java),
            InFilter(Product::brand, "brands")
        )
        .allowedSort(Product::price, Product::name)
        .page()
}

Usage:

GET /products?category=electronics&search=laptop&minPrice=500&maxPrice=2000
    &brands=Apple,Dell,HP&status=IN_STOCK&sort=price

User Management

@GetMapping("/users")
public List<User> getUsers() {
    return Baradum.make(User.class)
        .allowedFilters(
            PartialFilter("username"),
            SearchFilter.of("search", "username", "email", "fullName"),
            EnumFilter("role", Role.class),
            DateFilter.forLocalDateTime("createdAt"),
            IntervalFilter("age"),
            IsNullFilter("deletedAt")
        )
        .allowedSort("username", "createdAt")
        .get();
}

Usage:

GET /users?search=john&role=ADMIN&age=25-50&deletedAt=null&sort=-createdAt

Event Calendar

@GetMapping("/events")
public List<Event> getEvents() {
    return Baradum.make(Event.class)
        .allowedFilters(
            ExactFilter("organizerId"),
            PartialFilter("title"),
            DateFilter.builder("eventDate")
                .useLocalDateTime()
                .withPattern("yyyy-MM-dd HH:mm")
                .build(),
            GreaterFilter("attendeeCount", "minAttendees", true),
            InFilter("location")
        )
        .allowedSort("eventDate", "title")
        .page();
}

Usage:

GET /events?title=concert&eventDate=>2024-01-01&minAttendees=100
    &location=NY,LA,CHI&sort=eventDate

πŸ”§ Advanced Features

Default Values

ExactFilter("status").setDefaultValue("ACTIVE")

Ignoring Values

IntervalFilter("age").addIgnore("0", "null", "")

Custom Filters

new CustomFilter<>("status", (query, value) -> {
    if (value.equals("premium")) {
        query.where("subscription_level", BaradumOperator.GREATER, 5);
    } else {
        query.where("status", BaradumOperator.EQUAL, value);
    }
})

⚠️ Important Notes

  • Swagger/OpenAPI: Manual documentation required (no auto-generation support)
  • Spring Boot: Versions 2 & 3 supported
  • Apache Tomcat: Versions 9 & 10 supported

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE.txt file for details.

β˜• Support

If you find this library helpful, consider buying me a coffee!

Buy Me A Coffee


Made with ❀️ by Roberto Mike

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •