Skip to content

HwangInUng/data-morph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

34 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

DataMorph

Java 11+ MIT License Gradle

๐Ÿš€ Overview

DataMorph๋Š” ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์†Œ์Šค(CSV, JSON)๋ฅผ ํŒŒ์‹ฑํ•˜๊ณ  ๋ณ€ํ™˜ํ•˜๋Š” Java ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ์ง๊ด€์ ์ธ Fluent API๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ์ž‘์—…์„ ์ฒด์ด๋‹ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์ ์ธ ์ŠคํŠธ๋ฆฌ๋ฐ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

โœจ Key Features

  • ๐Ÿ”„ Fluent API: ์ง๊ด€์ ์ธ ๋ฉ”์„œ๋“œ ์ฒด์ด๋‹์„ ํ†ตํ•œ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜
  • ๐Ÿ“Š Multiple Data Sources: ํŒŒ์ผ, ๋ฌธ์ž์—ด, ๊ฐ์ฒด ๋ฆฌ์ŠคํŠธ, ์ŠคํŠธ๋ฆผ ์ง€์›
  • ๐Ÿš€ Streaming Processing: ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ์œ„ํ•œ ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์  ์ฒ˜๋ฆฌ
  • ๐Ÿ”ง POJO Mapping: ๋ฆฌํ”Œ๋ ‰์…˜ ๊ธฐ๋ฐ˜ ์–‘๋ฐฉํ–ฅ ๊ฐ์ฒด ๋ณ€ํ™˜
  • ๐Ÿ“ˆ Memory Monitoring: JMX ๊ธฐ๋ฐ˜ ์‹ค์‹œ๊ฐ„ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ถ”์ 
  • ๐ŸŽฏ Zero Dependencies: ์ˆœ์ˆ˜ Java ๊ตฌํ˜„์œผ๋กœ ๊ฐ€๋ฒผ์šด ์šฉ๋Ÿ‰

๐ŸŽฏ Why DataMorph?

DataMorph vs. ๊ธฐ์กด ๋ฐฉ์‹
ํ†ตํ•ฉ๋œ ๋‹จ์ผ API ์—ฌ๋Ÿฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์กฐํ•ฉ ํ•„์š”
Zero Dependencies Multi Dependencies
์ฆ‰์‹œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๋ณต์žกํ•œ ์„ค์ •
์ŠคํŠธ๋ฆฌ๋ฐ ์ฒ˜๋ฆฌ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ์œ„ํ—˜

๐Ÿ“ฆ Installation

Gradle (Kotlin DSL)

repositories {
    mavenCentral()
    maven { url = uri("https://jitpack.io") }
}

dependencies {
    implementation("com.github.HwangInUng:data-morph:1.0.0")
}

Gradle (Groovy)

repositories {
    mavenCentral()
    maven { url 'https://jitpack.io' }
}

dependencies {
    implementation 'com.github.HwangInUng:data-morph:1.0.0'
}

Maven

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>com.github.HwangInUng</groupId>
        <artifactId>data-morph</artifactId>
        <version>1.0.0</version>
    </dependency>
</dependencies>

๐Ÿš€ Quick Start

๊ธฐ๋ณธ ํŒŒ์ผ ์ฒ˜๋ฆฌ

// CSV ํŒŒ์ผ ์ฝ๊ธฐ ๋ฐ ๋ณ€ํ™˜
DataSource dataSource = DataMorph.from("employees.csv");

List<DataRow> results = dataSource
    .filter(row -> row.getInt("age") > 30)
    .transform(row -> {
        Integer salary = row.getInt("salary");
        if (salary != null) {
            row.set("salary", (int)(salary * 1.1)); // 10% ์ธ์ƒ
        }
    })
    .toList();

// ๊ฒฐ๊ณผ๋ฅผ ํŒŒ์ผ๋กœ ์ €์žฅ
dataSource.toFile("processed_employees.csv");

๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ

// JSON ๋ฌธ์ž์—ด ํŒŒ์‹ฑ
String jsonData = "[{\"name\":\"John\",\"age\":30},{\"name\":\"Jane\",\"age\":25}]";
DataSource dataSource = DataMorph.fromString(jsonData, Format.JSON);

List<DataRow> adults = dataSource
    .filter(row -> row.getInt("age") >= 18)
    .toList();

๊ฐ์ฒด ๋ฆฌ์ŠคํŠธ ์ฒ˜๋ฆฌ

// POJO ๊ฐ์ฒด ๋ฆฌ์ŠคํŠธ ๋ณ€ํ™˜
List<Employee> employees = Arrays.asList(
    new Employee("John", 30, 50000),
    new Employee("Jane", 25, 45000)
);

DataSource dataSource = DataMorph.fromObjects(employees);
List<Employee> processedEmployees = dataSource
    .transform(Transform.builder()
        .rename("emp_name", "name")
        .add("bonus", 1000)
        .build())
    .toList(Employee.class);

๐Ÿ“š API Reference

์ž์„ธํ•œ API ๋ฌธ์„œ๋Š” API Reference๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.


๐ŸŽจ Examples

๋‹ค์–‘ํ•œ ์‚ฌ์šฉ ์˜ˆ์ œ๋Š” Examples๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.


๐Ÿ—๏ธ Architecture

ํŒจํ‚ค์ง€ ๊ตฌ์กฐ

com.datamorph/
โ”œโ”€โ”€ core/                    # ํ•ต์‹ฌ API (DataMorph, DataSource, DataRow)
โ”œโ”€โ”€ parser/                  # ํŒŒ์ผ ํŒŒ์‹ฑ ์—”์ง„ (CSV, JSON)
โ”œโ”€โ”€ writer/                  # ํŒŒ์ผ ์ถœ๋ ฅ ์—”์ง„ (CSV, JSON)
โ”œโ”€โ”€ transform/               # ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ์—”์ง„
โ”œโ”€โ”€ mapper/                  # POJO ๋งคํ•‘ ์—”์ง„
โ”œโ”€โ”€ streaming/               # ์ŠคํŠธ๋ฆฌ๋ฐ ์ฒ˜๋ฆฌ ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ
โ”œโ”€โ”€ util/                    # ์œ ํ‹ธ๋ฆฌํ‹ฐ (ํฌ๋งท ๊ฐ์ง€)
โ””โ”€โ”€ exceptions/              # ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

ํด๋ž˜์Šค ๋‹ค์ด์–ด๊ทธ๋žจ

classDiagram
    class DataMorph {
        +from(filePath) DataSource
        +fromString(content, format) DataSource
        +fromObjects(objects) DataSource
        +fromStream(stream, format) DataSource
    }
    
    class DataSource {
        +transform(transformer) DataSource
        +transform(transform) DataSource
        +filter(predicate) DataSource
        +toList() List~DataRow~
        +toList(clazz) List~T~
        +toFile(path) void
        +toString(format) String
    }
    
    class DataRow {
        +getString(field) String
        +getInt(field) Integer
        +getDouble(field) Double
        +getBoolean(field) Boolean
        +set(field, value) void
        +has(field) boolean
        +remove(field) Object
    }
    
    class Transform {
        +builder() TransformBuilder
        +apply(row) DataRow
    }
    
    class ObjectMapper {
        +toObject(row, clazz) T
        +toDataRow(object) DataRow
    }
    
    class MemoryMonitor {
        +checkMemoryUsage() void
        +getMemoryUsageRatio() double
        +isMemoryPressureHigh() boolean
    }
    
    DataMorph --> DataSource
    DataSource --> DataRow
    DataSource --> Transform
    DataSource --> ObjectMapper
    DataSource --> MemoryMonitor
Loading

๐Ÿ”ง Advanced Features

์ŠคํŠธ๋ฆฌ๋ฐ ์ฒ˜๋ฆฌ

// ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ ์ฒ˜๋ฆฌ (๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์ )
DataSource largeDataSource = DataMorph.fromStreamFile("large_data.csv");

List<DataRow> results = largeDataSource
    .filter(row -> row.getInt("score") > 80)
    .transform(row -> row.set("grade", "A"))
    .toList();

๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋‹ˆํ„ฐ๋ง

MemoryMonitor monitor = new MemoryMonitor();

// ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ํ™•์ธ
monitor.checkMemoryUsage();

// ๋ฉ”๋ชจ๋ฆฌ ์ •๋ณด ์ถœ๋ ฅ
System.out.println(monitor.getMemoryInfo());

ํŒŒ์ผ ํฌ๋งท ๋ณ€ํ™˜

// CSV๋ฅผ JSON์œผ๋กœ ๋ณ€ํ™˜
DataMorph.convertFile("input.csv", "output.json");

// ํŠน์ • ํฌ๋งท ์ง€์ •
DataMorph.convertFile("data.txt", "result.txt", Format.CSV, Format.JSON);

๐Ÿ“Š Performance

๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ

  • ์ŠคํŠธ๋ฆฌ๋ฐ ์ฒ˜๋ฆฌ: ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ๋„ ์ผ์ •ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์œผ๋กœ ์ฒ˜๋ฆฌ
  • ์ง€์—ฐ ํ‰๊ฐ€: ํ•„์š”ํ•œ ์‹œ์ ์—๋งŒ ๋ฐ์ดํ„ฐ ๋กœ๋“œ
  • ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋‹ˆํ„ฐ๋ง: ์‹ค์‹œ๊ฐ„ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ถ”์  ๋ฐ ๊ฒฝ๊ณ 

์„ฑ๋Šฅ ๋ฒค์น˜๋งˆํฌ

์„ฑ๋Šฅ ํ‰๊ฐ€๋Š” ํ˜„์žฌ ์ง„ํ–‰ ์ค‘์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ์—…๋ฐ์ดํŠธ์—์„œ ๊ตฌ์ฒด์ ์ธ ๋ฒค์น˜๋งˆํฌ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

๊ณ„ํš๋œ ์„ฑ๋Šฅ ์ง€ํ‘œ

  • ์ฒ˜๋ฆฌ ์†๋„: ํŒŒ์ผ ํฌ๊ธฐ๋ณ„ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„
  • ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰: ์ผ๋ฐ˜ ์ฒ˜๋ฆฌ vs ์ŠคํŠธ๋ฆฌ๋ฐ ์ฒ˜๋ฆฌ ๋น„๊ต
  • ์ฒ˜๋ฆฌ๋Ÿ‰: ์ดˆ๋‹น ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅํ•œ ๋ ˆ์ฝ”๋“œ ์ˆ˜
  • ํ™•์žฅ์„ฑ: ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ํฌ๊ธฐ์—์„œ์˜ ์„ฑ๋Šฅ ๋ณ€ํ™”

์˜ˆ์ƒ ์„ฑ๋Šฅ ํŠน์„ฑ

ํŒŒ์ผ ํฌ๊ธฐ ์˜ˆ์ƒ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ฒ˜๋ฆฌ ๋ฐฉ์‹
~10MB 1-2์ดˆ ์ ์Œ ์ผ๋ฐ˜ ์ฒ˜๋ฆฌ
~100MB 5-10์ดˆ ์ค‘๊ฐ„ ์ŠคํŠธ๋ฆฌ๋ฐ ๊ถŒ์žฅ
~1GB+ 30-60์ดˆ ์ผ์ • ์ŠคํŠธ๋ฆฌ๋ฐ ํ•„์ˆ˜

์ง€์› ํฌ๋งท

ํฌ๋งท ์ฝ๊ธฐ ์“ฐ๊ธฐ ์ŠคํŠธ๋ฆฌ๋ฐ
CSV โœ… โœ… โœ…
JSON โœ… โœ… โœ…

๐Ÿงช Testing

# ์ „์ฒด ํ…Œ์ŠคํŠธ ์‹คํ–‰
./gradlew test

# ํŠน์ • ํ…Œ์ŠคํŠธ ์‹คํ–‰
./gradlew test --tests "DataMorphTest"

# ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ
./gradlew test --tests "com.datamorph.integration.*"

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

๐Ÿ“„ License

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

๐Ÿ”— Links


Made with โค๏ธ by DataMorph Contributors

About

Data transform library project

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages